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
|
|
|
)
|
|
|
|
})
|
|
|
|
|
2023-10-12 05:30:25 +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)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|