forked from atom/atom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuffered-process-spec.coffee
158 lines (130 loc) · 5.65 KB
/
buffered-process-spec.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
ChildProcess = require 'child_process'
path = require 'path'
fs = require 'fs-plus'
BufferedProcess = require '../src/buffered-process'
describe "BufferedProcess", ->
describe "when a bad command is specified", ->
[oldOnError] = []
beforeEach ->
oldOnError = window.onerror
window.onerror = jasmine.createSpy()
afterEach ->
window.onerror = oldOnError
describe "when there is an error handler specified", ->
describe "when an error event is emitted by the process", ->
it "calls the error handler and does not throw an exception", ->
bufferedProcess = new BufferedProcess
command: 'bad-command-nope1'
args: ['nothing']
options: {shell: false}
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
bufferedProcess.onWillThrowError(errorSpy)
waitsFor -> errorSpy.callCount > 0
runs ->
expect(window.onerror).not.toHaveBeenCalled()
expect(errorSpy).toHaveBeenCalled()
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'spawn bad-command-nope1 ENOENT'
describe "when an error is thrown spawning the process", ->
it "calls the error handler and does not throw an exception", ->
spyOn(ChildProcess, 'spawn').andCallFake ->
error = new Error('Something is really wrong')
error.code = 'EAGAIN'
throw error
bufferedProcess = new BufferedProcess
command: 'ls'
args: []
options: {}
errorSpy = jasmine.createSpy().andCallFake (error) -> error.handle()
bufferedProcess.onWillThrowError(errorSpy)
waitsFor -> errorSpy.callCount > 0
runs ->
expect(window.onerror).not.toHaveBeenCalled()
expect(errorSpy).toHaveBeenCalled()
expect(errorSpy.mostRecentCall.args[0].error.message).toContain 'Something is really wrong'
describe "when there is not an error handler specified", ->
it "does throw an exception", ->
new BufferedProcess
command: 'bad-command-nope2'
args: ['nothing']
options: {shell: false}
waitsFor -> window.onerror.callCount > 0
runs ->
expect(window.onerror).toHaveBeenCalled()
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope2`'
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
describe "when autoStart is false", ->
it "doesnt start unless start method is called", ->
stdout = ''
stderr = ''
exitCallback = jasmine.createSpy('exit callback')
apmProcess = new BufferedProcess
autoStart: false
command: atom.packages.getApmPath()
args: ['-h']
options: {}
stdout: (lines) -> stdout += lines
stderr: (lines) -> stderr += lines
exit: exitCallback
expect(apmProcess.started).not.toBe(true)
apmProcess.start()
expect(apmProcess.started).toBe(true)
waitsFor -> exitCallback.callCount is 1
runs ->
expect(stderr).toContain 'apm - Atom Package Manager'
expect(stdout).toEqual ''
it "calls the specified stdout, stderr, and exit callbacks", ->
stdout = ''
stderr = ''
exitCallback = jasmine.createSpy('exit callback')
new BufferedProcess
command: atom.packages.getApmPath()
args: ['-h']
options: {}
stdout: (lines) -> stdout += lines
stderr: (lines) -> stderr += lines
exit: exitCallback
waitsFor -> exitCallback.callCount is 1
runs ->
expect(stderr).toContain 'apm - Atom Package Manager'
expect(stdout).toEqual ''
it "calls the specified stdout callback with whole lines", ->
exitCallback = jasmine.createSpy('exit callback')
loremPath = require.resolve("./fixtures/lorem.txt")
content = fs.readFileSync(loremPath).toString()
baseContent = content.split('\n')
stdout = ''
allLinesEndWithNewline = true
new BufferedProcess
command: if process.platform is 'win32' then 'type' else 'cat'
args: [loremPath]
options: {}
stdout: (lines) ->
endsWithNewline = (lines.charAt lines.length - 1) is '\n'
if not endsWithNewline then allLinesEndWithNewline = false
stdout += lines
exit: exitCallback
waitsFor -> exitCallback.callCount is 1
runs ->
expect(allLinesEndWithNewline).toBeTrue
expect(stdout).toBe content
describe "on Windows", ->
originalPlatform = null
beforeEach ->
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn')
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'win32'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
describe "when the explorer command is spawned on Windows", ->
it "doesn't quote arguments of the form /root,C...", ->
new BufferedProcess({command: 'explorer.exe', args: ['/root,C:\\foo']})
expect(ChildProcess.spawn.argsForCall[0][1][3]).toBe '"explorer.exe /root,C:\\foo"'
it "spawns the command using a cmd.exe wrapper when options.shell is undefined", ->
new BufferedProcess({command: 'dir'})
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'cmd.exe'
expect(ChildProcess.spawn.argsForCall[0][1][0]).toBe '/s'
expect(ChildProcess.spawn.argsForCall[0][1][1]).toBe '/d'
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '/c'
expect(ChildProcess.spawn.argsForCall[0][1][3]).toBe '"dir"'