1
0
Fork 0
toolkit/packages/helpers/__tests__/command-runner.test.ts

205 lines
5.5 KiB
TypeScript
Raw Normal View History

2023-09-29 14:17:46 +00:00
import * as exec from '@actions/exec'
2023-10-04 05:57:29 +00:00
import {CommandRunner, createCommandRunner} from '../src/helpers'
2023-09-29 14:17:46 +00:00
describe('command-runner', () => {
2023-10-04 05:57:29 +00:00
describe('createCommandRunner', () => {
2023-09-29 14:17:46 +00:00
it('creates a command object', async () => {
2023-10-04 05:57:29 +00:00
const command = createCommandRunner('echo')
2023-09-29 14:17:46 +00:00
expect(command).toBeDefined()
expect(command).toBeInstanceOf(CommandRunner)
})
})
describe('CommandRunner', () => {
2023-10-04 05:57:29 +00:00
const execSpy = jest.spyOn(exec, 'exec')
2023-09-29 14:17:46 +00:00
afterEach(() => {
jest.resetAllMocks()
})
it('runs basic commands', async () => {
2023-10-04 05:57:29 +00:00
execSpy.mockImplementation(async () => 0)
2023-09-29 14:17:46 +00:00
2023-10-04 05:57:29 +00:00
const command = createCommandRunner('echo', ['hello', 'world'], {
2023-09-29 14:17:46 +00:00
silent: true
})
command.run()
expect(execSpy).toHaveBeenCalledTimes(1)
expect(execSpy).toHaveBeenCalledWith(
'echo',
2023-10-04 05:57:29 +00:00
['hello', 'world'],
expect.objectContaining({
silent: true,
ignoreReturnCode: true
})
2023-09-29 14:17:46 +00:00
)
})
it('throws error if command is not specified', async () => {
const command = createCommandRunner()
await expect(command.run()).rejects.toThrow('Command was not specified')
})
it('will have exec error if it occured', async () => {
execSpy.mockImplementation(async () => {
throw new Error('test')
})
const command = createCommandRunner('echo', ['hello', 'world'], {
silent: true
})
const context = await command.run()
expect(context.execerr).toBeDefined()
expect(context.execerr?.message).toBe('test')
})
it('allows to set command, args and options', async () => {
execSpy.mockImplementation(async () => 0)
createCommandRunner()
.setCommand('echo')
.setArgs(['hello', 'world'])
.setOptions({silent: true})
.run()
expect(execSpy).toHaveBeenCalledTimes(1)
expect(execSpy).toHaveBeenCalledWith(
'echo',
['hello', 'world'],
expect.objectContaining({
silent: true,
ignoreReturnCode: true
})
)
})
it('allows to modify command, args and options', async () => {
execSpy.mockImplementation(async () => 0)
createCommandRunner('echo', ['hello', 'world'], {silent: true})
.setCommand(commandLine => `${commandLine} hello world`)
.setArgs(() => [])
.setOptions(options => ({...options, env: {test: 'test'}}))
.run()
expect(execSpy).toHaveBeenCalledTimes(1)
expect(execSpy).toHaveBeenCalledWith(
'echo hello world',
[],
expect.objectContaining({
silent: true,
ignoreReturnCode: true,
env: {test: 'test'}
})
)
})
2023-10-04 05:57:29 +00:00
const createExecMock = (output: {
stdout: string
stderr: string
exitCode: number
}): typeof exec.exec => {
const stdoutBuffer = Buffer.from(output.stdout, 'utf8')
const stderrBuffer = Buffer.from(output.stderr, 'utf8')
return async (
commandLine?: string,
args?: string[],
options?: exec.ExecOptions
) => {
options?.listeners?.stdout?.(stdoutBuffer)
options?.listeners?.stderr?.(stderrBuffer)
await new Promise(resolve => setTimeout(resolve, 5))
return output.exitCode
}
}
2023-09-29 14:17:46 +00:00
it('allows to use middlewares', async () => {
2023-10-04 05:57:29 +00:00
execSpy.mockImplementation(
createExecMock({stdout: 'hello', stderr: '', exitCode: 0})
)
2023-09-29 14:17:46 +00:00
2023-10-04 05:57:29 +00:00
const command = createCommandRunner('echo', ['hello', 'world'], {
2023-09-29 14:17:46 +00:00
silent: true
})
const middleware = jest.fn()
await command.use(middleware).run()
expect(middleware).toHaveBeenCalledTimes(1)
expect(middleware).toHaveBeenCalledWith(
expect.objectContaining({
args: ['hello', 'world'],
2023-10-12 03:54:13 +00:00
commandLine: 'echo',
2023-09-29 14:17:46 +00:00
execerr: null,
2023-10-12 03:54:13 +00:00
exitCode: 0,
options: {failOnStdErr: false, ignoreReturnCode: true, silent: true},
stderr: '',
stdout: 'hello'
2023-09-29 14:17:46 +00:00
}),
expect.any(Function)
)
})
describe('CommandRunner.prototype.on', () => {
it('passes control to next middleware if nothing has matched', async () => {
2023-10-04 05:57:29 +00:00
execSpy.mockImplementation(
createExecMock({
2023-09-29 14:17:46 +00:00
stdout: 'hello',
stderr: '',
exitCode: 0
2023-10-04 05:57:29 +00:00
})
)
2023-09-29 14:17:46 +00:00
const willBeCalled = jest.fn()
const willNotBeCalled = jest.fn()
2023-10-04 05:57:29 +00:00
await createCommandRunner('echo', ['hello', 'world'], {
2023-09-29 14:17:46 +00:00
silent: true
})
2023-10-04 05:57:29 +00:00
.on('!stdout', willNotBeCalled)
2023-09-29 14:17:46 +00:00
.use(willBeCalled)
.run()
expect(willNotBeCalled).not.toHaveBeenCalled()
expect(willBeCalled).toHaveBeenCalledTimes(1)
})
it('runs a middleware if event matches', async () => {
2023-10-04 05:57:29 +00:00
execSpy.mockImplementation(
createExecMock({stdout: '', stderr: '', exitCode: 0})
)
2023-09-29 14:17:46 +00:00
const middleware = jest.fn()
2023-10-04 05:57:29 +00:00
await createCommandRunner('echo', ['hello', 'world'], {
2023-09-29 14:17:46 +00:00
silent: true
})
.on('ok', middleware)
.run()
expect(middleware).toHaveBeenCalledTimes(1)
})
it('runs a middleware if event matches with negation', async () => {
2023-10-04 05:57:29 +00:00
execSpy.mockImplementation(
createExecMock({stdout: '', stderr: '', exitCode: 1})
)
2023-09-29 14:17:46 +00:00
const middleware = jest.fn()
2023-10-04 05:57:29 +00:00
await createCommandRunner('echo', ['hello', 'world'], {
2023-09-29 14:17:46 +00:00
silent: true
})
2023-10-04 05:57:29 +00:00
.on('!stdout', middleware)
2023-09-29 14:17:46 +00:00
.run()
expect(middleware).toHaveBeenCalledTimes(1)
})
})
})
})