UNPKG

concurrently

Version:
117 lines (116 loc) 5.68 kB
import { Buffer } from 'node:buffer'; import { PassThrough } from 'node:stream'; import { beforeEach, expect, it } from 'vitest'; import { createMockInstance } from '../__fixtures__/create-mock-instance.js'; import { FakeCommand } from '../__fixtures__/fake-command.js'; import { Logger } from '../logger.js'; import { InputHandler } from './input-handler.js'; let commands; let controller; let inputStream; let logger; beforeEach(() => { commands = [new FakeCommand('foo', 'echo foo', 0), new FakeCommand('bar', 'echo bar', 1)]; inputStream = new PassThrough(); logger = createMockInstance(Logger); controller = new InputHandler({ defaultInputTarget: 0, inputStream, logger, }); }); it('returns same commands', () => { expect(controller.handle(commands)).toMatchObject({ commands }); controller = new InputHandler({ logger, inputStream }); expect(controller.handle(commands)).toMatchObject({ commands }); }); it('does nothing if called without input stream', () => { new InputHandler({ defaultInputTarget: 0, inputStream: undefined, logger, }).handle(commands); inputStream.write('something'); expect(commands[0].stdin?.write).not.toHaveBeenCalled(); }); it('forwards input stream to default target ID', () => { controller.handle(commands); inputStream.write('something'); expect(commands[0].stdin?.write).toHaveBeenCalledExactlyOnceWith('something'); expect(commands[1].stdin?.write).not.toHaveBeenCalled(); }); it('forwards input stream to target index specified in input', () => { controller.handle(commands); inputStream.write('1:something'); inputStream.write('1:multi\nline\n'); expect(commands[0].stdin?.write).not.toHaveBeenCalled(); expect(commands[1].stdin?.write).toHaveBeenCalledTimes(2); expect(commands[1].stdin?.write).toHaveBeenCalledWith('something'); expect(commands[1].stdin?.write).toHaveBeenCalledWith('multi\nline\n'); }); it('forwards input stream to target index specified in input when input contains colon', () => { controller.handle(commands); inputStream.emit('data', Buffer.from('1:some:thing')); inputStream.emit('data', Buffer.from('1: :something')); inputStream.emit('data', Buffer.from('1::something')); expect(commands[0].stdin?.write).not.toHaveBeenCalled(); expect(commands[1].stdin?.write).toHaveBeenCalledTimes(3); expect(commands[1].stdin?.write).toHaveBeenCalledWith('some:thing'); expect(commands[1].stdin?.write).toHaveBeenCalledWith(' :something'); expect(commands[1].stdin?.write).toHaveBeenCalledWith(':something'); }); it('does not forward input stream when input contains colon in a different format', () => { controller.handle(commands); inputStream.emit('data', Buffer.from('Ruby0::Const::Syntax')); inputStream.emit('data', Buffer.from('1:Ruby1::Const::Syntax')); inputStream.emit('data', Buffer.from('ruby_symbol_arg :my_symbol')); inputStream.emit('data', Buffer.from('ruby_symbol_arg(:my_symbol)')); inputStream.emit('data', Buffer.from('{ruby_key: :my_val}')); inputStream.emit('data', Buffer.from('{:ruby_key=>:my_val}')); inputStream.emit('data', Buffer.from('js_obj = {key: "my_val"}')); expect(commands[1].stdin?.write).toHaveBeenCalledExactlyOnceWith('Ruby1::Const::Syntax'); expect(commands[0].stdin?.write).toHaveBeenCalledTimes(6); expect(commands[0].stdin?.write).toHaveBeenCalledWith('Ruby0::Const::Syntax'); expect(commands[0].stdin?.write).toHaveBeenCalledWith('ruby_symbol_arg :my_symbol'); expect(commands[0].stdin?.write).toHaveBeenCalledWith('ruby_symbol_arg(:my_symbol)'); expect(commands[0].stdin?.write).toHaveBeenCalledWith('{ruby_key: :my_val}'); expect(commands[0].stdin?.write).toHaveBeenCalledWith('{:ruby_key=>:my_val}'); expect(commands[0].stdin?.write).toHaveBeenCalledWith('js_obj = {key: "my_val"}'); }); it('forwards input stream to target name specified in input', () => { controller.handle(commands); inputStream.write('bar:something'); expect(commands[0].stdin?.write).not.toHaveBeenCalled(); expect(commands[1].stdin?.write).toHaveBeenCalledExactlyOnceWith('something'); }); it('logs error if command has no stdin open', () => { commands[0].stdin = undefined; controller.handle(commands); inputStream.write('something'); expect(commands[1].stdin?.write).not.toHaveBeenCalled(); expect(logger.logGlobalEvent).toHaveBeenCalledWith('Unable to find command "0", or it has no stdin open\n'); }); it('fallback to default input stream if command is not found', () => { controller.handle(commands); inputStream.write('foobar:something'); expect(commands[0].stdin?.write).toHaveBeenCalledExactlyOnceWith('foobar:something'); expect(commands[1].stdin?.write).not.toHaveBeenCalled(); expect(logger.logGlobalEvent).not.toHaveBeenCalled(); }); it('pauses input stream when finished', () => { expect(inputStream.readableFlowing).toBeNull(); const { onFinish } = controller.handle(commands); expect(inputStream.readableFlowing).toBe(true); expect(onFinish).toBeDefined(); onFinish?.(); expect(inputStream.readableFlowing).toBe(false); }); it('does not pause input stream when pauseInputStreamOnFinish is set to false', () => { controller = new InputHandler({ logger, inputStream, pauseInputStreamOnFinish: false }); expect(inputStream.readableFlowing).toBeNull(); const { onFinish } = controller.handle(commands); expect(inputStream.readableFlowing).toBe(true); expect(onFinish).toBeDefined(); onFinish?.(); expect(inputStream.readableFlowing).toBe(true); });