From e9b44d277e6576e88cfabf969b4a0c27aa393065 Mon Sep 17 00:00:00 2001 From: Ruy Adorno Date: Mon, 16 Nov 2020 22:07:13 -0500 Subject: [PATCH] test: add tests for lib/init.js fix: https://github.com/npm/statusboard/issues/155 PR-URL: https://github.com/npm/cli/pull/2185 Credit: @ruyadorno Close: #2185 Reviewed-by: @nlf --- lib/init.js | 15 +- tap-snapshots/test-lib-init.js-TAP.test.js | 19 ++ test/lib/init.js | 211 +++++++++++++++++++++ 3 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 tap-snapshots/test-lib-init.js-TAP.test.js create mode 100644 test/lib/init.js diff --git a/lib/init.js b/lib/init.js index e805a2eda7796..ed476ef38cb28 100644 --- a/lib/init.js +++ b/lib/init.js @@ -1,11 +1,11 @@ -// initialize a package.json file - -const usageUtil = require('./utils/usage.js') -const completion = require('./utils/completion/none.js') +'use strict' +const initJson = require('init-package-json') const npa = require('npm-package-arg') + const npm = require('./npm.js') -const initJson = require('init-package-json') +const usageUtil = require('./utils/usage.js') +const completion = require('./utils/completion/none.js') const output = require('./utils/output.js') const usage = usageUtil( @@ -78,11 +78,12 @@ const init = async args => { npm.log.warn('init', 'canceled') return res() } - npm.log.info('init', 'written successfully') if (er) rej(er) - else + else { + npm.log.info('init', 'written successfully') res(data) + } }) }) } diff --git a/tap-snapshots/test-lib-init.js-TAP.test.js b/tap-snapshots/test-lib-init.js-TAP.test.js new file mode 100644 index 0000000000000..25015aab65cb6 --- /dev/null +++ b/tap-snapshots/test-lib-init.js-TAP.test.js @@ -0,0 +1,19 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/lib/init.js TAP classic npm init no args > should print helper info 1`] = ` +This utility will walk you through creating a package.json file. +It only covers the most common items, and tries to guess sensible defaults. + +See \`npm help init\` for definitive documentation on these fields +and exactly what they do. + +Use \`npm install \` afterwards to install a package and +save it as a dependency in the package.json file. + +Press ^C at any time to quit. +` diff --git a/test/lib/init.js b/test/lib/init.js new file mode 100644 index 0000000000000..cb15eac8fc2eb --- /dev/null +++ b/test/lib/init.js @@ -0,0 +1,211 @@ +const t = require('tap') +const requireInject = require('require-inject') + +let result = '' +const npmLog = { + disableProgress: () => null, + enableProgress: () => null, + info: () => null, + pause: () => null, + resume: () => null, + silly: () => null, +} +const npm = { + config: { set () {} }, + flatOptions: {}, + log: npmLog, +} +const mocks = { + 'init-package-json': (dir, initFile, config, cb) => cb(null, 'data'), + '../../lib/npm.js': npm, + '../../lib/utils/usage.js': () => 'usage instructions', + '../../lib/utils/output.js': (...msg) => { + result += msg.join('\n') + }, +} +const init = requireInject('../../lib/init.js', mocks) + +t.afterEach(cb => { + result = '' + npm.config = { get: () => '', set () {} } + npm.commands = {} + npm.flatOptions = {} + npm.log = npmLog + cb() +}) + +t.test('classic npm init no args', t => { + npm.config = { + get () { + return '~/.npm-init.js' + }, + } + init([], err => { + t.ifError(err, 'npm init no args') + t.matchSnapshot(result, 'should print helper info') + t.end() + }) +}) + +t.test('classic npm init -y', t => { + t.plan(7) + npm.config = { + get: () => '~/.npm-init.js', + } + npm.flatOptions = { + yes: true, + } + npm.log = { ...npm.log } + npm.log.silly = (title, msg) => { + t.equal(title, 'package data', 'should print title') + t.equal(msg, 'data', 'should print pkg data info') + } + npm.log.resume = () => { + t.ok('should resume logs') + } + npm.log.info = (title, msg) => { + t.equal(title, 'init', 'should print title') + t.equal(msg, 'written successfully', 'should print done info') + } + init([], err => { + t.ifError(err, 'npm init -y') + t.equal(result, '') + }) +}) + +t.test('npm init ', t => { + t.plan(4) + npm.config = { + set (key, val) { + t.equal(key, 'package', 'should set package key') + t.deepEqual(val, [], 'should set empty array value') + }, + } + npm.commands.exec = (arr, cb) => { + t.deepEqual( + arr, + ['create-react-app'], + 'should npx with listed packages' + ) + cb() + } + init(['react-app'], err => { + t.ifError(err, 'npm init react-app') + }) +}) + +t.test('npm init @scope/name', t => { + t.plan(2) + npm.commands.exec = (arr, cb) => { + t.deepEqual( + arr, + ['@npmcli/create-something'], + 'should npx with scoped packages' + ) + cb() + } + init(['@npmcli/something'], err => { + t.ifError(err, 'npm init init @scope/name') + }) +}) + +t.test('npm init git spec', t => { + t.plan(2) + npm.commands.exec = (arr, cb) => { + t.deepEqual( + arr, + ['npm/create-something'], + 'should npx with git-spec packages' + ) + cb() + } + init(['npm/something'], err => { + t.ifError(err, 'npm init init @scope/name') + }) +}) + +t.test('npm init @scope', t => { + t.plan(2) + npm.commands.exec = (arr, cb) => { + t.deepEqual( + arr, + ['@npmcli/create'], + 'should npx with @scope/create pkgs' + ) + cb() + } + init(['@npmcli'], err => { + t.ifError(err, 'npm init init @scope/create') + }) +}) + +t.test('npm init tgz', t => { + init(['something.tgz'], err => { + t.match( + err, + /Error: Unrecognized initializer: something.tgz/, + 'should throw error when using an unsupported spec' + ) + t.end() + }) +}) + +t.test('npm init @next', t => { + t.plan(2) + npm.commands.exec = (arr, cb) => { + t.deepEqual( + arr, + ['create-something@next'], + 'should npx with something@next' + ) + cb() + } + init(['something@next'], err => { + t.ifError(err, 'npm init init something@next') + }) +}) + +t.test('npm init exec error', t => { + npm.commands.exec = (arr, cb) => { + cb(new Error('ERROR')) + } + init(['something@next'], err => { + t.match( + err, + /ERROR/, + 'should exit with exec error' + ) + t.end() + }) +}) + +t.test('npm init cancel', t => { + t.plan(3) + const init = requireInject('../../lib/init.js', { + ...mocks, + 'init-package-json': (dir, initFile, config, cb) => cb( + new Error('canceled') + ), + }) + npm.log = { ...npm.log } + npm.log.warn = (title, msg) => { + t.equal(title, 'init', 'should have init title') + t.equal(msg, 'canceled', 'should log canceled') + } + init([], err => { + t.ifError(err, 'npm init cancel') + }) +}) + +t.test('npm init error', t => { + const init = requireInject('../../lib/init.js', { + ...mocks, + 'init-package-json': (dir, initFile, config, cb) => cb( + new Error('Unknown Error') + ), + }) + init([], err => { + t.match(err, /Unknown Error/, 'should throw error') + t.end() + }) +})