From 764e68a7c9cb4d1d4ee739006d6a704f6ea42e66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:20:20 +0000 Subject: [PATCH 1/7] Bump @oclif/core from 1.26.2 to 2.9.3 Bumps [@oclif/core](https://github.com/oclif/core) from 1.26.2 to 2.9.3. - [Release notes](https://github.com/oclif/core/releases) - [Changelog](https://github.com/oclif/core/blob/main/CHANGELOG.md) - [Commits](https://github.com/oclif/core/compare/1.26.2...2.9.3) --- updated-dependencies: - dependency-name: "@oclif/core" dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1150eb8c..d0272090 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "@adobe/aio-lib-core-config": "^3.0.0", "@adobe/aio-lib-core-networking": "^4.1.0", "@adobe/aio-lib-runtime": "^5.0.0", - "@oclif/core": "^1.3.0", + "@oclif/core": "^2.9.3", "@types/jest": "^27.4.0", "chalk": "^4.1.2", "dayjs": "^1.10.4", From c5047b0ceee80b5a84a12ef9947cd6e281f2c1d6 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Thu, 20 Jul 2023 16:00:36 +0800 Subject: [PATCH 2/7] fix RuntimeBaseCommand and action/create tests --- .eslintrc | 3 +- package.json | 1 + src/RuntimeBaseCommand.js | 2 + src/commands/runtime/action/create.js | 28 +- test/RuntimeBaseCommand.test.js | 57 +- test/commands/runtime/action/create.test.js | 1481 ++++++++++--------- test/jest.setup.js | 119 +- 7 files changed, 874 insertions(+), 817 deletions(-) diff --git a/.eslintrc b/.eslintrc index 4edb8504..999a32a0 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,11 +1,12 @@ { "extends": "@adobe/eslint-config-aio-lib-config", "globals": { + "createFileSystem": true, + "clearMockedFs": true, "fixtureFile": true, "fixtureFileWithTimeZoneAdjustment": true, "fixtureJson": true, "fixtureZip": true, - "fakeFileSystem": true, "createTestBaseFlagsFunction": true, "createTestFlagsFunction": true } diff --git a/package.json b/package.json index 3ebbbfc0..5898277d 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ }, "repository": "adobe/aio-cli-plugin-runtime", "scripts": { + "jest:debug": "jest --runInBand test/commands/runtime/action/create*", "eslint-fix": "eslint src test e2e --fix", "posttest": "eslint src test e2e", "test": "npm run unit-tests", diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index ca6f73b0..beba341b 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -155,4 +155,6 @@ RuntimeBaseCommand.flags = { }) } +RuntimeBaseCommand.args = {} + module.exports = RuntimeBaseCommand diff --git a/src/commands/runtime/action/create.js b/src/commands/runtime/action/create.js index 2f8ce10f..38db9a3a 100644 --- a/src/commands/runtime/action/create.js +++ b/src/commands/runtime/action/create.js @@ -14,7 +14,7 @@ const fs = require('fs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { createKeyValueArrayFromFlag, createKeyValueArrayFromFile, createComponentsfromSequence, getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils const { kindForFileExtension } = require('../../../kinds') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class ActionCreate extends RuntimeBaseCommand { isUpdate () { return false } @@ -66,7 +66,7 @@ class ActionCreate extends RuntimeBaseCommand { if (!flags.kind && !flags.docker) { throw (new Error(ActionCreate.errorMessages.missingKindForZip)) } - exec.code = fs.readFileSync(args.actionPath).toString('base64') + exec.code = Buffer.from(fs.readFileSync(args.actionPath)).toString('base64') } else { exec.code = fs.readFileSync(args.actionPath, { encoding: 'utf8' }) } @@ -220,15 +220,20 @@ class ActionCreate extends RuntimeBaseCommand { } } -ActionCreate.args = [ - { - name: 'actionName', - required: true - }, - { - name: 'actionPath' - } -] +// ActionCreate.args0 = [ +// { +// name: 'actionName', +// required: true +// }, +// { +// name: 'actionPath' +// } +// ] + +ActionCreate.args = { + actionName: Args.string({ required: true }), + actionPath: Args.string() +} ActionCreate.limits = { timeoutMs: { @@ -324,6 +329,7 @@ ActionCreate.flags = { } ActionCreate.description = 'Creates an Action' + ActionCreate.errorMessages = { websecure: 'Cannot specify --web-secure without also specifying --web [true|raw]', sequenceWithAction: 'Cannot specify sequence and a code artifact at the same time', diff --git a/test/RuntimeBaseCommand.test.js b/test/RuntimeBaseCommand.test.js index 987a1cc7..ff2aa8a6 100644 --- a/test/RuntimeBaseCommand.test.js +++ b/test/RuntimeBaseCommand.test.js @@ -17,9 +17,12 @@ const RuntimeLib = require('@adobe/aio-lib-runtime') const OpenWhiskError = require('openwhisk/lib/openwhisk_error') beforeEach(() => { - fakeFileSystem.reset() + RuntimeLib.init.mockClear() + clearMockedFs() }) +const WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') + test('exports', async () => { expect(typeof TheCommand).toEqual('function') expect(TheCommand.prototype).toBeInstanceOf(Command) @@ -39,7 +42,7 @@ test('flags', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { @@ -55,9 +58,9 @@ describe('instance methods', () => { }) test('apihost default', async () => { - const files = {} - files[require('path').join(require('os').homedir(), '.wskprops')] = 'AUTH=1234' - fakeFileSystem.addJson(files) + createFileSystem({ + [WSK_PROPS_PATH]: 'AUTH=1234' + }) return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( @@ -68,28 +71,36 @@ describe('instance methods', () => { test('empty APIHOST should throw', async () => { process.env[PropertyEnv.APIHOST] = ' ' + createFileSystem({ + [WSK_PROPS_PATH]: 'APIHOST=some.url' + }) + await expect(command.wsk()).rejects.toThrow(new Error('An API host must be specified')) }) test('null AUTH should throw', async () => { delete process.env[PropertyEnv.APIHOST] delete process.env[PropertyEnv.AUTH] - const files = {} - files[require('path').join(require('os').homedir(), '.wskprops')] = '' - fakeFileSystem.addJson(files) + createFileSystem({ + [WSK_PROPS_PATH]: 'AUTH=' + }) await expect(command.wsk()).rejects.toThrow(new Error('An AUTH key must be specified')) }) test('empty AUTH should throw', async () => { process.env[PropertyEnv.AUTH] = ' ' + createFileSystem({ + [WSK_PROPS_PATH]: 'AUTH=some-auth' + }) + await expect(command.wsk()).rejects.toThrow(new Error('An AUTH key must be specified')) delete process.env[PropertyEnv.AUTH] }) test('not string AUTH should not throw', async () => { - const files = {} - files[require('path').join(require('os').homedir(), '.wskprops')] = 'AUTH=1234' - fakeFileSystem.addJson(files) + createFileSystem({ + [WSK_PROPS_PATH]: 'AUTH=1234' + }) return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( @@ -100,9 +111,9 @@ describe('instance methods', () => { }) test('auth with inline comment should trim the comment', async () => { - const files = {} - files[require('path').join(require('os').homedir(), '.wskprops')] = 'AUTH=123 #inline-comment' - fakeFileSystem.addJson(files) + createFileSystem({ + [WSK_PROPS_PATH]: 'AUTH=123 #inline-comment' + }) return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( @@ -116,6 +127,10 @@ describe('instance methods', () => { const value = 'http://my-server' process.env[PropertyEnv.APIHOST] = value + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( // the values are from the wsk.properties fixture @@ -134,6 +149,10 @@ describe('instance methods', () => { const value = 'a9329ekasgk01' process.env[PropertyEnv.AUTH] = value + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( // the values are from the wsk.properties fixture @@ -152,6 +171,10 @@ describe('instance methods', () => { const value = 'v2' process.env[PropertyEnv.APIVERSION] = value + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + return command.wsk().then(() => { expect(RuntimeLib.init).toHaveBeenLastCalledWith( // the values are from the wsk.properties fixture @@ -206,6 +229,10 @@ describe('instance methods', () => { }) test('returns a promise', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + return command.wsk().then((ow) => { expect(ow).toBe(ow) }) @@ -213,7 +240,6 @@ describe('instance methods', () => { // eslint-disable-next-line jest/expect-expect test('no config file, no problem', () => { - fakeFileSystem.clear() process.env[PropertyEnv.AUTH] = '1234' return command.wsk().then(() => { @@ -223,7 +249,6 @@ describe('instance methods', () => { // eslint-disable-next-line jest/expect-expect test('should not throw if config file specified but doesnt exist', () => { - fakeFileSystem.clear() process.env[PropertyEnv.CONFIG_FILE] = '/foo' process.env[PropertyEnv.AUTH] = '1234' diff --git a/test/commands/runtime/action/create.test.js b/test/commands/runtime/action/create.test.js index 6273b7cd..1d62e423 100644 --- a/test/commands/runtime/action/create.test.js +++ b/test/commands/runtime/action/create.test.js @@ -21,6 +21,7 @@ const rtActionGet = 'actions.get' test('exports', async () => { expect(typeof TheCommand).toEqual('function') expect(TheCommand.prototype instanceof RuntimeBaseCommand).toBeTruthy() + expect(TheCommand.run).toBeInstanceOf(Function) }) test('description', async () => { @@ -52,13 +53,9 @@ test('flags', async () => { }) test('args', async () => { - const actionName = TheCommand.args[0] - expect(actionName.name).toBeDefined() - expect(actionName.name).toEqual('actionName') - expect(actionName.required).toEqual(true) - const actionPath = TheCommand.args[1] - expect(actionPath.name).toBeDefined() - expect(actionPath.name).toEqual('actionPath') + expect(TheCommand.args.actionName).toBeDefined() + expect(TheCommand.args.actionName.required).toEqual(true) + expect(TheCommand.args.actionPath).toBeDefined() }) test('aliases', async () => { @@ -67,807 +64,815 @@ test('aliases', async () => { expect(TheCommand.aliases.length).toBeGreaterThan(0) }) -const rejectWithError = async (command, error, handleError) => { - await expect(command.run()).rejects.toThrow(...error) - expect(handleError).toHaveBeenLastCalledWith(...error) - return true +// /////////////////////////////////////////// + +const JS_FILE = fixtureFile('action/actionFile.js') +const WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') +const FILE_SYSTEM_JSON = { + [WSK_PROPS_PATH]: 'AUTH=something', + '/action/actionFile.js': fixtureFile('action/actionFile.js'), + '/action/zipAction.zip': 'fakezipfile', + '/action/zipAction.bin': 'fakezipfilebin', + '/action/fileWithNoExt': 'fakefilewithnoext' } -describe('instance methods', () => { - let command, handleError, rtLib - beforeEach(async () => { - command = new TheCommand([]) - handleError = jest.spyOn(command, 'handleError') - rtLib = await RuntimeLib.init({ apihost: 'fakehost', api_key: 'fakekey' }) - rtLib.mockResolved('actions.client.options', '') - RuntimeLib.mockReset() - }) - - beforeAll(() => { - const json = { - 'action/actionFile.js': fixtureFile('action/actionFile.js'), - 'action/zipAction.zip': 'fakezipfile', - 'action/zipAction.bin': 'fakezipfile', - 'action/fileWithNoExt': 'fakefile' - } - fakeFileSystem.addJson(json) - }) - - afterAll(() => { - // reset back to normal - fakeFileSystem.reset() - }) - - describe('run', () => { - const jsFile = fixtureFile('action/actionFile.js') - test('exists', async () => { - expect(command.run).toBeInstanceOf(Function) - }) +let command, handleError, rtLib +beforeEach(async () => { + command = new TheCommand([]) + handleError = jest.spyOn(command, 'handleError') + rtLib = await RuntimeLib.init({ apihost: 'fakehost', api_key: 'fakekey' }) + rtLib.mockResolved('actions.client.options', '') + RuntimeLib.mockReset() +}) - test('creates an action with action name and action path', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ name, action: { name, exec: { code: jsFile, kind: 'nodejs:default' } } }) - expect(stdout.output).toMatch('') - }) - }) +beforeAll(() => { + createFileSystem(FILE_SYSTEM_JSON) +}) - test('creates an action with action name and --sequence flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '--sequence', 'a,p/b,ns/p/c,/ns2/p/d,/ns3/e'] - rtUtils.createComponentsfromSequence.mockReturnValue({ fake: 'value' }) - return command.run() - .then(() => { - expect(rtUtils.createComponentsfromSequence).toHaveBeenCalledWith(['a', 'p/b', 'ns/p/c', '/ns2/p/d', '/ns3/e']) - expect(cmd).toHaveBeenCalledWith({ - action: { - exec: { fake: 'value' }, - name - }, - name - }) - expect(stdout.output).toMatch('') - }) - }) +afterAll(() => { + // reset back to normal + clearMockedFs() +}) - test('creates an action with action name and --docker flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '--docker', 'some-image'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - kind: 'blackbox', - image: 'some-image' - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and action path', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ name, action: { name, exec: { code: JS_FILE, kind: 'nodejs:default' } } }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name and action path and --docker flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--docker', 'some-image'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'blackbox', - image: 'some-image' - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and --sequence flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '--sequence', 'a,p/b,ns/p/c,/ns2/p/d,/ns3/e'] + rtUtils.createComponentsfromSequence.mockReturnValue({ fake: 'value' }) + return command.run() + .then(() => { + expect(rtUtils.createComponentsfromSequence).toHaveBeenCalledWith(['a', 'p/b', 'ns/p/c', '/ns2/p/d', '/ns3/e']) + expect(cmd).toHaveBeenCalledWith({ + action: { + exec: { fake: 'value' }, + name + }, + name + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name and action path --json', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--json'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - } - } - }) - expect(stdout.output).toMatch('') // TODO: json version - }) +test('creates an action with action name and --docker flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '--docker', 'some-image'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + kind: 'blackbox', + image: 'some-image' + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name and action path to zip file', () => { - const name = 'hello' - const zipFile = Buffer.from('fakezipfile').toString('base64') - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/zipAction.zip', '--kind', 'nodejs:8'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: zipFile, - kind: 'nodejs:8' - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and action path and --docker flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--docker', 'some-image'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'blackbox', + image: 'some-image' + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name and action path to binary file', () => { - const name = 'hello' - const zipFile = Buffer.from('fakezipfile').toString('base64') - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/zipAction.bin', '--kind', 'nodejs:8', '--binary'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: zipFile, - kind: 'nodejs:8' - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and action path --json', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--json'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + } + } + }) + expect(stdout.output).toMatch('') // TODO: json version }) +}) - test('creates an action with action name, action path and --param flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation(params => params && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(cmd).toHaveBeenCalledWith({ - action: { - exec: { code: jsFile, kind: 'nodejs:default' }, - name, - parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] - }, - name - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and action path to zip file', () => { + const actionName = 'hello' + const actionPath = '/action/zipAction.zip' + + const base64ZipFile = Buffer.from(FILE_SYSTEM_JSON[actionPath]).toString('base64') + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [actionName, actionPath, '--kind', 'nodejs:8'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name: actionName, + action: { + name: actionName, + exec: { + code: base64ZipFile, + kind: 'nodejs:8' + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and --param-file flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => file && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - command.argv = [name, '/action/actionFile.js', '--param-file', '/action/parameters.json'] - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(undefined, '/action/parameters.json') - expect(cmd).toHaveBeenCalledWith({ - action: { - exec: { code: jsFile, kind: 'nodejs:default' }, - name, - parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] - }, - name - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name and action path to binary file', () => { + const actionName = 'hello' + const actionPath = '/action/zipAction.bin' + + const base64ZipFile = Buffer.from(FILE_SYSTEM_JSON[actionPath]).toString('base64') + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [actionName, '/action/zipAction.bin', '--kind', 'nodejs:8', '--binary'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name: actionName, + action: { + name: actionName, + exec: { + code: base64ZipFile, + kind: 'nodejs:8' + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --param-file and param flag (precedence)', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, '') - command.argv = [name, '/action/actionFile.js', '--param', 'param1', 'fromcmdline1', '--param', 'cmdparam', 'fromcmdline2', '--param-file', '/action/parameters.json'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && file && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path and --param flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation(params => params && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(cmd).toHaveBeenCalledWith({ + action: { + exec: { code: JS_FILE, kind: 'nodejs:default' }, + name, + parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] + }, + name + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag and limits', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--logsize', '8', '--memory', '128', '--timeout', '20000'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [ - { key: 'fakeParam', value: 'aaa' }, - { key: 'fakeParam2', value: 'bbb' } - ], - limits: { - logs: 8, - memory: 128, - timeout: 20000 - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path and --param-file flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => file && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + command.argv = [name, '/action/actionFile.js', '--param-file', '/action/parameters.json'] + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(undefined, '/action/parameters.json') + expect(cmd).toHaveBeenCalledWith({ + action: { + exec: { code: JS_FILE, kind: 'nodejs:default' }, + name, + parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] + }, + name + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag and limits with shorter flag version', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-l', '8', '-m', '128', '-t', '20000'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [ - { key: 'fakeParam', value: 'aaa' }, - { key: 'fakeParam2', value: 'bbb' } - ], - limits: { - logs: 8, - memory: 128, - timeout: 20000 - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --param-file and param flag (precedence)', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, '') + command.argv = [name, '/action/actionFile.js', '--param', 'param1', 'fromcmdline1', '--param', 'cmdparam', 'fromcmdline2', '--param-file', '/action/parameters.json'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && file && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag, limits and kind', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--logsize', '8', '--memory', '128', '--kind', 'nodejs:10'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && ([{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }])) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:10' - }, - parameters: [ - { key: 'fakeParam', value: 'aaa' }, - { key: 'fakeParam2', value: 'bbb' } - ], - limits: { - logs: 8, - memory: 128 - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag and limits', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--logsize', '8', '--memory', '128', '--timeout', '20000'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [ + { key: 'fakeParam', value: 'aaa' }, + { key: 'fakeParam2', value: 'bbb' } + ], + limits: { + logs: 8, + memory: 128, + timeout: 20000 + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and --env flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--env', 'c', 'd'] - rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) - return command.run() - .then(() => { - expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b', 'c', 'd']) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fakeEnv', - value: 'abc', - init: true - }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag and limits with shorter flag version', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-l', '8', '-m', '128', '-t', '20000'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [ + { key: 'fakeParam', value: 'aaa' }, + { key: 'fakeParam2', value: 'bbb' } + ], + limits: { + logs: 8, + memory: 128, + timeout: 20000 + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and --e flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '-e', 'c', 'd'] - rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) - return command.run() - .then(() => { - expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b', 'c', 'd']) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fakeEnv', - value: 'abc', - init: true - }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag, limits and kind', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--logsize', '8', '--memory', '128', '--kind', 'nodejs:10'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && ([{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }])) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:10' + }, + parameters: [ + { key: 'fakeParam', value: 'aaa' }, + { key: 'fakeParam2', value: 'bbb' } + ], + limits: { + logs: 8, + memory: 128 + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and --env and --param flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--param', 'c', 'd'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) - rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['c', 'd'], undefined) - expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b']) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [ - { key: 'fakeParam', value: 'aaa' }, - { key: 'fakeParam2', value: 'bbb' }, - { key: 'fakeEnv', value: 'abc', init: true } - ] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path and --env flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--env', 'c', 'd'] + rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) + return command.run() + .then(() => { + expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b', 'c', 'd']) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fakeEnv', + value: 'abc', + init: true + }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and overlapping --env and --param keys', async () => { - rtLib.mockRejected(rtAction, '') - const name = 'hello' - command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--param', 'a', 'd'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'same', value: 'kv' }]) - rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'same', value: 'abc' }]) - const error = ['failed to create the action', new Error('Invalid argument(s). Environment variables and function parameters may not overlap')] - expect(await rejectWithError(command, error, handleError)).toBeTruthy() +test('creates an action with action name, action path and --e flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '-e', 'c', 'd'] + rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) + return command.run() + .then(() => { + expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b', 'c', 'd']) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fakeEnv', + value: 'abc', + init: true + }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path and --env-file flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--env-file', '/action/parameters.json'] - rtUtils.createKeyValueArrayFromFile.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) - return command.run() - .then(() => { - expect(rtUtils.createKeyValueArrayFromFile).toHaveBeenCalledWith('/action/parameters.json') - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fakeEnv', - value: 'abc', - init: true - }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path and --env and --param flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--param', 'c', 'd'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'fakeParam', value: 'aaa' }, { key: 'fakeParam2', value: 'bbb' }]) + rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['c', 'd'], undefined) + expect(rtUtils.createKeyValueArrayFromFlag).toHaveBeenCalledWith(['a', 'b']) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [ + { key: 'fakeParam', value: 'aaa' }, + { key: 'fakeParam2', value: 'bbb' }, + { key: 'fakeEnv', value: 'abc', init: true } + ] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag and annotation flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--annotation', 'desc', 'Description'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => [{ key: 'fake', value: 'abc' }]) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['desc', 'Description'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fake', - value: 'abc' - }], - annotations: [{ - key: 'fake', - value: 'abc' - }] - } - }) - expect(stdout.output).toMatch('') - }) - }) +test('creates an action with action name, action path and overlapping --env and --param keys', async () => { + rtLib.mockRejected(rtAction, '') + const name = 'hello' + command.argv = [name, '/action/actionFile.js', '--env', 'a', 'b', '--param', 'a', 'd'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => flags && [{ key: 'same', value: 'kv' }]) + rtUtils.createKeyValueArrayFromFlag.mockReturnValue([{ key: 'same', value: 'abc' }]) + const error = ['failed to create the action', new Error('Invalid argument(s). Environment variables and function parameters may not overlap')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('creates an action with action name, action path, --params flag and annotation-file flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-A', '/action/parameters.json'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }]) || (file && [{ key: 'fakeAnno', value: 'tation' }])) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(undefined, '/action/parameters.json') - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fake', - value: 'abc' - }], - annotations: [{ - key: 'fakeAnno', - value: 'tation' - }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path and --env-file flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--env-file', '/action/parameters.json'] + rtUtils.createKeyValueArrayFromFile.mockReturnValue([{ key: 'fakeEnv', value: 'abc' }]) + return command.run() + .then(() => { + expect(rtUtils.createKeyValueArrayFromFile).toHaveBeenCalledWith('/action/parameters.json') + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fakeEnv', + value: 'abc', + init: true + }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag web flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '--web', 'raw'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }])) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fake', - value: 'abc' - }], - annotations: [{ key: 'web-export', value: true }, { key: 'raw-http', value: true }, { key: 'final', value: true }] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag and annotation flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--param', 'a', 'b', '--param', 'c', 'd', '--annotation', 'desc', 'Description'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => [{ key: 'fake', value: 'abc' }]) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['desc', 'Description'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fake', + value: 'abc' + }], + annotations: [{ + key: 'fake', + value: 'abc' + }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name, action path, --params flag, annotations and web flag as true', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-a', 'desc', 'Description', '--web', 'true', '--web-secure', 'true'] - rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }])) - return command.run() - .then(() => { - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) - expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['desc', 'Description'], undefined) - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - parameters: [{ - key: 'fake', - value: 'abc' - }], - annotations: [ - { key: 'fake', value: 'abc' }, - { key: 'web-export', value: true }, - { key: 'final', value: true }, - { key: 'require-whisk-auth', value: true } - ] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag and annotation-file flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-A', '/action/parameters.json'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }]) || (file && [{ key: 'fakeAnno', value: 'tation' }])) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(undefined, '/action/parameters.json') + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fake', + value: 'abc' + }], + annotations: [{ + key: 'fakeAnno', + value: 'tation' + }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name with --web-secure true', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, '') - command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'true'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - annotations: [ - { key: 'web-export', value: true }, - { key: 'final', value: true }, - { key: 'require-whisk-auth', value: true } - ] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag web flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '--web', 'raw'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }])) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fake', + value: 'abc' + }], + annotations: [{ key: 'web-export', value: true }, { key: 'raw-http', value: true }, { key: 'final', value: true }] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name with --web-secure false', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, '') - command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'false'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - annotations: [ - { key: 'web-export', value: true }, - { key: 'final', value: true }, - { key: 'require-whisk-auth', value: false } - ] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name, action path, --params flag, annotations and web flag as true', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '-p', 'a', 'b', '-p', 'c', 'd', '-a', 'desc', 'Description', '--web', 'true', '--web-secure', 'true'] + rtUtils.getKeyValueArrayFromMergedParameters.mockImplementation((flags, file) => (flags && [{ key: 'fake', value: 'abc' }])) + return command.run() + .then(() => { + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['a', 'b', 'c', 'd'], undefined) + expect(rtUtils.getKeyValueArrayFromMergedParameters).toHaveBeenCalledWith(['desc', 'Description'], undefined) + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + parameters: [{ + key: 'fake', + value: 'abc' + }], + annotations: [ + { key: 'fake', value: 'abc' }, + { key: 'web-export', value: true }, + { key: 'final', value: true }, + { key: 'require-whisk-auth', value: true } + ] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with action name with --web-secure abcxyz', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, '') - command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'abcxyz'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - kind: 'nodejs:default' - }, - annotations: [ - { key: 'web-export', value: true }, - { key: 'final', value: true }, - { key: 'require-whisk-auth', value: 'abcxyz' } - ] - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name with --web-secure true', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, '') + command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'true'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + annotations: [ + { key: 'web-export', value: true }, + { key: 'final', value: true }, + { key: 'require-whisk-auth', value: true } + ] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with --main flag', () => { - const name = 'hello' - const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) - command.argv = [name, '/action/actionFile.js', '--main', 'maynard'] - return command.run() - .then(() => { - expect(cmd).toHaveBeenCalledWith({ - name, - action: { - name, - exec: { - code: jsFile, - main: 'maynard', - kind: 'nodejs:default' - } - } - }) - expect(stdout.output).toMatch('') - }) +test('creates an action with action name with --web-secure false', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, '') + command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'false'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + annotations: [ + { key: 'web-export', value: true }, + { key: 'final', value: true }, + { key: 'require-whisk-auth', value: false } + ] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with code of unknown kind', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/fileWithNoExt'] - const error = ['failed to create the action', new Error('Cannot determine kind of action. Please use --kind to specify.')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() +test('creates an action with action name with --web-secure abcxyz', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, '') + command.argv = [name, '/action/actionFile.js', '--web', 'true', '--web-secure', 'abcxyz'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + kind: 'nodejs:default' + }, + annotations: [ + { key: 'web-export', value: true }, + { key: 'final', value: true }, + { key: 'require-whisk-auth', value: 'abcxyz' } + ] + } + }) + expect(stdout.output).toMatch('') }) +}) - test('creates an action with code and --sequence', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/actionFile.js', '--sequence', 'a,b,c'] - const error = ['failed to create the action', new Error('Cannot specify sequence and a code artifact at the same time')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() +test('creates an action with --main flag', () => { + const name = 'hello' + const cmd = rtLib.mockResolved(rtAction, { res: 'fake' }) + command.argv = [name, '/action/actionFile.js', '--main', 'maynard'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ + name, + action: { + name, + exec: { + code: JS_FILE, + main: 'maynard', + kind: 'nodejs:default' + } + } + }) + expect(stdout.output).toMatch('') }) +}) - test('tests for incorrect action with --main flag and --sequence', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '--main', 'maynard', '--sequence', 'a,b,c'] - const error = ['failed to create the action', new Error('The function handler can only be specified when you provide a code artifact')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('creates an action with code of unknown kind', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/fileWithNoExt'] + const error = ['failed to create the action', new Error('Cannot determine kind of action. Please use --kind to specify.')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('creates an action with --docker and --sequence', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '--docker', 'some-image', '--sequence', 'a,b,c'] - const error = ['failed to create the action', new Error('Cannot specify sequence and a container image at the same time')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('creates an action with code and --sequence', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/actionFile.js', '--sequence', 'a,b,c'] + const error = ['failed to create the action', new Error('Cannot specify sequence and a code artifact at the same time')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('creates an action with --docker and --kind', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/actionFile.js', '--kind', 'nodejs:8', '--docker', 'some-image'] - const error = ['failed to create the action', new Error('Cannot specify a kind and a container image at the same time')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('tests for incorrect action with --main flag and --sequence', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '--main', 'maynard', '--sequence', 'a,b,c'] + const error = ['failed to create the action', new Error('The function handler can only be specified when you provide a code artifact')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('tests for incorrect action create missing code and sequence', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello'] - const error = ['failed to create the action', new Error('Must provide a code artifact, container image, or a sequence')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('creates an action with --docker and --sequence', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '--docker', 'some-image', '--sequence', 'a,b,c'] + const error = ['failed to create the action', new Error('Cannot specify sequence and a container image at the same time')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('tests for incorrect action with --kind flag and --sequence', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '--kind', 'nodejs:10', '--sequence', 'a,b,c'] - const error = ['failed to create the action', new Error('A kind may not be specified for a sequence')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) - test('tests for incorrect --sequence flags', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '--sequence', ' ,a,b,c'] - const error = ['failed to create the action', new Error('Provide a valid sequence component')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('creates an action with --docker and --kind', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/actionFile.js', '--kind', 'nodejs:8', '--docker', 'some-image'] + const error = ['failed to create the action', new Error('Cannot specify a kind and a container image at the same time')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('tests for incorrect action path', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/file.js', '--kind', 'nodejs:10'] - const error = ['failed to create the action', new Error('Provide a valid path for ACTION')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('tests for incorrect action create missing code and sequence', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello'] + const error = ['failed to create the action', new Error('Must provide a code artifact, container image, or a sequence')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('tests for incorrect action zip path', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/file.zip', '--kind', 'nodejs:10'] - const error = ['failed to create the action', new Error('Provide a valid path for ACTION')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('tests for incorrect action with --kind flag and --sequence', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '--kind', 'nodejs:10', '--sequence', 'a,b,c'] + const error = ['failed to create the action', new Error('A kind may not be specified for a sequence')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) +test('tests for incorrect --sequence flags', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '--sequence', ' ,a,b,c'] + const error = ['failed to create the action', new Error('Provide a valid sequence component')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('errors out on api error', async () => { - rtLib.mockRejected(rtAction, new Error('an error')) - command.argv = ['hello', '/action/actionFile.js'] - const error = ['failed to create the action', new Error('an error')] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('tests for incorrect action path', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/file.js', '--kind', 'nodejs:10'] + const error = ['failed to create the action', new Error('Provide a valid path for ACTION')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('errors out on create with timeout below min', async () => { - const flag = '--timeout' - const invalidValue = '99' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 100 but received: ${invalidValue}\nSee more help with --help`) - }) +test('tests for incorrect action zip path', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/file.zip', '--kind', 'nodejs:10'] + const error = ['failed to create the action', new Error('Provide a valid path for ACTION')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('errors out on create with timeout above max', async () => { - const flag = '--timeout' - const invalidValue = '3600001' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 3600000 but received: ${invalidValue}\nSee more help with --help`) - }) +test('errors out on api error', async () => { + rtLib.mockRejected(rtAction, new Error('an error')) + command.argv = ['hello', '/action/actionFile.js'] + const error = ['failed to create the action', new Error('an error')] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('errors out on create with memory below min', async () => { - const flag = '--memory' - const invalidValue = '127' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 128 but received: ${invalidValue}\nSee more help with --help`) - }) +test('errors out on create with timeout below min', async () => { + const flag = '--timeout' + const invalidValue = '99' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 100 but received: ${invalidValue}\nSee more help with --help`) +}) - test('errors out on create with memory above max', async () => { - const flag = '--memory' - const invalidValue = '4097' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 4096 but received: ${invalidValue}\nSee more help with --help`) - }) +test('errors out on create with timeout above max', async () => { + const flag = '--timeout' + const invalidValue = '3600001' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 3600000 but received: ${invalidValue}\nSee more help with --help`) +}) - test('errors out on create with logsize below min', async () => { - const flag = '--logsize' - const invalidValue = '-1' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 0 but received: ${invalidValue}\nSee more help with --help`) - }) +test('errors out on create with memory below min', async () => { + const flag = '--memory' + const invalidValue = '127' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 128 but received: ${invalidValue}\nSee more help with --help`) +}) - test('errors out on create with logsize above max', async () => { - const flag = '--logsize' - const invalidValue = '11' - command.argv = [flag, invalidValue] - await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 10 but received: ${invalidValue}\nSee more help with --help`) - }) +test('errors out on create with memory above max', async () => { + const flag = '--memory' + const invalidValue = '4097' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 4096 but received: ${invalidValue}\nSee more help with --help`) +}) - test('errors on --web-secure with --web false flag', async () => { - rtLib.mockRejected(rtAction, '') - command.argv = ['hello', '/action/fileWithNoExt', '--web-secure', 'true', '--web', 'false'] - const error = ['failed to create the action', new Error(TheCommand.errorMessages.websecure)] - await expect(rejectWithError(command, error, handleError)).toBeTruthy() - }) +test('errors out on create with logsize below min', async () => { + const flag = '--logsize' + const invalidValue = '-1' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer greater than or equal to 0 but received: ${invalidValue}\nSee more help with --help`) +}) + +test('errors out on create with logsize above max', async () => { + const flag = '--logsize' + const invalidValue = '11' + command.argv = [flag, invalidValue] + await expect(command.run()).rejects.toThrow(`Parsing ${flag} \n\tExpected an integer less than or equal to 10 but received: ${invalidValue}\nSee more help with --help`) +}) + +test('errors on --web-secure with --web false flag', async () => { + rtLib.mockRejected(rtAction, '') + command.argv = ['hello', '/action/fileWithNoExt', '--web-secure', 'true', '--web', 'false'] + const error = ['failed to create the action', new Error(TheCommand.errorMessages.websecure)] + await expect(command.run()).rejects.toThrow(...error) + expect(handleError).toHaveBeenLastCalledWith(...error) +}) - test('aio runtime:action:create newAction --copy oldAction', () => { - const oldActionJson = require('../../../__fixtures__/action/get.json') - const cmdGet = rtLib.mockResolvedFixture(rtActionGet, 'action/get.json') - const cmdCreate = rtLib.mockResolved(rtAction, { fake: '' }) - const name = 'oldAction' - const newAction = 'newAction' - command.argv = [newAction, '--copy', name] - return command.run() - .then(() => { - expect(cmdGet).toHaveBeenCalledWith(name) - expect(cmdCreate).toHaveBeenCalledWith({ name: newAction, action: oldActionJson }) - expect(stdout.output).toMatch('') - }) +test('aio runtime:action:create newAction --copy oldAction', () => { + const oldActionJson = require('../../../__fixtures__/action/get.json') + const cmdGet = rtLib.mockResolvedFixture(rtActionGet, 'action/get.json') + const cmdCreate = rtLib.mockResolved(rtAction, { fake: '' }) + const name = 'oldAction' + const newAction = 'newAction' + command.argv = [newAction, '--copy', name] + return command.run() + .then(() => { + expect(cmdGet).toHaveBeenCalledWith(name) + expect(cmdCreate).toHaveBeenCalledWith({ name: newAction, action: oldActionJson }) + expect(stdout.output).toMatch('') }) - }) }) diff --git a/test/jest.setup.js b/test/jest.setup.js index 255cb69c..c333ebed 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -11,15 +11,14 @@ governing permissions and limitations under the License. */ const { stdout } = require('stdout-stderr') -const fs = jest.requireActual('fs') +const realFs = jest.requireActual('fs') +const fs = require('fs') const eol = require('eol') +const path = require('path') jest.setTimeout(30000) jest.useFakeTimers() -// dont touch the real fs -jest.mock('fs', () => require('jest-plugin-fs/mock')) - // ensure a mocked openwhisk module for unit-tests jest.mock('openwhisk') @@ -36,9 +35,71 @@ delete process.env.WSK_CONFIG_FILE beforeEach(() => { stdout.start() }) afterEach(() => { stdout.stop() }) +jest.mock('fs', () => ({ + ...jest.requireActual('fs'), + existsSync: jest.fn(), + // we have to have the default behaviour at the start since @oclif/core does some file reading on require + readFileSync: jest.fn((p) => jest.requireActual('fs').readFileSync(p)), + unlinkSync: jest.fn(), + rmdirSync: jest.fn(), + readdirSync: jest.fn() +})) + +global.createFileSystem = (initialFiles = {}) => { + const myFileSystem = { ...initialFiles } + + fs.existsSync.mockImplementation((filePath) => { + const value = !!myFileSystem[filePath] + if (!value) { + return realFs.existsSync(filePath) + } else { + return value + } + }) + + fs.readFileSync.mockImplementation((filePath) => { + const value = myFileSystem[filePath] + if (!value) { + return realFs.readFileSync(filePath) + } else { + return value + } + }) + + const removeFile = (filePath) => { + delete myFileSystem[filePath] + } + + fs.unlinkSync.mockImplementation(removeFile) + fs.rmdirSync.mockImplementation(removeFile) + + fs.readdirSync.mockImplementation((filePath) => { + const item = myFileSystem[filePath] + if (!Array.isArray(item)) { + throw new Error(`Fake filesystem ${filePath} value does not contain an array.`) + } + return item + }) + + return myFileSystem +} + +global.clearMockedFs = () => { + const mockedFs = require('fs') + + mockedFs.existsSync.mockImplementation((p) => realFs.existsSync(p)) + mockedFs.readFileSync.mockImplementation((p) => realFs.readFileSync(p)) + mockedFs.unlinkSync.mockImplementation((p) => realFs.unlinkSync(p)) + mockedFs.rmdirSync.mockImplementation((p) => realFs.rmdirSync(p)) + mockedFs.readdirSync.mockImplementation((p) => realFs.readdirSync(p)) +} + // helper for fixtures global.fixtureFile = (output) => { - return fs.readFileSync(`./test/__fixtures__/${output}`).toString() + if (!realFs.existsSync(`./test/__fixtures__/${output}`)) { + throw new Error(`./test/__fixtures__/${output}` + ' not found') + } + return realFs.readFileSync(`./test/__fixtures__/${output}`).toString() } // helper for fixtures, with regex replacement of place holders @@ -103,57 +164,13 @@ global.fixtureFileWithTimeZoneAdjustment = (() => { // helper for fixtures global.fixtureJson = (output) => { - return JSON.parse(fs.readFileSync(`./test/__fixtures__/${output}`).toString()) + return JSON.parse(realFs.readFileSync(path.join(__dirname, '__fixtures__', output)).toString()) } // helper for zip fixtures global.fixtureZip = (output) => { - return fs.readFileSync(`./test/__fixtures__/${output}`) -} - -// define a filesystem with a fake .wskprops -const wskprops = require('path').join(require('os').homedir(), '.wskprops') -const wskPropsFs = { - [wskprops]: global.fixtureFile('wsk.properties') -} -const emptyWskPropsFs = { - [wskprops]: global.fixtureFile('empty-wsk.properties') -} - -// set the fake filesystem -const ffs = require('jest-plugin-fs').default - -global.fakeFileSystem = { - addJson: (json) => { - // add to existing - ffs.mock(json) - }, - removeKeys: (arr) => { - // remove from existing - const files = ffs.files() - for (const prop in files) { - if (arr.includes(prop)) { - delete files[prop] - } - } - ffs.restore() - ffs.mock(files) - }, - clear: () => { - // reset to empty - ffs.restore() - }, - reset: ({ emptyWskProps = false } = {}) => { - // reset to file system with wskprops - ffs.restore() - ffs.mock(emptyWskProps ? emptyWskPropsFs : wskPropsFs) - }, - files: () => { - return ffs.files() - } + return realFs.readFileSync(path.join(__dirname, '__fixtures__', output)) } -// seed the fake filesystem -fakeFileSystem.reset() global.createTestBaseFlagsFunction = (TheCommand, BaseCommand) => { return global.createTestFlagsFunction(TheCommand, BaseCommand.flags) From 97cbef4088e5457d40acb16f9fce003a07dfcbcc Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Fri, 21 Jul 2023 02:54:38 +0800 Subject: [PATCH 3/7] fixed unit tests with full coverage --- .eslintrc | 1 + package.json | 3 +- src/commands/runtime/action/create.js | 10 --- src/commands/runtime/action/delete.js | 11 ++- src/commands/runtime/action/get.js | 11 ++- src/commands/runtime/action/invoke.js | 11 ++- src/commands/runtime/action/list.js | 13 ++- src/commands/runtime/action/update.js | 10 +-- src/commands/runtime/activation/get.js | 15 ++-- src/commands/runtime/activation/list.js | 12 ++- src/commands/runtime/activation/logs.js | 10 +-- src/commands/runtime/activation/result.js | 13 ++- src/commands/runtime/api/create.js | 24 +++-- src/commands/runtime/api/delete.js | 21 ++--- src/commands/runtime/api/get.js | 11 ++- src/commands/runtime/api/list.js | 23 +++-- src/commands/runtime/namespace/get.js | 10 +-- src/commands/runtime/namespace/list.js | 4 +- src/commands/runtime/package/bind.js | 16 ++-- src/commands/runtime/package/create.js | 11 ++- src/commands/runtime/package/delete.js | 11 ++- src/commands/runtime/package/get.js | 10 +-- src/commands/runtime/package/list.js | 12 ++- src/commands/runtime/package/update.js | 10 +-- src/commands/runtime/property/get.js | 4 +- src/commands/runtime/rule/create.js | 21 ++--- src/commands/runtime/rule/delete.js | 11 ++- src/commands/runtime/rule/disable.js | 10 +-- src/commands/runtime/rule/enable.js | 10 +-- src/commands/runtime/rule/get.js | 10 +-- src/commands/runtime/rule/list.js | 4 +- src/commands/runtime/rule/status.js | 10 +-- src/commands/runtime/rule/update.js | 20 ++--- src/commands/runtime/trigger/create.js | 11 ++- src/commands/runtime/trigger/delete.js | 10 +-- src/commands/runtime/trigger/fire.js | 11 ++- src/commands/runtime/trigger/get.js | 10 +-- src/commands/runtime/trigger/list.js | 4 +- src/commands/runtime/trigger/update.js | 10 +-- test/RuntimeBaseCommand.test.js | 19 ++-- test/__fixtures__/deploy/main.js | 7 +- test/commands/runtime/action/create.test.js | 1 - test/commands/runtime/action/delete.test.js | 6 +- test/commands/runtime/action/get.test.js | 11 +-- test/commands/runtime/action/index.test.js | 2 +- test/commands/runtime/action/invoke.test.js | 8 +- test/commands/runtime/action/update.test.js | 25 +++--- test/commands/runtime/activation/get.test.js | 4 +- .../commands/runtime/activation/index.test.js | 2 +- test/commands/runtime/activation/list.test.js | 4 +- test/commands/runtime/activation/logs.test.js | 4 +- .../runtime/activation/result.test.js | 4 +- test/commands/runtime/api/create.test.js | 54 +++++------ test/commands/runtime/api/delete.test.js | 27 +++--- test/commands/runtime/api/get.test.js | 13 ++- test/commands/runtime/api/index.test.js | 2 +- test/commands/runtime/api/list.test.js | 31 +++---- test/commands/runtime/deploy/export.test.js | 89 +++++++++++-------- test/commands/runtime/index.test.js | 2 +- test/commands/runtime/namespace/get.test.js | 5 +- test/commands/runtime/namespace/index.test.js | 2 +- test/commands/runtime/namespace/list.test.js | 5 +- test/commands/runtime/package/bind.test.js | 15 ++-- test/commands/runtime/package/create.test.js | 8 +- test/commands/runtime/package/delete.test.js | 6 +- test/commands/runtime/package/get.test.js | 6 +- test/commands/runtime/package/index.test.js | 2 +- test/commands/runtime/package/list.test.js | 4 +- test/commands/runtime/package/update.test.js | 8 +- test/commands/runtime/property/get.test.js | 47 ++++++++-- test/commands/runtime/property/index.test.js | 2 +- test/commands/runtime/property/set.test.js | 77 ++++------------ test/commands/runtime/property/unset.test.js | 77 ++++------------ test/commands/runtime/rule/create.test.js | 25 +++--- test/commands/runtime/rule/delete.test.js | 13 ++- test/commands/runtime/rule/disable.test.js | 13 ++- test/commands/runtime/rule/enable.test.js | 13 ++- test/commands/runtime/rule/get.test.js | 13 ++- test/commands/runtime/rule/index.test.js | 2 +- test/commands/runtime/rule/list.test.js | 22 ++--- test/commands/runtime/rule/status.test.js | 13 ++- test/commands/runtime/rule/update.test.js | 25 +++--- test/commands/runtime/trigger/create.test.js | 12 ++- test/commands/runtime/trigger/delete.test.js | 12 ++- test/commands/runtime/trigger/fire.test.js | 12 ++- test/commands/runtime/trigger/get.test.js | 12 ++- test/commands/runtime/trigger/index.test.js | 2 +- test/commands/runtime/trigger/list.test.js | 5 +- test/commands/runtime/trigger/update.test.js | 12 ++- test/jest.setup.js | 26 ++++-- 90 files changed, 550 insertions(+), 700 deletions(-) diff --git a/.eslintrc b/.eslintrc index 999a32a0..1db58df3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,7 @@ { "extends": "@adobe/eslint-config-aio-lib-config", "globals": { + "WSK_PROPS_PATH": true, "createFileSystem": true, "clearMockedFs": true, "fixtureFile": true, diff --git a/package.json b/package.json index 5898277d..917110a8 100644 --- a/package.json +++ b/package.json @@ -68,11 +68,10 @@ }, "repository": "adobe/aio-cli-plugin-runtime", "scripts": { - "jest:debug": "jest --runInBand test/commands/runtime/action/create*", "eslint-fix": "eslint src test e2e --fix", "posttest": "eslint src test e2e", "test": "npm run unit-tests", - "unit-tests": "jest --ci", + "unit-tests": "jest --ci --runInBand test", "prepack": "oclif manifest && oclif readme --no-aliases", "postpack": "rm -f oclif.manifest.json", "version": "oclif readme --no-aliases && git add README.md", diff --git a/src/commands/runtime/action/create.js b/src/commands/runtime/action/create.js index 38db9a3a..709e75b1 100644 --- a/src/commands/runtime/action/create.js +++ b/src/commands/runtime/action/create.js @@ -220,16 +220,6 @@ class ActionCreate extends RuntimeBaseCommand { } } -// ActionCreate.args0 = [ -// { -// name: 'actionName', -// required: true -// }, -// { -// name: 'actionPath' -// } -// ] - ActionCreate.args = { actionName: Args.string({ required: true }), actionPath: Args.string() diff --git a/src/commands/runtime/action/delete.js b/src/commands/runtime/action/delete.js index 31532a2e..67b2b8b5 100644 --- a/src/commands/runtime/action/delete.js +++ b/src/commands/runtime/action/delete.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class ActionDelete extends RuntimeBaseCommand { async run () { @@ -29,12 +29,11 @@ class ActionDelete extends RuntimeBaseCommand { } } -ActionDelete.args = [ - { - name: 'actionName', +ActionDelete.args = { + actionName: Args.string({ required: true - } -] + }) +} ActionDelete.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/action/get.js b/src/commands/runtime/action/get.js index 23553f53..a3fb41ea 100644 --- a/src/commands/runtime/action/get.js +++ b/src/commands/runtime/action/get.js @@ -13,7 +13,7 @@ governing permissions and limitations under the License. const fs = require('fs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { fileExtensionForKind } = require('../../../kinds') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class ActionGet extends RuntimeBaseCommand { async run () { @@ -93,12 +93,11 @@ class ActionGet extends RuntimeBaseCommand { } } -ActionGet.args = [ - { - name: 'actionName', +ActionGet.args = { + actionName: Args.string({ required: true - } -] + }) +} ActionGet.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/action/invoke.js b/src/commands/runtime/action/invoke.js index 4f0f4968..42abefc3 100644 --- a/src/commands/runtime/action/invoke.js +++ b/src/commands/runtime/action/invoke.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') const { getKeyValueObjectFromMergedParameters } = require('@adobe/aio-lib-runtime').utils class ActionInvoke extends RuntimeBaseCommand { @@ -49,12 +49,11 @@ class ActionInvoke extends RuntimeBaseCommand { } } -ActionInvoke.args = [ - { - name: 'actionName', +ActionInvoke.args = { + actionName: Args.string({ required: true - } -] + }) +} ActionInvoke.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/action/list.js b/src/commands/runtime/action/list.js index 4f5cf18d..33461cc4 100644 --- a/src/commands/runtime/action/list.js +++ b/src/commands/runtime/action/list.js @@ -13,7 +13,7 @@ governing permissions and limitations under the License. const moment = require('dayjs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePackageName } = require('@adobe/aio-lib-runtime').utils -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, Args, ux } = require('@oclif/core') const decorators = require('../../../decorators').decorators() class ActionList extends RuntimeBaseCommand { @@ -86,7 +86,7 @@ class ActionList extends RuntimeBaseCommand { } } } - cli.ux.table(result, columns) + ux.table(result, columns) } } catch (err) { await this.handleError('failed to list the actions', err) @@ -94,12 +94,11 @@ class ActionList extends RuntimeBaseCommand { } } -ActionList.args = [ - { - name: 'packageName', +ActionList.args = { + packageName: Args.string({ required: false - } -] + }) +} ActionList.limits = { min: 0, diff --git a/src/commands/runtime/action/update.js b/src/commands/runtime/action/update.js index fe830c41..fb1d62b7 100644 --- a/src/commands/runtime/action/update.js +++ b/src/commands/runtime/action/update.js @@ -16,15 +16,7 @@ class ActionUpdate extends ActionCreate { isUpdate () { return true } } -ActionUpdate.args = [ - { - name: 'actionName', - required: true - }, - { - name: 'actionPath' - } -] +ActionUpdate.args = ActionCreate.args ActionUpdate.flags = ActionCreate.flags diff --git a/src/commands/runtime/activation/get.js b/src/commands/runtime/activation/get.js index a4772f5a..68bdb985 100644 --- a/src/commands/runtime/activation/get.js +++ b/src/commands/runtime/activation/get.js @@ -9,14 +9,14 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { printLogs } = require('@adobe/aio-lib-runtime').utils class ActivationGet extends RuntimeBaseCommand { async run () { const { args, flags } = await this.parse(ActivationGet) - let id = args.activationID + let id = args.activationId try { const ow = await this.wsk() if (flags.last) { @@ -28,7 +28,7 @@ class ActivationGet extends RuntimeBaseCommand { } } if (!id) { - this.error('missing required argument activationID') + this.error('missing required argument activationId') } if (flags.logs) { @@ -45,11 +45,10 @@ class ActivationGet extends RuntimeBaseCommand { } } -ActivationGet.args = [ - { - name: 'activationID' - } -] +ActivationGet.args = { + activationId: Args.string({ + }) +} ActivationGet.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/activation/list.js b/src/commands/runtime/activation/list.js index e8b2444a..9d6b6f1e 100644 --- a/src/commands/runtime/activation/list.js +++ b/src/commands/runtime/activation/list.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const moment = require('dayjs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, Args, ux } = require('@oclif/core') const decorators = require('../../../decorators').decorators() const statusStrings = ['success', 'app error', 'dev error', 'sys error'] @@ -187,7 +187,7 @@ class ActivationList extends RuntimeBaseCommand { } } if (listActivation) { - cli.ux.table(listActivation, columns, { + ux.table(listActivation, columns, { 'no-truncate': true }) } @@ -198,11 +198,9 @@ class ActivationList extends RuntimeBaseCommand { } } -ActivationList.args = [ - { - name: 'action_name' - } -] +ActivationList.args = { + action_name: Args.string({}) +} ActivationList.limits = { min: 0, diff --git a/src/commands/runtime/activation/logs.js b/src/commands/runtime/activation/logs.js index aad2cb35..e8d667bd 100644 --- a/src/commands/runtime/activation/logs.js +++ b/src/commands/runtime/activation/logs.js @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const rtLib = require('@adobe/aio-lib-runtime') const printLogs = rtLib.utils.printLogs @@ -86,11 +86,9 @@ class ActivationLogs extends RuntimeBaseCommand { } } -ActivationLogs.args = [ - { - name: 'activationId' - } -] +ActivationLogs.args = { + activationId: Args.string({}) +} ActivationLogs.limits = { min: 0, diff --git a/src/commands/runtime/activation/result.js b/src/commands/runtime/activation/result.js index 270e7181..cb27021d 100644 --- a/src/commands/runtime/activation/result.js +++ b/src/commands/runtime/activation/result.js @@ -10,13 +10,13 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') class ActivationResult extends RuntimeBaseCommand { async run () { const { args, flags } = await this.parse(ActivationResult) - let id = args.activationID + let id = args.activationId try { const ow = await this.wsk() if (flags.last) { @@ -35,11 +35,10 @@ class ActivationResult extends RuntimeBaseCommand { } } -ActivationResult.args = [ - { - name: 'activationID' - } -] +ActivationResult.args = { + activationId: Args.string({ + }) +} ActivationResult.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/api/create.js b/src/commands/runtime/api/create.js index e6a2794c..abbb8c5a 100644 --- a/src/commands/runtime/api/create.js +++ b/src/commands/runtime/api/create.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') const fs = require('fs') class ApiCreate extends RuntimeBaseCommand { @@ -48,29 +48,27 @@ class ApiCreate extends RuntimeBaseCommand { } } -ApiCreate.args = [ - { - name: 'basePath', +ApiCreate.args = { + basePath: Args.string({ required: false, description: 'The base path of the api' - }, - { - name: 'relPath', + }), + relPath: Args.string({ required: false, description: 'The path of the api relative to the base path' - }, - { + }), + apiVerb: Args.string({ name: 'apiVerb', required: false, description: 'The http verb', options: ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'] - }, - { + }), + action: Args.string({ name: 'action', required: false, description: 'The action to call' - } -] + }) +} ApiCreate.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/api/delete.js b/src/commands/runtime/api/delete.js index 2f3d08e6..cdfdff47 100644 --- a/src/commands/runtime/api/delete.js +++ b/src/commands/runtime/api/delete.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -// eslint-disable-next-line no-unused-vars +const { Args } = require('@oclif/core') class ApiDelete extends RuntimeBaseCommand { async run () { @@ -31,22 +31,19 @@ class ApiDelete extends RuntimeBaseCommand { } } -ApiDelete.args = [ - { - name: 'basePathOrApiName', +ApiDelete.args = { + basePathOrApiName: Args.string({ required: true, description: 'The base path or api name' - }, - { - name: 'relPath', + }), + relPath: Args.string({ description: 'The path of the api relative to the base path' - }, - { - name: 'apiVerb', + }), + apiVerb: Args.string({ description: 'The http verb', options: ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'] - } -] + }) +} ApiDelete.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/api/get.js b/src/commands/runtime/api/get.js index f3c32567..ac278ff5 100644 --- a/src/commands/runtime/api/get.js +++ b/src/commands/runtime/api/get.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -// eslint-disable-next-line no-unused-vars +const { Args } = require('@oclif/core') class ApiGet extends RuntimeBaseCommand { async run () { @@ -30,13 +30,12 @@ class ApiGet extends RuntimeBaseCommand { } } -ApiGet.args = [ - { - name: 'basePathOrApiName', +ApiGet.args = { + basePathOrApiName: Args.string({ required: true, description: 'The base path or api name' - } -] + }) +} ApiGet.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/api/list.js b/src/commands/runtime/api/list.js index f88ade06..f329d4f4 100644 --- a/src/commands/runtime/api/list.js +++ b/src/commands/runtime/api/list.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, Args, ux } = require('@oclif/core') /** @private */ function processApi (api) { @@ -66,7 +66,7 @@ class ApiList extends RuntimeBaseCommand { }, data) }) - cli.ux.table(data, { + ux.table(data, { Action: { minWidth: 10 }, Verb: { minWidth: 10 }, APIName: { header: 'API Name', minWidth: 10 }, @@ -83,21 +83,18 @@ class ApiList extends RuntimeBaseCommand { } } -ApiList.args = [ - { - name: 'basePath', +ApiList.args = { + basePath: Args.string({ description: 'The base path of the api' - }, - { - name: 'relPath', + }), + relPath: Args.string({ description: 'The path of the api relative to the base path' - }, - { - name: 'apiVerb', + }), + apiVerb: Args.string({ description: 'The http verb', options: ['get', 'post', 'put', 'patch', 'delete', 'head', 'options'] - } -] + }) +} ApiList.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/namespace/get.js b/src/commands/runtime/namespace/get.js index 29d588d6..613bf475 100644 --- a/src/commands/runtime/namespace/get.js +++ b/src/commands/runtime/namespace/get.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, ux } = require('@oclif/core') /** @private */ function createColumns (columnName) { @@ -79,10 +79,10 @@ class NamespaceGet extends RuntimeBaseCommand { } else { this.log('Entities in namespace:') - cli.ux.table(data.packages, createColumns('packages')) - cli.ux.table(data.actions, createColumns('actions')) - cli.ux.table(data.triggers, createColumns('triggers')) - cli.ux.table(data.rules, createColumns('rules')) + ux.table(data.packages, createColumns('packages')) + ux.table(data.actions, createColumns('actions')) + ux.table(data.triggers, createColumns('triggers')) + ux.table(data.rules, createColumns('rules')) } } catch (err) { await this.handleError('failed to get the data for a namespace', err) diff --git a/src/commands/runtime/namespace/list.js b/src/commands/runtime/namespace/list.js index a2106ee4..1cd804a2 100644 --- a/src/commands/runtime/namespace/list.js +++ b/src/commands/runtime/namespace/list.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, ux } = require('@oclif/core') class NamespaceList extends RuntimeBaseCommand { async run () { @@ -29,7 +29,7 @@ class NamespaceList extends RuntimeBaseCommand { get: row => row } } - cli.ux.table(result, columns) + ux.table(result, columns) } } catch (err) { await this.handleError('failed to list namespaces', err) diff --git a/src/commands/runtime/package/bind.js b/src/commands/runtime/package/bind.js index 47aecb10..e7a1f941 100644 --- a/src/commands/runtime/package/bind.js +++ b/src/commands/runtime/package/bind.js @@ -13,7 +13,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePackageName } = require('@adobe/aio-lib-runtime').utils const { getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class PackageBind extends RuntimeBaseCommand { async run () { @@ -42,16 +42,14 @@ class PackageBind extends RuntimeBaseCommand { } } -PackageBind.args = [ - { - name: 'packageName', +PackageBind.args = { + packageName: Args.string({ required: true - }, - { - name: 'bindPackageName', + }), + bindPackageName: Args.string({ required: true - } -] + }) +} PackageBind.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/package/create.js b/src/commands/runtime/package/create.js index baae386f..17443c5f 100644 --- a/src/commands/runtime/package/create.js +++ b/src/commands/runtime/package/create.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class PackageCreate extends RuntimeBaseCommand { isUpdate () { return false } @@ -59,12 +59,11 @@ class PackageCreate extends RuntimeBaseCommand { } } -PackageCreate.args = [ - { - name: 'packageName', +PackageCreate.args = { + packageName: Args.string({ required: true - } -] + }) +} PackageCreate.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/package/delete.js b/src/commands/runtime/package/delete.js index 0cc603a0..c84c69ed 100644 --- a/src/commands/runtime/package/delete.js +++ b/src/commands/runtime/package/delete.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePackageName } = require('@adobe/aio-lib-runtime').utils -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class PackageDelete extends RuntimeBaseCommand { async run () { @@ -74,12 +74,11 @@ async function recursivelyDeletePackage (ow, pkg) { return ow.packages.delete(pkg) } -PackageDelete.args = [ - { - name: 'packageName', +PackageDelete.args = { + packageName: Args.string({ required: true - } -] + }) +} PackageDelete.flags = { json: Flags.boolean({ diff --git a/src/commands/runtime/package/get.js b/src/commands/runtime/package/get.js index e9de0be1..49850ccf 100644 --- a/src/commands/runtime/package/get.js +++ b/src/commands/runtime/package/get.js @@ -12,6 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePackageName } = require('@adobe/aio-lib-runtime').utils +const { Args } = require('@oclif/core') class PackageGet extends RuntimeBaseCommand { async run () { @@ -27,12 +28,11 @@ class PackageGet extends RuntimeBaseCommand { } } -PackageGet.args = [ - { - name: 'packageName', +PackageGet.args = { + packageName: Args.string({ required: true - } -] + }) +} PackageGet.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/package/list.js b/src/commands/runtime/package/list.js index c3d2643b..151c91f6 100644 --- a/src/commands/runtime/package/list.js +++ b/src/commands/runtime/package/list.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const moment = require('dayjs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, Args, ux } = require('@oclif/core') class PackageList extends RuntimeBaseCommand { async run () { @@ -78,7 +78,7 @@ class PackageList extends RuntimeBaseCommand { get: row => row.name } } - cli.ux.table(result, columns) + ux.table(result, columns) } } catch (err) { await this.handleError('failed to list the packages', err) @@ -121,11 +121,9 @@ PackageList.flags = { }) } -PackageList.args = [ - { - name: 'namespace' - } -] +PackageList.args = { + namespace: Args.string({}) +} PackageList.description = 'Lists all the Packages' diff --git a/src/commands/runtime/package/update.js b/src/commands/runtime/package/update.js index f49a2a32..6144a50b 100644 --- a/src/commands/runtime/package/update.js +++ b/src/commands/runtime/package/update.js @@ -11,17 +11,17 @@ governing permissions and limitations under the License. */ const PackageCreate = require('./create') +const { Args } = require('@oclif/core') class PackageUpdate extends PackageCreate { isUpdate () { return true } } -PackageUpdate.args = [ - { - name: 'packageName', +PackageUpdate.args = { + packageName: Args.string({ required: true - } -] + }) +} PackageUpdate.flags = PackageCreate.flags diff --git a/src/commands/runtime/property/get.js b/src/commands/runtime/property/get.js index 0d5b1b7f..a041de77 100644 --- a/src/commands/runtime/property/get.js +++ b/src/commands/runtime/property/get.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: { ux: cli } } = require('@oclif/core') +const { Flags, ux } = require('@oclif/core') const { createFetch } = require('@adobe/aio-lib-core-networking') const { PropertyKey, PropertyDefault, propertiesFile, PropertyEnv } = require('../../../properties') const debug = require('debug')('aio-cli-plugin-runtime/property') @@ -90,7 +90,7 @@ class PropertyGet extends RuntimeBaseCommand { data.push({ Property: PropertyGet.flags.apibuildno.description, Value: result.buildno }) } } - cli.table(data, + ux.table(data, { Property: { minWidth: 10 }, Value: { minWidth: 20 } diff --git a/src/commands/runtime/rule/create.js b/src/commands/runtime/rule/create.js index b01d4d47..4ef43ccb 100644 --- a/src/commands/runtime/rule/create.js +++ b/src/commands/runtime/rule/create.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class RuleCreate extends RuntimeBaseCommand { isUpdate () { return false } @@ -34,23 +34,20 @@ class RuleCreate extends RuntimeBaseCommand { RuleCreate.description = 'Create a Rule' -RuleCreate.args = [ - { - name: 'name', +RuleCreate.args = { + name: Args.string({ required: true, description: 'Name of the rule' - }, - { - name: 'trigger', + }), + trigger: Args.string({ required: true, description: 'Name of the trigger' - }, - { - name: 'action', + }), + action: Args.string({ required: true, description: 'Name of the action' - } -] + }) +} RuleCreate.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/rule/delete.js b/src/commands/runtime/rule/delete.js index fd8e7a2e..f5f9eb9e 100644 --- a/src/commands/runtime/rule/delete.js +++ b/src/commands/runtime/rule/delete.js @@ -10,7 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class RuleDelete extends RuntimeBaseCommand { async run () { @@ -30,13 +30,12 @@ class RuleDelete extends RuntimeBaseCommand { RuleDelete.description = 'Delete a Rule' -RuleDelete.args = [ - { - name: 'name', +RuleDelete.args = { + name: Args.string({ required: true, description: 'Name of the rule' - } -] + }) +} RuleDelete.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/rule/disable.js b/src/commands/runtime/rule/disable.js index 5f28ec40..33b253fc 100644 --- a/src/commands/runtime/rule/disable.js +++ b/src/commands/runtime/rule/disable.js @@ -10,6 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const { Args } = require('@oclif/core') class RuleDisable extends RuntimeBaseCommand { async run () { @@ -27,13 +28,12 @@ class RuleDisable extends RuntimeBaseCommand { RuleDisable.description = 'Disable a Rule' -RuleDisable.args = [ - { - name: 'name', +RuleDisable.args = { + name: Args.string({ required: true, description: 'Name of the rule' - } -] + }) +} RuleDisable.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/rule/enable.js b/src/commands/runtime/rule/enable.js index 916125ad..1498e55f 100644 --- a/src/commands/runtime/rule/enable.js +++ b/src/commands/runtime/rule/enable.js @@ -10,6 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const { Args } = require('@oclif/core') class RuleEnable extends RuntimeBaseCommand { async run () { @@ -27,13 +28,12 @@ class RuleEnable extends RuntimeBaseCommand { RuleEnable.description = 'Enable a Rule' -RuleEnable.args = [ - { - name: 'name', +RuleEnable.args = { + name: Args.string({ required: true, description: 'Name of the rule' - } -] + }) +} RuleEnable.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/rule/get.js b/src/commands/runtime/rule/get.js index fc57e538..eb087cc2 100644 --- a/src/commands/runtime/rule/get.js +++ b/src/commands/runtime/rule/get.js @@ -10,6 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const { Args } = require('@oclif/core') class RuleGet extends RuntimeBaseCommand { async run () { @@ -27,13 +28,12 @@ class RuleGet extends RuntimeBaseCommand { RuleGet.description = 'Retrieves a Rule' -RuleGet.args = [ - { - name: 'name', +RuleGet.args = { + name: Args.string({ required: true, description: 'Name of the rule' - } -] + }) +} RuleGet.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/rule/list.js b/src/commands/runtime/rule/list.js index 611fe4de..1b7fa754 100644 --- a/src/commands/runtime/rule/list.js +++ b/src/commands/runtime/rule/list.js @@ -11,7 +11,7 @@ governing permissions and limitations under the License. const moment = require('dayjs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, ux } = require('@oclif/core') class RuleList extends RuntimeBaseCommand { async run () { @@ -68,7 +68,7 @@ class RuleList extends RuntimeBaseCommand { get: row => row.name } } - cli.ux.table(resultsWithStatus, columns) + ux.table(resultsWithStatus, columns) } }) return p diff --git a/src/commands/runtime/rule/status.js b/src/commands/runtime/rule/status.js index e23326c3..7a52fa81 100644 --- a/src/commands/runtime/rule/status.js +++ b/src/commands/runtime/rule/status.js @@ -10,6 +10,7 @@ governing permissions and limitations under the License. */ const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') +const { Args } = require('@oclif/core') class RuleStatus extends RuntimeBaseCommand { async run () { @@ -27,13 +28,12 @@ class RuleStatus extends RuntimeBaseCommand { RuleStatus.description = 'Gets the status of a rule' -RuleStatus.args = [ - { - name: 'name', +RuleStatus.args = { + name: Args.string({ required: true, description: 'Name of the rule' - } -] + }) +} RuleStatus.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/rule/update.js b/src/commands/runtime/rule/update.js index 1556ba40..b6e6c403 100644 --- a/src/commands/runtime/rule/update.js +++ b/src/commands/runtime/rule/update.js @@ -10,6 +10,7 @@ governing permissions and limitations under the License. */ const RuleCreate = require('./create') +const { Args } = require('@oclif/core') class RuleUpdate extends RuleCreate { isUpdate () { return true } @@ -17,23 +18,20 @@ class RuleUpdate extends RuleCreate { RuleUpdate.description = 'Update a Rule' -RuleUpdate.args = [ - { - name: 'name', +RuleUpdate.args = { + name: Args.string({ required: true, description: 'Name of the rule' - }, - { - name: 'trigger', + }), + trigger: Args.string({ required: true, description: 'Name of the trigger' - }, - { - name: 'action', + }), + action: Args.string({ required: true, description: 'Name of the action' - } -] + }) +} RuleUpdate.flags = RuleCreate.flags diff --git a/src/commands/runtime/trigger/create.js b/src/commands/runtime/trigger/create.js index 16022071..87fd36e8 100644 --- a/src/commands/runtime/trigger/create.js +++ b/src/commands/runtime/trigger/create.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { getKeyValueArrayFromMergedParameters } = require('@adobe/aio-lib-runtime').utils -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class TriggerCreate extends RuntimeBaseCommand { isUpdate () { return false } @@ -53,13 +53,12 @@ class TriggerCreate extends RuntimeBaseCommand { } } -TriggerCreate.args = [ - { - name: 'triggerName', +TriggerCreate.args = { + triggerName: Args.string({ required: true, description: 'The name of the trigger' - } -] + }) +} TriggerCreate.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/trigger/delete.js b/src/commands/runtime/trigger/delete.js index 9d56e45e..53ca6f2e 100644 --- a/src/commands/runtime/trigger/delete.js +++ b/src/commands/runtime/trigger/delete.js @@ -12,6 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePathPattern } = require('@adobe/aio-lib-runtime').utils +const { Args } = require('@oclif/core') class TriggerDelete extends RuntimeBaseCommand { async run () { @@ -29,13 +30,12 @@ class TriggerDelete extends RuntimeBaseCommand { } } -TriggerDelete.args = [ - { - name: 'triggerPath', +TriggerDelete.args = { + triggerPath: Args.string({ required: true, description: 'The name of the trigger, in the format /NAMESPACE/NAME' - } -] + }) +} TriggerDelete.flags = { ...RuntimeBaseCommand.flags diff --git a/src/commands/runtime/trigger/fire.js b/src/commands/runtime/trigger/fire.js index 531cf322..680673fc 100644 --- a/src/commands/runtime/trigger/fire.js +++ b/src/commands/runtime/trigger/fire.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { getKeyValueObjectFromMergedParameters } = require('@adobe/aio-lib-runtime').utils -const { Flags } = require('@oclif/core') +const { Flags, Args } = require('@oclif/core') class TriggerFire extends RuntimeBaseCommand { async run () { @@ -34,13 +34,12 @@ class TriggerFire extends RuntimeBaseCommand { } } -TriggerFire.args = [ - { - name: 'triggerName', +TriggerFire.args = { + triggerName: Args.string({ required: true, description: 'The name of the trigger' - } -] + }) +} TriggerFire.flags = { ...RuntimeBaseCommand.flags, diff --git a/src/commands/runtime/trigger/get.js b/src/commands/runtime/trigger/get.js index 1b5557b4..a0f75550 100644 --- a/src/commands/runtime/trigger/get.js +++ b/src/commands/runtime/trigger/get.js @@ -12,6 +12,7 @@ governing permissions and limitations under the License. const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') const { parsePathPattern } = require('@adobe/aio-lib-runtime').utils +const { Args } = require('@oclif/core') class TriggerGet extends RuntimeBaseCommand { async run () { @@ -34,13 +35,12 @@ TriggerGet.flags = { ...RuntimeBaseCommand.flags } -TriggerGet.args = [ - { - name: 'triggerPath', +TriggerGet.args = { + triggerPath: Args.string({ required: true, description: 'The name/path of the trigger, in the format /NAMESPACE/NAME' - } -] + }) +} TriggerGet.description = 'Get a trigger for Adobe I/O Runtime' diff --git a/src/commands/runtime/trigger/list.js b/src/commands/runtime/trigger/list.js index 1271750a..eed8e258 100644 --- a/src/commands/runtime/trigger/list.js +++ b/src/commands/runtime/trigger/list.js @@ -12,7 +12,7 @@ governing permissions and limitations under the License. const moment = require('dayjs') const RuntimeBaseCommand = require('../../../RuntimeBaseCommand') -const { Flags, CliUx: cli } = require('@oclif/core') +const { Flags, ux } = require('@oclif/core') class TriggerList extends RuntimeBaseCommand { async run () { @@ -84,7 +84,7 @@ class TriggerList extends RuntimeBaseCommand { get: row => row.name } } - cli.ux.table(resultsWithStatus, columns) + ux.table(resultsWithStatus, columns) } }) } catch (err) { diff --git a/src/commands/runtime/trigger/update.js b/src/commands/runtime/trigger/update.js index 959c5c9b..04af5604 100644 --- a/src/commands/runtime/trigger/update.js +++ b/src/commands/runtime/trigger/update.js @@ -12,18 +12,18 @@ governing permissions and limitations under the License. const TriggerCreate = require('./create') const cloneDeep = require('lodash.clonedeep') +const { Args } = require('@oclif/core') class TriggerUpdate extends TriggerCreate { isUpdate () { return true } } -TriggerUpdate.args = [ - { - name: 'triggerName', +TriggerUpdate.args = { + triggerName: Args.string({ required: true, description: 'The name of the trigger' - } -] + }) +} TriggerUpdate.flags = cloneDeep(TriggerCreate.flags) // TODO: Updating a feed is not supported as per wsk cli. Need to check if we can still support it. diff --git a/test/RuntimeBaseCommand.test.js b/test/RuntimeBaseCommand.test.js index ff2aa8a6..3430a9a7 100644 --- a/test/RuntimeBaseCommand.test.js +++ b/test/RuntimeBaseCommand.test.js @@ -21,8 +21,6 @@ beforeEach(() => { clearMockedFs() }) -const WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') - test('exports', async () => { expect(typeof TheCommand).toEqual('function') expect(TheCommand.prototype).toBeInstanceOf(Command) @@ -238,24 +236,19 @@ describe('instance methods', () => { }) }) - // eslint-disable-next-line jest/expect-expect - test('no config file, no problem', () => { + test('no config file, no problem', async () => { process.env[PropertyEnv.AUTH] = '1234' - return command.wsk().then(() => { - delete process.env[PropertyEnv.AUTH] - }) + await expect(command.wsk()).resolves.not.toThrow() + delete process.env[PropertyEnv.AUTH] }) - // eslint-disable-next-line jest/expect-expect - test('should not throw if config file specified but doesnt exist', () => { + test('should not throw if config file specified but doesnt exist', async () => { process.env[PropertyEnv.CONFIG_FILE] = '/foo' process.env[PropertyEnv.AUTH] = '1234' - return command.wsk().then(() => { - delete process.env[PropertyEnv.CONFIG_FILE] - delete process.env[PropertyEnv.AUTH] - }) + await expect(command.wsk()).resolves.not.toThrow() + delete process.env[PropertyEnv.CONFIG_FILE] }) }) diff --git a/test/__fixtures__/deploy/main.js b/test/__fixtures__/deploy/main.js index abe763d6..01042dc3 100644 --- a/test/__fixtures__/deploy/main.js +++ b/test/__fixtures__/deploy/main.js @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ - /** @private */ function split (params) { const text = params.text || '' @@ -13,3 +11,8 @@ function split1 (params) { const words = text.split(' ') return { words } } + +module.exports = { + split, + split1 +} diff --git a/test/commands/runtime/action/create.test.js b/test/commands/runtime/action/create.test.js index 1d62e423..d19538d6 100644 --- a/test/commands/runtime/action/create.test.js +++ b/test/commands/runtime/action/create.test.js @@ -67,7 +67,6 @@ test('aliases', async () => { // /////////////////////////////////////////// const JS_FILE = fixtureFile('action/actionFile.js') -const WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') const FILE_SYSTEM_JSON = { [WSK_PROPS_PATH]: 'AUTH=something', '/action/actionFile.js': fixtureFile('action/actionFile.js'), diff --git a/test/commands/runtime/action/delete.test.js b/test/commands/runtime/action/delete.test.js index 5b46bb80..01900bc4 100644 --- a/test/commands/runtime/action/delete.test.js +++ b/test/commands/runtime/action/delete.test.js @@ -32,10 +32,8 @@ test('aliases', async () => { }) test('args', async () => { - const deleteName = TheCommand.args[0] - expect(deleteName.name).toBeDefined() - expect(deleteName.name).toEqual('actionName') - expect(deleteName.required).toEqual(true) + expect(TheCommand.args.actionName).toBeDefined() + expect(TheCommand.args.actionName.required).toEqual(true) }) describe('instance methods', () => { diff --git a/test/commands/runtime/action/get.test.js b/test/commands/runtime/action/get.test.js index 84ce7c48..67fc1f9e 100644 --- a/test/commands/runtime/action/get.test.js +++ b/test/commands/runtime/action/get.test.js @@ -33,10 +33,8 @@ test('aliases', async () => { }) test('args', async () => { - const getName = TheCommand.args[0] - expect(getName.name).toBeDefined() - expect(getName.name).toEqual('actionName') - expect(getName.required).toEqual(true) + expect(TheCommand.args.actionName).toBeDefined() + expect(TheCommand.args.actionName.required).toEqual(true) }) describe('instance methods', () => { @@ -210,7 +208,6 @@ describe('instance methods', () => { const bufferData = Buffer.from('this is the code', 'base64') test('retrieve an action --save', () => { - fs.writeFileSync = jest.fn() const cmd = rtLib.mockResolvedFixture(rtAction, 'action/get.json') command.argv = ['hello', '--save'] return command.run() @@ -221,7 +218,6 @@ describe('instance methods', () => { }) test('retrieve an action in a package --save', () => { - fs.writeFileSync = jest.fn() const cmd = rtLib.mockResolvedFixture(rtAction, 'action/getpackage.json') command.argv = ['pkg/hello', '--save'] return command.run() @@ -233,7 +229,6 @@ describe('instance methods', () => { test('retrieve an action --save-as', () => { const cmd = rtLib.mockResolvedFixture(rtAction, 'action/get.json') - fs.writeFileSync = jest.fn() command.argv = ['hello', '--save-as', 'filename.js'] return command.run() .then(() => { @@ -244,7 +239,6 @@ describe('instance methods', () => { test('retrieve an action --save (binary)', () => { const cmd = rtLib.mockResolvedFixture(rtAction, 'action/get.binary.json') - fs.writeFileSync = jest.fn() command.argv = ['hello', '--save'] return command.run() .then(() => { @@ -256,7 +250,6 @@ describe('instance methods', () => { test('retrieve an action --save-as (binary)', () => { const cmd = rtLib.mockResolvedFixture(rtAction, 'action/get.binary.json') - fs.writeFileSync = jest.fn() command.argv = ['hello', '--save-as', 'filename.zip'] return command.run() .then(() => { diff --git a/test/commands/runtime/action/index.test.js b/test/commands/runtime/action/index.test.js index 056f77e7..9d0e2d2a 100644 --- a/test/commands/runtime/action/index.test.js +++ b/test/commands/runtime/action/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/action/invoke.test.js b/test/commands/runtime/action/invoke.test.js index 6ba5abe0..0c47cbed 100644 --- a/test/commands/runtime/action/invoke.test.js +++ b/test/commands/runtime/action/invoke.test.js @@ -47,10 +47,8 @@ test('flags', async () => { }) test('args', async () => { - const invokeName = TheCommand.args[0] - expect(invokeName.name).toBeDefined() - expect(invokeName.name).toEqual('actionName') - expect(invokeName.required).toEqual(true) + expect(TheCommand.args.actionName).toBeDefined() + expect(TheCommand.args.actionName.required).toEqual(true) }) describe('instance methods', () => { @@ -66,7 +64,7 @@ describe('instance methods', () => { afterAll(() => { // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/action/update.test.js b/test/commands/runtime/action/update.test.js index f06c50a8..c4961893 100644 --- a/test/commands/runtime/action/update.test.js +++ b/test/commands/runtime/action/update.test.js @@ -62,13 +62,9 @@ test('flags', async () => { }) test('args', async () => { - const actionName = TheCommand.args[0] - expect(actionName.name).toBeDefined() - expect(actionName.name).toEqual('actionName') - expect(actionName.required).toEqual(true) - const actionPath = TheCommand.args[1] - expect(actionPath.name).toBeDefined() - expect(actionPath.name).toEqual('actionPath') + expect(TheCommand.args.actionName).toBeDefined() + expect(TheCommand.args.actionName.required).toEqual(true) + expect(TheCommand.args.actionPath).toBeDefined() }) describe('instance methods', () => { @@ -81,17 +77,18 @@ describe('instance methods', () => { RuntimeLib.mockReset() }) + const FILE_SYSTEM_JSON = { + [WSK_PROPS_PATH]: 'AUTH=something', + '/action/actionFile.js': fixtureFile('action/actionFile.js'), + '/action/zipAction.zip': 'fakezipfile' + } + beforeAll(() => { - const json = { - 'action/actionFile.js': fixtureFile('action/actionFile.js'), - 'action/zipAction.zip': 'fakezipfile' - } - fakeFileSystem.addJson(json) + createFileSystem(FILE_SYSTEM_JSON) }) afterAll(() => { - // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/activation/get.test.js b/test/commands/runtime/activation/get.test.js index e2898bde..1d77e0ff 100644 --- a/test/commands/runtime/activation/get.test.js +++ b/test/commands/runtime/activation/get.test.js @@ -33,9 +33,7 @@ test('aliases', async () => { }) test('args', async () => { - const getName = TheCommand.args[0] - expect(getName.name).toBeDefined() - expect(getName.name).toEqual('activationID') + expect(TheCommand.args.activationId).toBeDefined() }) test('flags', async () => { diff --git a/test/commands/runtime/activation/index.test.js b/test/commands/runtime/activation/index.test.js index 6926cb9b..39745359 100644 --- a/test/commands/runtime/activation/index.test.js +++ b/test/commands/runtime/activation/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/activation/list.test.js b/test/commands/runtime/activation/list.test.js index f6c84425..0a703f24 100644 --- a/test/commands/runtime/activation/list.test.js +++ b/test/commands/runtime/activation/list.test.js @@ -41,9 +41,7 @@ test('flags', async () => { }) test('args', async () => { - const logName = TheCommand.args[0] - expect(logName.name).toBeDefined() - expect(logName.name).toEqual('action_name') + expect(TheCommand.args.action_name).toBeDefined() }) describe('instance methods', () => { diff --git a/test/commands/runtime/activation/logs.test.js b/test/commands/runtime/activation/logs.test.js index dcc82329..d1ca6d56 100644 --- a/test/commands/runtime/activation/logs.test.js +++ b/test/commands/runtime/activation/logs.test.js @@ -32,9 +32,7 @@ test('aliases', async () => { }) test('args', async () => { - const logName = TheCommand.args[0] - expect(logName.name).toBeDefined() - expect(logName.name).toEqual('activationId') + expect(TheCommand.args.activationId).toBeDefined() }) test('flags', async () => { diff --git a/test/commands/runtime/activation/result.test.js b/test/commands/runtime/activation/result.test.js index 57d87099..872c163b 100644 --- a/test/commands/runtime/activation/result.test.js +++ b/test/commands/runtime/activation/result.test.js @@ -32,9 +32,7 @@ test('aliases', async () => { }) test('args', async () => { - const logName = TheCommand.args[0] - expect(logName.name).toBeDefined() - expect(logName.name).toEqual('activationID') + expect(TheCommand.args.activationId).toBeDefined() }) test('flags', async () => { diff --git a/test/commands/runtime/api/create.test.js b/test/commands/runtime/api/create.test.js index 2948ff28..c7231dbd 100644 --- a/test/commands/runtime/api/create.test.js +++ b/test/commands/runtime/api/create.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/api/create.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'routes.create' @@ -32,29 +34,24 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(4) - - expect(args[0].name).toEqual('basePath') - expect(args[0].required).not.toBeTruthy() - expect(args[0].description).toBeDefined() - - expect(args[1].name).toEqual('relPath') - expect(args[1].required).not.toBeTruthy() - expect(args[1].description).toBeDefined() - - expect(args[2].name).toEqual('apiVerb') - expect(args[2].required).not.toBeTruthy() - expect(args[2].options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) - expect(args[2].description).toBeDefined() - - expect(args[3].name).toEqual('action') - expect(args[3].required).not.toBeTruthy() - expect(args[3].description).toBeDefined() + expect(TheCommand.args.basePath).toBeDefined() + expect(TheCommand.args.basePath.required).not.toBeTruthy() + expect(TheCommand.args.basePath.description).toBeDefined() + + expect(TheCommand.args.basePath).toBeDefined() + expect(TheCommand.args.basePath.required).not.toBeTruthy() + expect(TheCommand.args.basePath.description).toBeDefined() + + expect(TheCommand.args.apiVerb).toBeDefined() + expect(TheCommand.args.apiVerb.required).not.toBeTruthy() + expect(TheCommand.args.apiVerb.options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) + expect(TheCommand.args.apiVerb.description).toBeDefined() + + expect(TheCommand.args.action).toBeDefined() + expect(TheCommand.args.action.required).not.toBeTruthy() + expect(TheCommand.args.action.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) @@ -83,15 +80,18 @@ describe('instance methods', () => { rtLib.mockResolved('actions.client.options', '') RuntimeLib.mockReset() }) + + const FILE_SYSTEM_JSON = { + [WSK_PROPS_PATH]: 'AUTH=something', + '/api/api_swagger.json': fixtureFile('api/api_swagger.json') + } + beforeAll(() => { - const json = { - 'api/api_swagger.json': fixtureFile('api/api_swagger.json') - } - fakeFileSystem.addJson(json) + createFileSystem(FILE_SYSTEM_JSON) }) + afterAll(() => { - // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/api/delete.test.js b/test/commands/runtime/api/delete.test.js index da484ade..33f7b3c1 100644 --- a/test/commands/runtime/api/delete.test.js +++ b/test/commands/runtime/api/delete.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/api/delete.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { stdout } = require('stdout-stderr') @@ -32,25 +34,20 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(3) - - expect(args[0].name).toEqual('basePathOrApiName') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.basePathOrApiName).toBeDefined() + expect(TheCommand.args.basePathOrApiName.required).toBeTruthy() + expect(TheCommand.args.basePathOrApiName.description).toBeDefined() - expect(args[1].name).toEqual('relPath') - expect(args[1].required).toBeFalsy() - expect(args[1].description).toBeDefined() + expect(TheCommand.args.relPath).toBeDefined() + expect(TheCommand.args.relPath.required).toBeFalsy() + expect(TheCommand.args.relPath.description).toBeDefined() - expect(args[2].name).toEqual('apiVerb') - expect(args[2].required).toBeFalsy() - expect(args[2].options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) - expect(args[2].description).toBeDefined() + expect(TheCommand.args.apiVerb).toBeDefined() + expect(TheCommand.args.apiVerb.required).toBeFalsy() + expect(TheCommand.args.apiVerb.options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) + expect(TheCommand.args.apiVerb.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/api/get.test.js b/test/commands/runtime/api/get.test.js index 2009a773..40d58457 100644 --- a/test/commands/runtime/api/get.test.js +++ b/test/commands/runtime/api/get.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/api/get.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { stdout } = require('stdout-stderr') @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('basePathOrApiName') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.basePathOrApiName).toBeDefined() + expect(TheCommand.args.basePathOrApiName.required).toBeTruthy() + expect(TheCommand.args.basePathOrApiName.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/api/index.test.js b/test/commands/runtime/api/index.test.js index 0226b8ec..882ff74b 100644 --- a/test/commands/runtime/api/index.test.js +++ b/test/commands/runtime/api/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/api/list.test.js b/test/commands/runtime/api/list.test.js index d4210a94..92b79ec0 100644 --- a/test/commands/runtime/api/list.test.js +++ b/test/commands/runtime/api/list.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/api/list.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'routes.list' @@ -32,25 +34,20 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(3) - - expect(args[0].name).toEqual('basePath') - expect(args[0].required).toBeFalsy() - expect(args[0].description).toBeDefined() - - expect(args[1].name).toEqual('relPath') - expect(args[1].required).toBeFalsy() - expect(args[1].description).toBeDefined() - - expect(args[2].name).toEqual('apiVerb') - expect(args[2].required).toBeFalsy() - expect(args[2].options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) - expect(args[2].description).toBeDefined() + expect(TheCommand.args.basePath).toBeDefined() + expect(TheCommand.args.basePath.required).toBeFalsy() + expect(TheCommand.args.basePath.description).toBeDefined() + + expect(TheCommand.args.relPath).toBeDefined() + expect(TheCommand.args.relPath.required).toBeFalsy() + expect(TheCommand.args.relPath.description).toBeDefined() + + expect(TheCommand.args.apiVerb).toBeDefined() + expect(TheCommand.args.apiVerb.required).toBeFalsy() + expect(TheCommand.args.apiVerb.options).toMatchObject(['get', 'post', 'put', 'patch', 'delete', 'head', 'options']) + expect(TheCommand.args.apiVerb.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/deploy/export.test.js b/test/commands/runtime/deploy/export.test.js index f69740a5..ede82dc8 100644 --- a/test/commands/runtime/deploy/export.test.js +++ b/test/commands/runtime/deploy/export.test.js @@ -17,6 +17,9 @@ const { stdout } = require('stdout-stderr') const rtPackageList = 'packages.list' const owRulesList = 'rules.list' const owTriggerList = 'triggers.list' +const rtPackagesGet = 'packages.get' +const rtActionsGet = 'actions.get' +const rtTriggersGet = 'triggers.get' const fs = require('fs') test('exports', async () => { @@ -418,29 +421,30 @@ describe('instance methods', () => { version: '0.0.2' }] + const FILE_SYSTEM_JSON = { + [WSK_PROPS_PATH]: 'AUTH=something', + '/deploy/deployment_syncSequences.yaml': fixtureFile('deploy/deployment_syncSequences.yaml'), + '/deploy/manifest.yaml': fixtureFile('deploy/manifest.yaml'), + '/deploy/deployment_actionMissingInputs.yaml': fixtureFile('deploy/deployment_actionMissingInputs.yaml'), + '/deploy/deployment_syncMissingAction.yaml': fixtureFile('deploy/deployment_syncMissingAction.yaml'), + '/deploy/manifest.yml': fixtureFile('deploy/manifest.yml'), + '/deploy/hello.js': fixtureFile('deploy/hello.js'), + '/deploy/hello_plus.js': fixtureFile('deploy/hello_plus.js'), + '/deploy/deployment.yaml': fixtureFile('deploy/deployment.yaml'), + '/deploy/deployment.yml': fixtureFile('deploy/deployment.yml') + } + let rtLib beforeEach(() => { RuntimeLib.mockReset() rtLib = RuntimeLib.init({ fake: 'credentials' }) command = new TheCommand([]) handleError = jest.spyOn(command, 'handleError') - const json = { - 'deploy/deployment_syncSequences.yaml': fixtureFile('deploy/deployment_syncSequences.yaml'), - 'deploy/manifest.yaml': fixtureFile('deploy/manifest.yaml'), - 'deploy/deployment_actionMissingInputs.yaml': fixtureFile('deploy/deployment_actionMissingInputs.yaml'), - 'deploy/deployment_syncMissingAction.yaml': fixtureFile('deploy/deployment_syncMissingAction.yaml'), - 'deploy/manifest.yml': fixtureFile('deploy/manifest.yml'), - 'deploy/hello.js': fixtureFile('deploy/hello.js'), - 'deploy/hello_plus.js': fixtureFile('deploy/hello_plus.js'), - 'deploy/deployment.yaml': fixtureFile('deploy/deployment.yaml'), - 'deploy/deployment.yml': fixtureFile('deploy/deployment.yml') - } - fakeFileSystem.addJson(json) + createFileSystem(FILE_SYSTEM_JSON) }) afterEach(() => { - // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { @@ -459,10 +463,10 @@ describe('instance methods', () => { }) test('fetch list of actions to be exported from project name', () => { - const cmd = rtLib.mockResolved('packages.get', packageget) + const cmd = rtLib.mockResolved(rtPackagesGet, packageget) command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] rtLib.mockResolved(rtPackageList, packagelist) - rtLib.mockResolved('actions.get', actionGet) + rtLib.mockResolved(rtActionsGet, actionGet) return command.run() .then(() => { expect(cmd).toHaveBeenCalled() @@ -471,11 +475,10 @@ describe('instance methods', () => { }) test('fetch list of packages (shared) to be exported from project name', () => { - const cmd = rtLib.mockResolved('packages.get', emptyPackage) + const cmd = rtLib.mockResolved(rtPackagesGet, emptyPackage) command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] rtLib.mockResolved(rtPackageList, sharedPackagelist) - rtLib.mockResolved('actions.get', '') - fs.writeFileSync = jest.fn() + rtLib.mockResolved(rtActionsGet, '') return command.run() .then(() => { expect(cmd).toHaveBeenCalled() @@ -488,8 +491,8 @@ describe('instance methods', () => { const cmd = rtLib.mockResolved(owTriggerList, '') command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] rtLib.mockResolved(rtPackageList, packagelist) - rtLib.mockResolved('packages.get', packageget) - rtLib.mockResolved('actions.get', actionGet) + rtLib.mockResolved(rtPackagesGet, packageget) + rtLib.mockResolved(rtActionsGet, actionGet) return command.run() .then(() => { expect(cmd).toHaveBeenCalled() @@ -501,8 +504,8 @@ describe('instance methods', () => { const cmd = rtLib.mockResolved(owRulesList, '') command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] rtLib.mockResolved(rtPackageList, packagelist) - rtLib.mockResolved('packages.get', packageget) - rtLib.mockResolved('actions.get', actionGet) + rtLib.mockResolved(rtPackagesGet, packageget) + rtLib.mockResolved(rtActionsGet, actionGet) rtLib.mockResolved(owTriggerList, '') return command.run() .then(() => { @@ -513,9 +516,8 @@ describe('instance methods', () => { test('write to manifest file when trigger has a feed', () => { rtLib.mockResolved(owTriggerList, triggerWithFeed) - rtLib.mockResolved('triggers.get', triggerGetWithFeed) + rtLib.mockResolved(rtTriggersGet, triggerGetWithFeed) rtLib.mockResolved(owRulesList, ruleslist) - fs.writeFileSync = jest.fn() command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] const yaml = fixtureFile('deploy/export_yaml_feed.yaml') return command.run() @@ -528,9 +530,8 @@ describe('instance methods', () => { test('write action to js file', () => { rtLib.mockResolved(owTriggerList, triggerlist) - rtLib.mockResolved('triggers.get', triggerGet) + rtLib.mockResolved(rtTriggersGet, triggerGet) rtLib.mockResolved(owRulesList, ruleslist) - fs.writeFileSync = jest.fn() command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] const yaml = fixtureFile('deploy/export_yaml.yaml') return command.run() @@ -542,11 +543,10 @@ describe('instance methods', () => { }) test('write sequence to js file', async () => { - rtLib.mockResolved('actions.get', sequenceGet) + rtLib.mockResolved(rtActionsGet, sequenceGet) rtLib.mockResolved(owTriggerList, triggerlist) - rtLib.mockResolved('triggers.get', triggerGet) + rtLib.mockResolved(rtTriggersGet, triggerGet) rtLib.mockResolved(owRulesList, ruleslist) - fs.writeFileSync = jest.fn() command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] const yaml = fixtureFile('deploy/export_yaml_Sequence.yaml') await command.run() @@ -555,11 +555,10 @@ describe('instance methods', () => { test('write binary of action to js file', () => { const bufferData = Buffer.from('code', 'base64') - rtLib.mockResolved('actions.get', actionBinaryGet) + rtLib.mockResolved(rtActionsGet, actionBinaryGet) rtLib.mockResolved(owTriggerList, triggerlist) - rtLib.mockResolved('triggers.get', triggerGet) + rtLib.mockResolved(rtTriggersGet, triggerGet) rtLib.mockResolved(owRulesList, ruleslist) - fs.writeFileSync = jest.fn() command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] return command.run() .then(() => { @@ -571,7 +570,6 @@ describe('instance methods', () => { rtLib.mockResolved(rtPackageList, packageNoAnnotations) rtLib.mockResolved(owTriggerList, '') rtLib.mockResolved(owRulesList, '') - fs.writeFileSync = jest.fn() command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] const yaml = fixtureFile('deploy/export_yaml_noAnnotations.yaml') return command.run() @@ -582,7 +580,6 @@ describe('instance methods', () => { test('write project name to manifest file if package has no whisk managed project name and there are no triggers and rules', () => { rtLib.mockResolved(rtPackageList, packagelistNoProjectName) - fs.writeFileSync = jest.fn() rtLib.mockResolved(owTriggerList, '') rtLib.mockResolved(owRulesList, '') command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] @@ -597,7 +594,7 @@ describe('instance methods', () => { rtLib.mockResolved(rtPackageList, '') rtLib.mockResolved(owTriggerList, triggerNoProjectName) rtLib.mockResolved(owRulesList, '') - const cmd = rtLib.mockResolved('triggers.get', '') + const cmd = rtLib.mockResolved(rtTriggersGet, '') command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] return command.run() .then(() => { @@ -609,7 +606,7 @@ describe('instance methods', () => { rtLib.mockResolved(rtPackageList, '') rtLib.mockResolved(owTriggerList, triggerNoAnnotation) rtLib.mockResolved(owRulesList, '') - const cmd = rtLib.mockResolved('triggers.get', '') + const cmd = rtLib.mockResolved(rtTriggersGet, '') command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] return command.run() .then(() => { @@ -619,7 +616,6 @@ describe('instance methods', () => { test('write project name to manifest file if rule has no whisk managed project name', () => { rtLib.mockResolved(rtPackageList, '') - fs.writeFileSync = jest.fn() rtLib.mockResolved(owTriggerList, '') rtLib.mockResolved(owRulesList, rulesNoAnnotations) command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] @@ -637,5 +633,22 @@ describe('instance methods', () => { await expect(command.run()).rejects.toThrow(error[0]) expect(handleError).toHaveBeenLastCalledWith(...error) }) + + test('do not create the package folder if it already exists (coverage)', () => { + const newJson = { + ...FILE_SYSTEM_JSON, + '/deploy/testSeq': true + } + createFileSystem(newJson) + + rtLib.mockResolved(rtPackageList, packagelist) + command.argv = ['--projectname', 'proj', '-m', '/deploy/manifest.yaml'] + const yaml = fixtureFile('deploy/export_yaml_noAnnotations.yaml') + return command.run() + .then(() => { + expect(fs.writeFileSync).toHaveBeenCalledWith('/deploy/manifest.yaml', yaml) + expect(fs.mkdirSync).not.toHaveBeenCalled() + }) + }) }) }) diff --git a/test/commands/runtime/index.test.js b/test/commands/runtime/index.test.js index 31f6b56e..50db4adc 100644 --- a/test/commands/runtime/index.test.js +++ b/test/commands/runtime/index.test.js @@ -34,7 +34,7 @@ test('flags', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/namespace/get.test.js b/test/commands/runtime/namespace/get.test.js index bb5692cb..9ee92d7b 100644 --- a/test/commands/runtime/namespace/get.test.js +++ b/test/commands/runtime/namespace/get.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/namespace/get.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { stdout } = require('stdout-stderr') @@ -33,10 +35,9 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/namespace/index.test.js b/test/commands/runtime/namespace/index.test.js index de454562..1d2d4d06 100644 --- a/test/commands/runtime/namespace/index.test.js +++ b/test/commands/runtime/namespace/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/namespace/list.test.js b/test/commands/runtime/namespace/list.test.js index f313954b..d47cfb5a 100644 --- a/test/commands/runtime/namespace/list.test.js +++ b/test/commands/runtime/namespace/list.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/namespace/list.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { stdout } = require('stdout-stderr') @@ -32,10 +34,9 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/package/bind.test.js b/test/commands/runtime/package/bind.test.js index d6c5e1d1..2e69e54c 100644 --- a/test/commands/runtime/package/bind.test.js +++ b/test/commands/runtime/package/bind.test.js @@ -46,14 +46,11 @@ test('flags', async () => { }) test('args', async () => { - const packageName = TheCommand.args[0] - expect(packageName.name).toBeDefined() - expect(packageName.name).toEqual('packageName') - expect(packageName.required).toEqual(true) - const bindPackageName = TheCommand.args[1] - expect(bindPackageName.name).toBeDefined() - expect(bindPackageName.name).toEqual('bindPackageName') - expect(bindPackageName.required).toEqual(true) + expect(TheCommand.args.packageName).toBeDefined() + expect(TheCommand.args.packageName.required).toEqual(true) + + expect(TheCommand.args.bindPackageName).toBeDefined() + expect(TheCommand.args.bindPackageName.required).toEqual(true) }) describe('instance methods', () => { @@ -68,7 +65,7 @@ describe('instance methods', () => { afterAll(() => { // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/package/create.test.js b/test/commands/runtime/package/create.test.js index f854933a..7db10436 100644 --- a/test/commands/runtime/package/create.test.js +++ b/test/commands/runtime/package/create.test.js @@ -47,10 +47,8 @@ test('flags', async () => { }) test('args', async () => { - const packageName = TheCommand.args[0] - expect(packageName.name).toBeDefined() - expect(packageName.name).toEqual('packageName') - expect(packageName.required).toEqual(true) + expect(TheCommand.args.packageName).toBeDefined() + expect(TheCommand.args.packageName.required).toEqual(true) }) describe('instance methods', () => { @@ -65,7 +63,7 @@ describe('instance methods', () => { afterAll(() => { // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/package/delete.test.js b/test/commands/runtime/package/delete.test.js index 632e6277..4c3ca940 100644 --- a/test/commands/runtime/package/delete.test.js +++ b/test/commands/runtime/package/delete.test.js @@ -33,10 +33,8 @@ test('aliases', async () => { }) test('args', async () => { - const deleteName = TheCommand.args[0] - expect(deleteName.name).toBeDefined() - expect(deleteName.name).toEqual('packageName') - expect(deleteName.required).toEqual(true) + expect(TheCommand.args.packageName).toBeDefined() + expect(TheCommand.args.packageName.required).toEqual(true) }) describe('instance methods', () => { diff --git a/test/commands/runtime/package/get.test.js b/test/commands/runtime/package/get.test.js index 6442b444..293c8c85 100644 --- a/test/commands/runtime/package/get.test.js +++ b/test/commands/runtime/package/get.test.js @@ -33,10 +33,8 @@ test('aliases', async () => { }) test('args', async () => { - const getName = TheCommand.args[0] - expect(getName.name).toBeDefined() - expect(getName.name).toEqual('packageName') - expect(getName.required).toEqual(true) + expect(TheCommand.args.packageName).toBeDefined() + expect(TheCommand.args.packageName.required).toEqual(true) }) describe('instance methods', () => { diff --git a/test/commands/runtime/package/index.test.js b/test/commands/runtime/package/index.test.js index c9f968f3..61c92a87 100644 --- a/test/commands/runtime/package/index.test.js +++ b/test/commands/runtime/package/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/package/list.test.js b/test/commands/runtime/package/list.test.js index 3a78c1e0..15dd225c 100644 --- a/test/commands/runtime/package/list.test.js +++ b/test/commands/runtime/package/list.test.js @@ -39,9 +39,7 @@ test('flags', async () => { }) test('args', async () => { - const listName = TheCommand.args[0] - expect(listName.name).toBeDefined() - expect(listName.name).toEqual('namespace') + expect(TheCommand.args.namespace).toBeDefined() }) describe('instance methods', () => { diff --git a/test/commands/runtime/package/update.test.js b/test/commands/runtime/package/update.test.js index a60a5485..ce826ed4 100644 --- a/test/commands/runtime/package/update.test.js +++ b/test/commands/runtime/package/update.test.js @@ -47,10 +47,8 @@ test('flags', async () => { }) test('args', async () => { - const packageName = TheCommand.args[0] - expect(packageName.name).toBeDefined() - expect(packageName.name).toEqual('packageName') - expect(packageName.required).toEqual(true) + expect(TheCommand.args.packageName).toBeDefined() + expect(TheCommand.args.packageName.required).toEqual(true) }) describe('instance methods', () => { @@ -65,7 +63,7 @@ describe('instance methods', () => { afterAll(() => { // reset back to normal - fakeFileSystem.reset() + clearMockedFs() }) describe('run', () => { diff --git a/test/commands/runtime/property/get.test.js b/test/commands/runtime/property/get.test.js index b32bdbfe..b5f4ea5c 100644 --- a/test/commands/runtime/property/get.test.js +++ b/test/commands/runtime/property/get.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/property/get.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { stdout } = require('stdout-stderr') @@ -36,15 +38,14 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect -test('base flags included in command flags', +test('base flags included in command flags', () => { createTestFlagsFunction(TheCommand, { ...RuntimeBaseCommand.flags }) -) +}) test('flags', async () => { const flags = TheCommand.flags @@ -82,12 +83,20 @@ describe('instance methods', () => { command = new TheCommand([]) }) + afterEach(() => { + clearMockedFs() + }) + describe('run', () => { test('exists', async () => { expect(command.run).toBeInstanceOf(Function) }) test('no flags', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // cli version command.config = fixtureJson('property/config.json') return command.run() @@ -97,6 +106,10 @@ describe('instance methods', () => { }) test('no flags, api server unreachable', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // apibuild and apibuildno mockFetch.mockRejectedValue(new Error('no connection')) @@ -109,6 +122,10 @@ describe('instance methods', () => { }) test('--all', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // cli version command.config = fixtureJson('property/config.json') // set flag @@ -120,6 +137,10 @@ describe('instance methods', () => { }) test('--namespace', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // cli version command.config = fixtureJson('property/config.json') // set flag @@ -131,6 +152,10 @@ describe('instance methods', () => { }) test('--auth', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // cli version command.config = fixtureJson('property/config.json') // set flag @@ -142,6 +167,10 @@ describe('instance methods', () => { }) test('--apihost', () => { + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('wsk.properties') + }) + // cli version command.config = fixtureJson('property/config.json') // set flag @@ -198,7 +227,9 @@ describe('instance methods', () => { }) test('keys not found in .wskconfig, use defaults', () => { - fakeFileSystem.reset({ emptyWskProps: true }) + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('empty-wsk.properties') + }) // cli version command.config = fixtureJson('property/config.json') @@ -207,12 +238,14 @@ describe('instance methods', () => { return command.run() .then(() => { expect(stdout.output).toMatchFixture('property/all-empty-wskprops.txt') - fakeFileSystem.reset() }) }) test('ENV overrides', () => { - fakeFileSystem.reset({ emptyWskProps: true }) + createFileSystem({ + [WSK_PROPS_PATH]: fixtureFile('empty-wsk.properties') + }) + process.env[PropertyEnv.APIHOST] = 'https://google.com' process.env[PropertyEnv.AUTH] = 'foobar' process.env[PropertyEnv.APIVERSION] = 'v12.4' diff --git a/test/commands/runtime/property/index.test.js b/test/commands/runtime/property/index.test.js index adf90f10..4ecd1fe9 100644 --- a/test/commands/runtime/property/index.test.js +++ b/test/commands/runtime/property/index.test.js @@ -34,7 +34,7 @@ test('flags', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/property/set.test.js b/test/commands/runtime/property/set.test.js index dd16af02..60ec94bf 100644 --- a/test/commands/runtime/property/set.test.js +++ b/test/commands/runtime/property/set.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/property/set.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const { PropertyEnv, propertiesFile } = require('../../../../src/properties') @@ -30,15 +32,14 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect -test('base flags included in command flags', +test('base flags included in command flags', () => { createTestFlagsFunction(TheCommand, { ...RuntimeBaseCommand.flags }) -) +}) test('flags', async () => { const flags = TheCommand.flags @@ -68,76 +69,34 @@ describe('instance methods', () => { }) }) - // eslint-disable-next-line jest/expect-expect test('--auth', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--auth', 'some-auth-key'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--auth', 'some-auth-key'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--apihost', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--apihost', 'http://myserver'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--apihost', 'http://myserver'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--apiversion', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--apiversion', 'v2'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--apiversion', 'v2'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--cert', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--cert', 'mycert=12512tsagZFSG'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--cert', 'mycert=12512tsagZFSG'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--key', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--key', '7129asgas97195t9asgha'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--key', '7129asgas97195t9asgha'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--namespace', () => { - return new Promise((resolve) => { - // set flag - command.argv = ['--namespace', 'my-namespace'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--namespace', 'my-namespace'] + return expect(command.run()).resolves.not.toThrow() }) test('namespace flag with env', async () => { @@ -153,6 +112,6 @@ describe('instance methods', () => { test('unknown flag', async () => { command.argv = ['--unknown-flag', 'some-value'] await expect(command.run()).rejects.toThrow() - expect(handleError).toHaveBeenLastCalledWith('failed to set the property', new Error('Unexpected arguments: --unknown-flag, some-value\nSee more help with --help')) + expect(handleError).toHaveBeenLastCalledWith('failed to set the property', new Error('Nonexistent flag: --unknown-flag\nSee more help with --help')) }) }) diff --git a/test/commands/runtime/property/unset.test.js b/test/commands/runtime/property/unset.test.js index a809c677..5b949d5d 100644 --- a/test/commands/runtime/property/unset.test.js +++ b/test/commands/runtime/property/unset.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/property/unset.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') @@ -29,15 +31,14 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect -test('base flags included in command flags', +test('base flags included in command flags', () => { createTestFlagsFunction(TheCommand, { ...RuntimeBaseCommand.flags }) -) +}) test('flags', async () => { const flags = TheCommand.flags @@ -66,82 +67,40 @@ describe('instance methods', () => { expect(command.run).toBeInstanceOf(Function) }) - // eslint-disable-next-line jest/expect-expect test('--auth', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--auth'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--auth'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--apihost', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--apihost'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--apihost'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--apiversion', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--apiversion'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--apiversion'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--cert', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--cert'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--cert'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--key', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--key'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--key'] + return expect(command.run()).resolves.not.toThrow() }) - // eslint-disable-next-line jest/expect-expect test('--namespace', () => { - return new Promise((resolve) => { - // unset flag - command.argv = ['--namespace'] - return command.run() - .then(() => { - resolve() - }) - }) + command.argv = ['--namespace'] + return expect(command.run()).resolves.not.toThrow() }) test('unknown flag', async () => { command.argv = ['--unknown-flag'] await expect(command.run()).rejects.toThrow() - expect(handleError).toHaveBeenLastCalledWith('failed to unset the property', new Error('Unexpected argument: --unknown-flag\nSee more help with --help')) + expect(handleError).toHaveBeenLastCalledWith('failed to unset the property', new Error('Nonexistent flag: --unknown-flag\nSee more help with --help')) }) }) }) diff --git a/test/commands/runtime/rule/create.test.js b/test/commands/runtime/rule/create.test.js index 46ff20bc..24cd46a6 100644 --- a/test/commands/runtime/rule/create.test.js +++ b/test/commands/runtime/rule/create.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/create.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.create' @@ -32,24 +34,19 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(3) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() - expect(args[1].name).toEqual('trigger') - expect(args[1].required).toBeTruthy() - expect(args[1].description).toBeDefined() + expect(TheCommand.args.trigger).toBeDefined() + expect(TheCommand.args.trigger.required).toBeTruthy() + expect(TheCommand.args.trigger.description).toBeDefined() - expect(args[2].name).toEqual('action') - expect(args[2].required).toBeTruthy() - expect(args[2].description).toBeDefined() + expect(TheCommand.args.action).toBeDefined() + expect(TheCommand.args.action.required).toBeTruthy() + expect(TheCommand.args.action.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/delete.test.js b/test/commands/runtime/rule/delete.test.js index e266ca01..02e07fff 100644 --- a/test/commands/runtime/rule/delete.test.js +++ b/test/commands/runtime/rule/delete.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/delete.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.delete' @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/disable.test.js b/test/commands/runtime/rule/disable.test.js index 44586ee9..4a1b0c1e 100644 --- a/test/commands/runtime/rule/disable.test.js +++ b/test/commands/runtime/rule/disable.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/disable.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.disable' @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/enable.test.js b/test/commands/runtime/rule/enable.test.js index 1ceb59d8..9f8b7221 100644 --- a/test/commands/runtime/rule/enable.test.js +++ b/test/commands/runtime/rule/enable.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/enable.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.enable' @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/get.test.js b/test/commands/runtime/rule/get.test.js index 7355dced..b49af3cd 100644 --- a/test/commands/runtime/rule/get.test.js +++ b/test/commands/runtime/rule/get.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/get.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.get' @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/index.test.js b/test/commands/runtime/rule/index.test.js index 3e555b4d..0ac7b18d 100644 --- a/test/commands/runtime/rule/index.test.js +++ b/test/commands/runtime/rule/index.test.js @@ -30,7 +30,7 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/rule/list.test.js b/test/commands/runtime/rule/list.test.js index 95d395fb..4ba1ca80 100644 --- a/test/commands/runtime/rule/list.test.js +++ b/test/commands/runtime/rule/list.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/list.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.list' @@ -31,7 +33,6 @@ test('aliases', async () => { expect(TheCommand.aliases.length).toBeGreaterThan(0) }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) @@ -150,16 +151,15 @@ describe('instance methods', () => { }) }) - // eslint-disable-next-line jest/no-commented-out-tests - // test('return the number of rules with count flag', () => { - // let cmd = rtLib.mockResolved(rtAction, '2') - // command.argv = ['--count'] - // return command.run() - // .then(() => { - // expect(cmd).toHaveBeenCalledWith({ 'count': true, 'limit': 30 }) - // expect(stdout.output).toMatch('2') - // }) - // }) + test('return the number of rules with count flag', () => { + const cmd = rtLib.mockResolved(rtAction, Promise.resolve({ rules: 2 })) + command.argv = ['--count'] + return command.run() + .then(() => { + expect(cmd).toHaveBeenCalledWith({ count: true, useragent: expect.any(String) }) + expect(stdout.output).toMatch('2') + }) + }) test('return empty list of rules', () => { const cmd = rtLib.mockResolved(rtAction, []) diff --git a/test/commands/runtime/rule/status.test.js b/test/commands/runtime/rule/status.test.js index b3d5a20f..59d4e92d 100644 --- a/test/commands/runtime/rule/status.test.js +++ b/test/commands/runtime/rule/status.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/status.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.get' @@ -32,16 +34,11 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(1) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/rule/update.test.js b/test/commands/runtime/rule/update.test.js index b91a6469..2ead42ac 100644 --- a/test/commands/runtime/rule/update.test.js +++ b/test/commands/runtime/rule/update.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/rule/update.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const rtAction = 'rules.update' @@ -32,24 +34,19 @@ test('aliases', async () => { }) test('args', async () => { - const args = TheCommand.args - expect(args).toBeDefined() - expect(args.length).toEqual(3) - - expect(args[0].name).toEqual('name') - expect(args[0].required).toBeTruthy() - expect(args[0].description).toBeDefined() + expect(TheCommand.args.name).toBeDefined() + expect(TheCommand.args.name.required).toBeTruthy() + expect(TheCommand.args.name.description).toBeDefined() - expect(args[1].name).toEqual('trigger') - expect(args[1].required).toBeTruthy() - expect(args[1].description).toBeDefined() + expect(TheCommand.args.trigger).toBeDefined() + expect(TheCommand.args.trigger.required).toBeTruthy() + expect(TheCommand.args.trigger.description).toBeDefined() - expect(args[2].name).toEqual('action') - expect(args[2].required).toBeTruthy() - expect(args[2].description).toBeDefined() + expect(TheCommand.args.action).toBeDefined() + expect(TheCommand.args.action.required).toBeTruthy() + expect(TheCommand.args.action.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/trigger/create.test.js b/test/commands/runtime/trigger/create.test.js index 6798d98c..0c686562 100644 --- a/test/commands/runtime/trigger/create.test.js +++ b/test/commands/runtime/trigger/create.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/create.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -32,7 +34,6 @@ test('aliases', async () => { expect(TheCommand.aliases.length).toBeGreaterThan(0) }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) @@ -63,12 +64,9 @@ test('flags', async () => { }) test('args', async () => { - const triggerName = TheCommand.args[0] - - expect(triggerName).toBeDefined() - expect(triggerName.name).toEqual('triggerName') - expect(triggerName.required).toEqual(true) - expect(triggerName.description).toBeDefined() + expect(TheCommand.args.triggerName).toBeDefined() + expect(TheCommand.args.triggerName.required).toEqual(true) + expect(TheCommand.args.triggerName.description).toBeDefined() }) describe('instance methods', () => { diff --git a/test/commands/runtime/trigger/delete.test.js b/test/commands/runtime/trigger/delete.test.js index 6259ed23..a2cfb2d7 100644 --- a/test/commands/runtime/trigger/delete.test.js +++ b/test/commands/runtime/trigger/delete.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/delete.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -33,15 +35,11 @@ test('aliases', async () => { }) test('args', async () => { - const triggerPath = TheCommand.args[0] - - expect(triggerPath).toBeDefined() - expect(triggerPath.name).toEqual('triggerPath') - expect(triggerPath.required).toEqual(true) - expect(triggerPath.description).toBeDefined() + expect(TheCommand.args.triggerPath).toBeDefined() + expect(TheCommand.args.triggerPath.required).toEqual(true) + expect(TheCommand.args.triggerPath.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/trigger/fire.test.js b/test/commands/runtime/trigger/fire.test.js index 9eba40b3..807bdc18 100644 --- a/test/commands/runtime/trigger/fire.test.js +++ b/test/commands/runtime/trigger/fire.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/fire.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -33,15 +35,11 @@ test('aliases', async () => { }) test('args', async () => { - const triggerName = TheCommand.args[0] - - expect(triggerName).toBeDefined() - expect(triggerName.name).toEqual('triggerName') - expect(triggerName.required).toEqual(true) - expect(triggerName.description).toBeDefined() + expect(TheCommand.args.triggerName).toBeDefined() + expect(TheCommand.args.triggerName.required).toEqual(true) + expect(TheCommand.args.triggerName.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/trigger/get.test.js b/test/commands/runtime/trigger/get.test.js index a6834949..947ee178 100644 --- a/test/commands/runtime/trigger/get.test.js +++ b/test/commands/runtime/trigger/get.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/get.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -33,15 +35,11 @@ test('aliases', async () => { }) test('args', async () => { - const triggerPath = TheCommand.args[0] - - expect(triggerPath).toBeDefined() - expect(triggerPath.name).toEqual('triggerPath') - expect(triggerPath.required).toEqual(true) - expect(triggerPath.description).toBeDefined() + expect(TheCommand.args.triggerPath).toBeDefined() + expect(TheCommand.args.triggerPath.required).toEqual(true) + expect(TheCommand.args.triggerPath.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/trigger/index.test.js b/test/commands/runtime/trigger/index.test.js index 617fe968..fc192db5 100644 --- a/test/commands/runtime/trigger/index.test.js +++ b/test/commands/runtime/trigger/index.test.js @@ -34,7 +34,7 @@ test('flags', async () => { }) test('args', async () => { - expect(TheCommand.args).toBeUndefined() + expect(TheCommand.args).toEqual({}) }) describe('instance methods', () => { diff --git a/test/commands/runtime/trigger/list.test.js b/test/commands/runtime/trigger/list.test.js index 3592001d..e12f136b 100644 --- a/test/commands/runtime/trigger/list.test.js +++ b/test/commands/runtime/trigger/list.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/list.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -32,10 +34,9 @@ test('aliases', async () => { }) test('args', async () => { - expect(TheCommand.args).not.toBeDefined() + expect(TheCommand.args).toEqual({}) }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/commands/runtime/trigger/update.test.js b/test/commands/runtime/trigger/update.test.js index d030d054..53226718 100644 --- a/test/commands/runtime/trigger/update.test.js +++ b/test/commands/runtime/trigger/update.test.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "createTestBaseFlagsFunction"] }] */ + const TheCommand = require('../../../../src/commands/runtime/trigger/update.js') const RuntimeBaseCommand = require('../../../../src/RuntimeBaseCommand.js') const RuntimeLib = require('@adobe/aio-lib-runtime') @@ -58,15 +60,11 @@ test('flags', async () => { }) test('args', async () => { - const triggerName = TheCommand.args[0] - - expect(triggerName).toBeDefined() - expect(triggerName.name).toEqual('triggerName') - expect(triggerName.required).toEqual(true) - expect(triggerName.description).toBeDefined() + expect(TheCommand.args.triggerName).toBeDefined() + expect(TheCommand.args.triggerName.required).toEqual(true) + expect(TheCommand.args.triggerName.description).toBeDefined() }) -// eslint-disable-next-line jest/expect-expect test('base flags included in command flags', createTestBaseFlagsFunction(TheCommand, RuntimeBaseCommand) ) diff --git a/test/jest.setup.js b/test/jest.setup.js index c333ebed..2f647b8a 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -10,6 +10,8 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +/* eslint jest/no-standalone-expect: ["error", { "additionalTestBlockFunctions": ["expect.extend"] }] */ + const { stdout } = require('stdout-stderr') const realFs = jest.requireActual('fs') const fs = require('fs') @@ -29,6 +31,9 @@ delete process.env.WHISK_APIVERSION delete process.env.WHISK_NAMESPACE delete process.env.WSK_CONFIG_FILE +// default location of .wskprops +global.WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') + // trap console log // if you want to see output, you can do this: // beforeEach(() => { stdout.start(); stdout.print = true }) @@ -38,6 +43,8 @@ afterEach(() => { stdout.stop() }) jest.mock('fs', () => ({ ...jest.requireActual('fs'), existsSync: jest.fn(), + writeFileSync: jest.fn(), + mkdirSync: jest.fn(), // we have to have the default behaviour at the start since @oclif/core does some file reading on require readFileSync: jest.fn((p) => jest.requireActual('fs').readFileSync(p)), unlinkSync: jest.fn(), @@ -50,16 +57,20 @@ global.createFileSystem = (initialFiles = {}) => { fs.existsSync.mockImplementation((filePath) => { const value = !!myFileSystem[filePath] - if (!value) { + if (!value && filePath !== WSK_PROPS_PATH) { // for testing, we don't want to use an existing .wskprops return realFs.existsSync(filePath) } else { return value } }) + fs.writeFileSync.mockImplementation((filePath, value) => { + myFileSystem[filePath] = value + }) + fs.readFileSync.mockImplementation((filePath) => { const value = myFileSystem[filePath] - if (!value) { + if (value === undefined && filePath !== WSK_PROPS_PATH) { // for testing, we don't want to use an existing .wskprops return realFs.readFileSync(filePath) } else { return value @@ -81,6 +92,8 @@ global.createFileSystem = (initialFiles = {}) => { return item }) + fs.mkdirSync = jest.fn() // don't do anything + return myFileSystem } @@ -88,7 +101,9 @@ global.clearMockedFs = () => { const mockedFs = require('fs') mockedFs.existsSync.mockImplementation((p) => realFs.existsSync(p)) - mockedFs.readFileSync.mockImplementation((p) => realFs.readFileSync(p)) + mockedFs.writeFileSync.mockImplementation((p, ...rest) => realFs.writeFileSync(p, ...rest)) + mockedFs.mkdirSync.mockImplementation((p, ...rest) => realFs.mkdirSync(p, ...rest)) + mockedFs.readFileSync.mockImplementation((p, ...rest) => realFs.readFileSync(p, ...rest)) mockedFs.unlinkSync.mockImplementation((p) => realFs.unlinkSync(p)) mockedFs.rmdirSync.mockImplementation((p) => realFs.rmdirSync(p)) mockedFs.readdirSync.mockImplementation((p) => realFs.readdirSync(p)) @@ -194,7 +209,6 @@ global.createTestFlagsFunction = (TheCommand, Flags) => { expect.extend({ toMatchFixture (received, argument) { const val = fixtureFile(argument) - // eslint-disable-next-line jest/no-standalone-expect expect(eol.auto(received)).toEqual(eol.auto(val)) return { pass: true } } @@ -210,7 +224,6 @@ expect.extend({ toMatchFixtureIgnoreWhite (received, argument) { const val = cleanWhite(fixtureFile(argument)) // eat white - // eslint-disable-next-line jest/no-standalone-expect expect(cleanWhite(received)).toEqual(val) return { pass: true } } @@ -219,8 +232,9 @@ expect.extend({ expect.extend({ toMatchFixtureJson (received, argument) { const val = fixtureJson(argument) - // eslint-disable-next-line jest/no-standalone-expect expect(received).toEqual(val) return { pass: true } } }) + +global.createFileSystem({ [WSK_PROPS_PATH]: fixtureFile('wsk.properties') }) // seed the filesystem with .wskprops From 07cc91d3121db38bb9e8a891aff365b3dc058b39 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Fri, 21 Jul 2023 03:17:51 +0800 Subject: [PATCH 4/7] fix merge issue --- test/commands/runtime/action/create.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/commands/runtime/action/create.test.js b/test/commands/runtime/action/create.test.js index 3b74e288..9d3e3adc 100644 --- a/test/commands/runtime/action/create.test.js +++ b/test/commands/runtime/action/create.test.js @@ -306,7 +306,7 @@ test('creates an action with action name, action path, --params flag, limits and action: { name, exec: { - code: jsFile, + code: JS_FILE, kind: 'nodejs:10' }, parameters: [ @@ -337,7 +337,7 @@ test('creates an action with action name, action path, --params flag, only concu action: { name, exec: { - code: jsFile, + code: JS_FILE, kind: 'nodejs:10' }, parameters: [ From 8b99725bc5cccae52ee97ce8554142b50c3de7f0 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Fri, 21 Jul 2023 03:28:56 +0800 Subject: [PATCH 5/7] add AbortController polyfill for node-14 --- package.json | 1 + src/RuntimeBaseCommand.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/package.json b/package.json index 917110a8..135f81ee 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "inquirer": "^8.2.0", "js-yaml": "^4", "lodash.clonedeep": "^4.5.0", + "node-abort-controller": "^3.1.1", "openwhisk": "^3.21.2", "openwhisk-fqn": "^0.0.2", "properties-reader": "2.2.0", diff --git a/src/RuntimeBaseCommand.js b/src/RuntimeBaseCommand.js index beba341b..1c409d0f 100644 --- a/src/RuntimeBaseCommand.js +++ b/src/RuntimeBaseCommand.js @@ -10,6 +10,9 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ +const { AbortController } = require('node-abort-controller') +global.AbortController = AbortController + const { Command, Flags } = require('@oclif/core') const { propertiesFile, PropertyEnv, PropertyDefault } = require('./properties') From 3c62376d3e620c4c10b452e4f89c7d60c5f23fde Mon Sep 17 00:00:00 2001 From: Shazron Abdullah <36107+shazron@users.noreply.github.com> Date: Tue, 8 Aug 2023 16:39:40 +0800 Subject: [PATCH 6/7] fix eslint peer-dep issues --- .eslintrc | 10 +++++++++ package.json | 21 ++++++++++--------- .../namespace/log-forwarding/set.test.js | 2 +- .../set/adobe-io-runtime.test.js | 4 ++-- .../set/azure-log-analytics.test.js | 2 +- .../set/new-relic-runtime.test.js | 2 +- .../log-forwarding/set/splunk-hec.test.js | 2 +- test/jest.setup.js | 8 ++++--- 8 files changed, 32 insertions(+), 19 deletions(-) diff --git a/.eslintrc b/.eslintrc index 1db58df3..f87bf987 100644 --- a/.eslintrc +++ b/.eslintrc @@ -10,5 +10,15 @@ "fixtureZip": true, "createTestBaseFlagsFunction": true, "createTestFlagsFunction": true + }, + "rules": { + "jsdoc/tag-lines": [ + // The Error level should be `error`, `warn`, or `off` (or 2, 1, or 0) + "error", + "never", + { + "startLines": null + } + ] } } \ No newline at end of file diff --git a/package.json b/package.json index 135f81ee..2bd5daa7 100644 --- a/package.json +++ b/package.json @@ -26,20 +26,20 @@ "sha1": "^1.1.1" }, "devDependencies": { - "@adobe/eslint-config-aio-lib-config": "^2.0.0", + "@adobe/eslint-config-aio-lib-config": "^2.0.1", "@babel/core": "^7.16.12", "@babel/preset-env": "^7.16.11", "babel-jest": "^29.5.0", "babel-runtime": "^6.26.0", "dedent-js": "^1.0.1", "eol": "^0.9.1", - "eslint": "^8.38.0", + "eslint": "^8.46.0", "eslint-config-oclif": "^4.0.0", - "eslint-config-standard": "^17.0.0", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-jest": "^23.20.0", - "eslint-plugin-jsdoc": "^37.9.7", - "eslint-plugin-n": "^15.7.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-jest": "^27.2.3", + "eslint-plugin-jsdoc": "^42.0.0", + "eslint-plugin-n": "^16.0.1", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^6.1.1", "execa": "^4.0.0", @@ -47,7 +47,8 @@ "jest-junit": "^13.0.0", "jest-plugin-fs": "^2.9.0", "oclif": "^3.2.0", - "stdout-stderr": "^0.1.9" + "stdout-stderr": "^0.1.9", + "typescript": "^5.1.6" }, "engines": { "node": "^14.18 || ^16.13 || >=18" @@ -70,8 +71,8 @@ "repository": "adobe/aio-cli-plugin-runtime", "scripts": { "eslint-fix": "eslint src test e2e --fix", - "posttest": "eslint src test e2e", - "test": "npm run unit-tests", + "lint": "eslint src test e2e", + "test": "npm run unit-tests && npm run lint", "unit-tests": "jest --ci --runInBand test", "prepack": "oclif manifest && oclif readme --no-aliases", "postpack": "rm -f oclif.manifest.json", diff --git a/test/commands/runtime/namespace/log-forwarding/set.test.js b/test/commands/runtime/namespace/log-forwarding/set.test.js index 878ae109..91281dab 100644 --- a/test/commands/runtime/namespace/log-forwarding/set.test.js +++ b/test/commands/runtime/namespace/log-forwarding/set.test.js @@ -68,7 +68,7 @@ test.each(dataFixtures)('set log forwarding settings to %s (interactive)', async return command.run() .then(() => { expect(stdout.output).toMatch(`Log forwarding was set to ${destination} for this namespace`) - expect(setCall).toBeCalledTimes(1) + expect(setCall).toHaveBeenCalledTimes(1) expect(setCall).toHaveBeenCalledWith(destination, input) resolve() }) diff --git a/test/commands/runtime/namespace/log-forwarding/set/adobe-io-runtime.test.js b/test/commands/runtime/namespace/log-forwarding/set/adobe-io-runtime.test.js index bf0addfa..3e2277b2 100644 --- a/test/commands/runtime/namespace/log-forwarding/set/adobe-io-runtime.test.js +++ b/test/commands/runtime/namespace/log-forwarding/set/adobe-io-runtime.test.js @@ -27,8 +27,8 @@ test('set log forwarding settings to adobe_io_runtime', () => { return command.run() .then(() => { expect(stdout.output).toMatch(/Log forwarding was set to adobe_io_runtime for this namespace/) - expect(setCall).toBeCalledTimes(1) - expect(setCall).toBeCalledWith('adobe_io_runtime', {}) + expect(setCall).toHaveBeenCalledTimes(1) + expect(setCall).toHaveBeenCalledWith('adobe_io_runtime', {}) resolve() }) }) diff --git a/test/commands/runtime/namespace/log-forwarding/set/azure-log-analytics.test.js b/test/commands/runtime/namespace/log-forwarding/set/azure-log-analytics.test.js index 0a349fa1..b43a031d 100644 --- a/test/commands/runtime/namespace/log-forwarding/set/azure-log-analytics.test.js +++ b/test/commands/runtime/namespace/log-forwarding/set/azure-log-analytics.test.js @@ -28,7 +28,7 @@ test('set log forwarding settings to azure_log_analytics', () => { return command.run() .then(() => { expect(stdout.output).toMatch(/Log forwarding was set to azure_log_analytics for this namespace/) - expect(setCall).toBeCalledTimes(1) + expect(setCall).toHaveBeenCalledTimes(1) expect(setCall).toHaveBeenCalledWith('azure_log_analytics', { customer_id: 'customer1', shared_key: 'key1', log_type: 'mylog' }) resolve() }) diff --git a/test/commands/runtime/namespace/log-forwarding/set/new-relic-runtime.test.js b/test/commands/runtime/namespace/log-forwarding/set/new-relic-runtime.test.js index 0b3b4119..c34b08c7 100644 --- a/test/commands/runtime/namespace/log-forwarding/set/new-relic-runtime.test.js +++ b/test/commands/runtime/namespace/log-forwarding/set/new-relic-runtime.test.js @@ -28,7 +28,7 @@ test('set log forwarding settings to new_relic', () => { return command.run() .then(() => { expect(stdout.output).toMatch(/Log forwarding was set to new_relic for this namespace/) - expect(setCall).toBeCalledTimes(1) + expect(setCall).toHaveBeenCalledTimes(1) expect(setCall).toHaveBeenCalledWith('new_relic', { base_uri: 'uri1', license_key: 'key1' }) resolve() }) diff --git a/test/commands/runtime/namespace/log-forwarding/set/splunk-hec.test.js b/test/commands/runtime/namespace/log-forwarding/set/splunk-hec.test.js index 5c0c5a2c..a65896a2 100644 --- a/test/commands/runtime/namespace/log-forwarding/set/splunk-hec.test.js +++ b/test/commands/runtime/namespace/log-forwarding/set/splunk-hec.test.js @@ -28,7 +28,7 @@ test('set log forwarding settings to splunk_hec', () => { return command.run() .then(() => { expect(stdout.output).toMatch(/Log forwarding was set to splunk_hec for this namespace/) - expect(setCall).toBeCalledTimes(1) + expect(setCall).toHaveBeenCalledTimes(1) expect(setCall).toHaveBeenCalledWith('splunk_hec', { host: 'host1', port: 'port1', index: 'index1', hec_token: 'token1' }) resolve() }) diff --git a/test/jest.setup.js b/test/jest.setup.js index 2f647b8a..da69d014 100644 --- a/test/jest.setup.js +++ b/test/jest.setup.js @@ -35,9 +35,8 @@ delete process.env.WSK_CONFIG_FILE global.WSK_PROPS_PATH = require('path').join(require('os').homedir(), '.wskprops') // trap console log -// if you want to see output, you can do this: -// beforeEach(() => { stdout.start(); stdout.print = true }) -beforeEach(() => { stdout.start() }) +// if you want to see output, set stdout.print = true: +beforeEach(() => { stdout.start(); stdout.print = false }) afterEach(() => { stdout.stop() }) jest.mock('fs', () => ({ @@ -209,6 +208,7 @@ global.createTestFlagsFunction = (TheCommand, Flags) => { expect.extend({ toMatchFixture (received, argument) { const val = fixtureFile(argument) + // eslint-disable-next-line jest/no-standalone-expect expect(eol.auto(received)).toEqual(eol.auto(val)) return { pass: true } } @@ -224,6 +224,7 @@ expect.extend({ toMatchFixtureIgnoreWhite (received, argument) { const val = cleanWhite(fixtureFile(argument)) // eat white + // eslint-disable-next-line jest/no-standalone-expect expect(cleanWhite(received)).toEqual(val) return { pass: true } } @@ -232,6 +233,7 @@ expect.extend({ expect.extend({ toMatchFixtureJson (received, argument) { const val = fixtureJson(argument) + // eslint-disable-next-line jest/no-standalone-expect expect(received).toEqual(val) return { pass: true } } From a21b4e844756ffe41d4e988f9834f0068ac485e7 Mon Sep 17 00:00:00 2001 From: Shazron Abdullah Date: Tue, 19 Nov 2024 10:06:35 +0800 Subject: [PATCH 7/7] fix eslint issues --- package.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index c287ffad..c7d7898a 100644 --- a/package.json +++ b/package.json @@ -26,22 +26,22 @@ "sha1": "^1.1.1" }, "devDependencies": { - "@adobe/eslint-config-aio-lib-config": "^3.0.0", + "@adobe/eslint-config-aio-lib-config": "^4.0.0", "@babel/core": "^7.16.12", "@babel/preset-env": "^7.16.11", "babel-jest": "^29.5.0", "babel-runtime": "^6.26.0", "dedent-js": "^1.0.1", "eol": "^0.9.1", - "eslint": "^8.46.0", + "eslint": "^8.57.1", "eslint-config-oclif": "^4.0.0", "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.28.0", - "eslint-plugin-jest": "^27.2.3", - "eslint-plugin-jsdoc": "^42.0.0", - "eslint-plugin-n": "^16.0.1", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-jsdoc": "^48.11.0", + "eslint-plugin-n": "^15.7.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-promise": "^6.6.0", "execa": "^4.0.0", "jest": "^29.6.2", "jest-junit": "^16.0.0",