import * as command from '../src/command' import * as os from 'os' /* eslint-disable @typescript-eslint/unbound-method */ let originalWriteFunction: (str: string) => boolean describe('@actions/core/src/command', () => { beforeAll(() => { originalWriteFunction = process.stdout.write }) beforeEach(() => { process.stdout.write = jest.fn() }) afterEach(() => {}) afterAll(() => { process.stdout.write = (originalWriteFunction as unknown) as ( str: string ) => boolean }) it('command only', () => { command.issueCommand('some-command', {}, '') assertWriteCalls([`::some-command::${os.EOL}`]) }) it('command escapes message', () => { // Verify replaces each instance, not just first instance command.issueCommand( 'some-command', {}, 'percent % percent % cr \r cr \r lf \n lf \n' ) assertWriteCalls([ `::some-command::percent %25 percent %25 cr %0D cr %0D lf %0A lf %0A${os.EOL}` ]) // Verify literal escape sequences process.stdout.write = jest.fn() command.issueCommand('some-command', {}, '%25 %25 %0D %0D %0A %0A') assertWriteCalls([ `::some-command::%2525 %2525 %250D %250D %250A %250A${os.EOL}` ]) }) it('command escapes property', () => { // Verify replaces each instance, not just first instance command.issueCommand( 'some-command', { name: 'percent % percent % cr \r cr \r lf \n lf \n colon : colon : comma , comma ,' }, '' ) assertWriteCalls([ `::some-command name=percent %25 percent %25 cr %0D cr %0D lf %0A lf %0A colon %3A colon %3A comma %2C comma %2C::${os.EOL}` ]) // Verify literal escape sequences process.stdout.write = jest.fn() command.issueCommand( 'some-command', {}, '%25 %25 %0D %0D %0A %0A %3A %3A %2C %2C' ) assertWriteCalls([ `::some-command::%2525 %2525 %250D %250D %250A %250A %253A %253A %252C %252C${os.EOL}` ]) }) it('command with message', () => { command.issueCommand('some-command', {}, 'some message') assertWriteCalls([`::some-command::some message${os.EOL}`]) }) it('command with message and properties', () => { command.issueCommand( 'some-command', {prop1: 'value 1', prop2: 'value 2'}, 'some message' ) assertWriteCalls([ `::some-command prop1=value 1,prop2=value 2::some message${os.EOL}` ]) }) it('command with one property', () => { command.issueCommand('some-command', {prop1: 'value 1'}, '') assertWriteCalls([`::some-command prop1=value 1::${os.EOL}`]) }) it('command with two properties', () => { command.issueCommand( 'some-command', {prop1: 'value 1', prop2: 'value 2'}, '' ) assertWriteCalls([`::some-command prop1=value 1,prop2=value 2::${os.EOL}`]) }) it('command with three properties', () => { command.issueCommand( 'some-command', {prop1: 'value 1', prop2: 'value 2', prop3: 'value 3'}, '' ) assertWriteCalls([ `::some-command prop1=value 1,prop2=value 2,prop3=value 3::${os.EOL}` ]) }) it('should handle issueing commands for non-string objects', () => { command.issueCommand( 'some-command', { prop1: ({test: 'object'} as unknown) as string, prop2: (123 as unknown) as string, prop3: (true as unknown) as string }, ({test: 'object'} as unknown) as string ) assertWriteCalls([ `::some-command prop1={"test"%3A"object"},prop2=123,prop3=true::{"test":"object"}${os.EOL}` ]) }) }) // Assert that process.stdout.write calls called only with the given arguments. function assertWriteCalls(calls: string[]): void { expect(process.stdout.write).toHaveBeenCalledTimes(calls.length) for (let i = 0; i < calls.length; i++) { expect(process.stdout.write).toHaveBeenNthCalledWith(i + 1, calls[i]) } }