pulsar/spec/buffered-process-spec.coffee
2017-01-19 13:30:39 -08:00

159 lines
5.6 KiB
CoffeeScript

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"'