diff --git a/jest.setup.js b/jest.setup.js index bb05b30..309fc53 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -33,18 +33,16 @@ global.fixtureJson = (output) => { expect.extend({ toMatchFixture (received, argument) { const val = global.fixtureFile(argument) - // eslint-disable-next-line jest/no-standalone-expect - expect(eol.auto(received)).toEqual(eol.auto(val)) - return { pass: true } + const isEqual = eol.auto(received) === eol.auto(val) + return { pass: isEqual } } }) expect.extend({ toMatchFixtureJson (received, argument) { const val = global.fixtureJson(argument) - // eslint-disable-next-line jest/no-standalone-expect - expect(received).toEqual(val) - return { pass: true } + const isEqual = received === val + return { pass: isEqual } } }) diff --git a/package.json b/package.json index 51d9434..deccd95 100644 --- a/package.json +++ b/package.json @@ -7,14 +7,14 @@ "url": "git+https://github.com/adobe/aio-cli-plugin-app-templates.git" }, "dependencies": { - "@adobe/aio-cli-lib-app-config": "^0.2.2", - "@adobe/aio-cli-lib-console": "^4.0.0", - "@adobe/aio-lib-console-project-installation": "^2.2.2", - "@adobe/aio-lib-core-config": "^2.0.0", - "@adobe/aio-lib-core-logging": "^1.1.0", - "@adobe/aio-lib-env": "^2.0.0", - "@adobe/aio-lib-ims": "^6.0.1", - "@adobe/aio-lib-templates": "^2.2.0", + "@adobe/aio-cli-lib-app-config": "^4", + "@adobe/aio-cli-lib-console": "^5", + "@adobe/aio-lib-console-project-installation": "^3", + "@adobe/aio-lib-core-config": "^5", + "@adobe/aio-lib-core-logging": "^3", + "@adobe/aio-lib-env": "^3", + "@adobe/aio-lib-ims": "^7", + "@adobe/aio-lib-templates": "^3", "@oclif/core": "^1.9.3", "chalk": "^4.1.2", "execa": "^4.1.0", @@ -26,25 +26,27 @@ "yeoman-environment": "^3.9.1" }, "devDependencies": { - "@adobe/eslint-config-aio-lib-config": "^1.4.0", + "@adobe/eslint-config-aio-lib-config": "^2.0.2", "@types/jest": "^28.1.5", "acorn": "^7", "eol": "^0.9.1", - "eslint": "^7.5", + "eslint": "^8.56.0", "eslint-config-oclif": "^3.1.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^23.20.0", - "eslint-plugin-jsdoc": "^37.9.7", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^27.6.2", + "eslint-plugin-jsdoc": "^42.0.0", + "eslint-plugin-n": "^15.7.0", "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.2.0", + "eslint-plugin-promise": "^6.1.1", "eslint-plugin-standard": "^4.0.1", - "jest": "^27", + "jest": "^29", "jest-haste-map": "^24.5.0", "jest-junit": "^6.0.0", "jest-resolve": "^24.5.0", "oclif": "^3.2.0", - "stdout-stderr": "^0.1.9" + "stdout-stderr": "^0.1.9", + "typescript": "^5.3.3" }, "engines": { "node": ">=18" @@ -80,7 +82,8 @@ "global": { "branches": 100, "lines": 100, - "statements": 100 + "statements": 100, + "functions": 100 } }, "collectCoverage": true, diff --git a/src/commands/templates/discover.js b/src/commands/templates/discover.js index 1ff27ad..f38e28e 100644 --- a/src/commands/templates/discover.js +++ b/src/commands/templates/discover.js @@ -17,7 +17,7 @@ const inquirer = require('inquirer') const { TEMPLATE_PACKAGE_JSON_KEY, readPackageJson } = require('../../lib/npm-helper') const { getTemplates } = require('../../lib/template-registry-helper') const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app-templates:templates:discover', { provider: 'debug' }) -const loadConfig = require('@adobe/aio-cli-lib-app-config') +const { load: loadConfig } = require('@adobe/aio-cli-lib-app-config') const env = require('@adobe/aio-lib-env') const LibConsoleCLI = require('@adobe/aio-cli-lib-console') const { SEARCH_CRITERIA_FILTER_NOT } = require('@adobe/aio-lib-templates') @@ -32,7 +32,7 @@ class DiscoverCommand extends BaseCommand { await this.login() const apiKey = env.getCliEnv() === 'prod' ? 'aio-cli-console-auth' : 'aio-cli-console-auth-stage' - const consoleCLI = await LibConsoleCLI.init({ accessToken: this.accessToken, env: env.getCliEnv(), apiKey: apiKey }) + const consoleCLI = await LibConsoleCLI.init({ accessToken: this.accessToken, env: env.getCliEnv(), apiKey }) const appConfig = loadConfig({}) let orgId = appConfig?.aio?.project?.org?.id diff --git a/src/commands/templates/install.js b/src/commands/templates/install.js index 2a05884..41c98fe 100644 --- a/src/commands/templates/install.js +++ b/src/commands/templates/install.js @@ -21,7 +21,7 @@ const { Flags } = require('@oclif/core') // aio-lib-console-project-installation dependencies const path = require('path') -const loadConfig = require('@adobe/aio-cli-lib-app-config') +const { load: loadConfig } = require('@adobe/aio-cli-lib-app-config') const templateHandler = require('@adobe/aio-lib-console-project-installation') class InstallCommand extends BaseCommand { diff --git a/test/commands/templates/discover.test.js b/test/commands/templates/discover.test.js index d5e2118..8aa2206 100644 --- a/test/commands/templates/discover.test.js +++ b/test/commands/templates/discover.test.js @@ -29,7 +29,7 @@ jest.mock('@adobe/aio-lib-ims', () => ({ })) jest.mock('@adobe/aio-cli-lib-app-config') -const loadConfig = require('@adobe/aio-cli-lib-app-config') +const { load: loadConfig } = require('@adobe/aio-cli-lib-app-config') const mockAIOConfigJSON = JSON.parse('{"aio": {"project": {"id": "project-id","org": {"id": "org-id"}}}}') jest.mock('@adobe/aio-lib-env') @@ -140,16 +140,9 @@ describe('sorting', () => { test('unknown sort-field', async () => { command.argv = ['--sort-field', 'unknown'] - return new Promise((resolve, reject) => { - return command.run() - .then(() => { - reject(new Error('it should not succeed')) - }) - .catch(error => { - expect(error.message).toMatch('Expected --sort-field=') - resolve() - }) - }) + + await expect(command.run()).rejects + .toThrow('Expected --sort-field=unknown to be one of: publishDate, names, adobeRecommended\nSee more help with --help') }) test('sort-field=names, ascending', async () => { diff --git a/test/commands/templates/install.test.js b/test/commands/templates/install.test.js index 9837fd6..897bed6 100644 --- a/test/commands/templates/install.test.js +++ b/test/commands/templates/install.test.js @@ -25,7 +25,7 @@ TemplateHandler.init.mockResolvedValue(mockTemplateHandlerInstance) // mock app config calls jest.mock('@adobe/aio-cli-lib-app-config') -const loadConfig = require('@adobe/aio-cli-lib-app-config') +const { load: loadConfig } = require('@adobe/aio-cli-lib-app-config') const mockAIOConfigJSON = JSON.parse('{"aio": {"project": {"id": "project-id","org": {"id": "org-id"}}}}') loadConfig.mockImplementation(() => mockAIOConfigJSON) @@ -148,12 +148,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', argPath]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', argPath]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -174,12 +174,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -200,12 +200,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': true, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': true, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -226,12 +226,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: true }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: true }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -252,12 +252,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -279,12 +279,12 @@ describe('run', () => { expect.assertions(8) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).not.toBeCalled() - expect(getTemplateRequiredServiceNames).toBeCalledWith(templateName) - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).not.toHaveBeenCalled() + expect(getTemplateRequiredServiceNames).toHaveBeenCalledWith(templateName) + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -307,12 +307,12 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).not.toBeCalled() - expect(getTemplateRequiredServiceNames).toBeCalledWith(templateName) - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).not.toHaveBeenCalled() + expect(getTemplateRequiredServiceNames).toHaveBeenCalledWith(templateName) + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] @@ -336,11 +336,11 @@ describe('run', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', templateName]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', templateName]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() expect(writeObjectToPackageJson).not.toHaveBeenCalled() }) @@ -358,8 +358,8 @@ describe('run', () => { getNpmDependency.mockResolvedValueOnce([templateName, '1.0.0']) expect.assertions(2) - await expect(command.run()).rejects.toThrowError('Error installing template: Missing orgId or projectId in project configuration') - expect(mockTemplateHandlerInstance.installTemplate).not.toBeCalled() + await expect(command.run()).rejects.toThrow('Error installing template: Missing orgId or projectId in project configuration') + expect(mockTemplateHandlerInstance.installTemplate).not.toHaveBeenCalled() }) }) @@ -379,12 +379,12 @@ describe('template-options', () => { expect.assertions(7) await expect(command.run()).resolves.toBeUndefined() - expect(runScript).toBeCalledWith('npm', process.cwd(), ['install', argPath]) - expect(yeomanEnvInstantiate).toBeCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) - expect(yeomanEnvOptionsSet).toBeCalledWith({ skipInstall: false }) - expect(mockTemplateHandlerInstance.installTemplate).toBeCalledWith('org-id', 'project-id') - expect(getTemplateRequiredServiceNames).not.toBeCalled() - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(runScript).toHaveBeenCalledWith('npm', process.cwd(), ['install', argPath]) + expect(yeomanEnvInstantiate).toHaveBeenCalledWith(expect.any(Object), { options: { 'skip-prompt': false, force: true } }) + expect(yeomanEnvOptionsSet).toHaveBeenCalledWith({ skipInstall: false }) + expect(mockTemplateHandlerInstance.installTemplate).toHaveBeenCalledWith('org-id', 'project-id') + expect(getTemplateRequiredServiceNames).not.toHaveBeenCalled() + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [ templateName ] diff --git a/test/commands/templates/uninstall.test.js b/test/commands/templates/uninstall.test.js index 4e8c8af..bafa6e0 100644 --- a/test/commands/templates/uninstall.test.js +++ b/test/commands/templates/uninstall.test.js @@ -80,7 +80,7 @@ describe('run', () => { return new Promise(resolve => { return command.run() .then(() => { - expect(writeObjectToPackageJson).toBeCalledWith({ + expect(writeObjectToPackageJson).toHaveBeenCalledWith({ [TEMPLATE_PACKAGE_JSON_KEY]: [] }) resolve() @@ -101,7 +101,7 @@ describe('run', () => { return new Promise(resolve => { return command.run() .then(() => { - expect(command.error).toBeCalledWith(`template ${templateName} is not installed.`) + expect(command.error).toHaveBeenCalledWith(`template ${templateName} is not installed.`) resolve() }) }) diff --git a/test/lib/npm-helper.test.js b/test/lib/npm-helper.test.js index 336a1a2..b1c5a25 100644 --- a/test/lib/npm-helper.test.js +++ b/test/lib/npm-helper.test.js @@ -268,11 +268,8 @@ describe('package.json', () => { const obj = { foo: 'bar' } fs.writeJson.mockImplementation((fp, objToWrite) => { - if (fp === filePath) { - expect(objToWrite).toStrictEqual({ ...packageJson, ...obj }) - } else { - throw new Error(`writeJson: file not found: ${fp}`) - } + expect(fp).toEqual(filePath) + expect(objToWrite).toStrictEqual({ ...packageJson, ...obj }) }) await writeObjectToPackageJson(obj, dir) @@ -283,11 +280,8 @@ describe('package.json', () => { const obj = { foo: 'bar' } fs.writeJson.mockImplementation((fp, objToWrite) => { - if (fp === filePath) { - expect(objToWrite).toStrictEqual({ ...packageJson, ...obj }) - } else { - throw new Error(`writeJson: file not found: ${fp}`) - } + expect(fp).toEqual(filePath) + expect(objToWrite).toStrictEqual({ ...packageJson, ...obj }) }) useProcessCwd = true diff --git a/test/lib/template-helper.test.js b/test/lib/template-helper.test.js index b6c6cbc..bc33e96 100644 --- a/test/lib/template-helper.test.js +++ b/test/lib/template-helper.test.js @@ -23,7 +23,7 @@ describe('Getting services required by a template', () => { const templateRequiredServices = { runtime: true, apis: [{ code: 'GraphQLServiceSDK' }, { code: 'AssetComputeSDK' }] } templateHandler.getTemplateRequiredServices.mockReturnValueOnce(templateRequiredServices) expect(getTemplateRequiredServices(npmPackageName)).toEqual(templateRequiredServices) - expect(templateHandler.getTemplateRequiredServices).toBeCalledWith(templateConfigurationFile) + expect(templateHandler.getTemplateRequiredServices).toHaveBeenCalledWith(templateConfigurationFile) }) test('Getting a list of service names required by a template', () => { diff --git a/test/resolver.js b/test/resolver.js index a353488..87cd35f 100644 --- a/test/resolver.js +++ b/test/resolver.js @@ -11,6 +11,7 @@ governing permissions and limitations under the License. */ const fs = require('fs') +const nodePath = require('path') /** * Resolves to a full path. @@ -20,8 +21,7 @@ const fs = require('fs') * @returns {string} A resolved path. */ function resolver (path, options) { - /* eslint-disable node/no-path-concat */ - const modulesResolutionJson = __dirname + '/modules-resolution.json' + const modulesResolutionJson = nodePath.join(__dirname, 'modules-resolution.json') const mapping = JSON.parse(fs.readFileSync(modulesResolutionJson)) return mapping[path] || options.defaultResolver(path, options) }