diff options
author | Ruy Adorno <ruyadorno@hotmail.com> | 2020-05-17 08:30:11 +0300 |
---|---|---|
committer | nlf <quitlahok@gmail.com> | 2021-01-28 23:50:12 +0300 |
commit | d011266b733367aad283ccbfb9d2b19442c3405f (patch) | |
tree | 689c45b149cd77b4dab6d12b2c09bfa9c40d8aaa /test | |
parent | bb7329def2631308a82144f050955de913a5c8e4 (diff) |
feat: add npm diffruyadorno/npm-diff
- As proposed in RFC: https://github.com/npm/rfcs/pull/144
PR-URL: https://github.com/npm/cli/pull/1319
Credit: @ruyadorno
Close: #1319
Reviewed-by: @isaacs
Diffstat (limited to 'test')
-rw-r--r-- | test/lib/diff.js | 1159 |
1 files changed, 1159 insertions, 0 deletions
diff --git a/test/lib/diff.js b/test/lib/diff.js new file mode 100644 index 000000000..926c54fdf --- /dev/null +++ b/test/lib/diff.js @@ -0,0 +1,1159 @@ +const { resolve } = require('path') +const t = require('tap') +const requireInject = require('require-inject') + +const noop = () => null +let libnpmdiff = noop +let rlp = () => 'foo' +const defaultFlatOptions = { + defaultTag: 'latest', + diff: [], + diffUnified: null, + diffIgnoreAllSpace: false, + diffNoPrefix: false, + diffSrcPrefix: '', + diffDstPrefix: '', + diffText: false, + prefix: '.', + savePrefix: '^', +} +const npm = { + globalDir: __dirname, + flatOptions: { ...defaultFlatOptions }, + get prefix () { + return this.flatOptions.prefix + }, +} +const mocks = { + npmlog: { info: noop, verbose: noop }, + libnpmdiff: (...args) => libnpmdiff(...args), + 'npm-registry-fetch': async () => ({}), + '../../lib/npm.js': npm, + '../../lib/utils/output.js': noop, + '../../lib/utils/read-local-package.js': async () => rlp(), + '../../lib/utils/usage.js': () => 'usage instructions', +} + +t.afterEach(cb => { + npm.flatOptions = { ...defaultFlatOptions } + libnpmdiff = noop + rlp = () => 'foo' + npm.globalDir = __dirname + cb() +}) + +const diff = requireInject('../../lib/diff.js', mocks) + +t.test('no args', t => { + t.test('in a project dir', t => { + t.plan(3) + + const path = t.testdir({}) + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@latest', 'should have default spec comparison') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('no args, missing package.json name in cwd', t => { + rlp = () => undefined + + diff([], err => { + t.match( + err, + /Needs multiple arguments to compare or run from a project dir./, + 'should throw EDIFF error msg' + ) + t.end() + }) + }) + + t.test('no args, missing package.json in cwd', t => { + rlp = () => { + throw new Error('ERR') + } + + diff([], err => { + t.match( + err, + /Needs multiple arguments to compare or run from a project dir./, + 'should throw EDIFF error msg' + ) + t.end() + }) + }) + + t.end() +}) + +t.test('single arg', t => { + t.test('spec using cwd package name', t => { + t.plan(3) + + const path = t.testdir({}) + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@1.0.0', 'should forward single spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['foo@1.0.0'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('unknown spec, no package.json', t => { + const path = t.testdir({}) + rlp = () => { + throw new Error('ERR') + } + + npm.flatOptions.diff = ['foo@1.0.0'] + npm.flatOptions.prefix = path + diff([], err => { + t.match( + err, + /Needs multiple arguments to compare or run from a project dir./, + 'should throw usage error' + ) + t.end() + }) + }) + + t.test('spec using semver range', t => { + t.plan(3) + + const path = t.testdir({}) + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@~1.0.0', 'should forward single spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['foo@~1.0.0'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('version', t => { + t.plan(3) + + const path = t.testdir({}) + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@2.1.4', 'should convert to expected first spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['2.1.4'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('version, no package.json', t => { + rlp = () => { + throw new Error('ERR') + } + + npm.flatOptions.diff = ['2.1.4'] + diff([], err => { + t.match( + err, + /Needs multiple arguments to compare or run from a project dir./, + 'should throw an error message explaining usage' + ) + t.end() + }) + }) + + t.test('version, filtering by files', t => { + t.plan(3) + + const path = t.testdir({}) + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@2.1.4', 'should use expected spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, { + ...npm.flatOptions, + diffFiles: [ + './foo.js', + './bar.js', + ], + }, 'should forward flatOptions and diffFiles') + } + + npm.flatOptions.diff = ['2.1.4'] + npm.flatOptions.prefix = path + diff(['./foo.js', './bar.js'], err => { + if (err) + throw err + }) + }) + + t.test('spec is not a dep', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: {}, + 'package.json': JSON.stringify({ + name: 'my-project', + }), + }) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should have current spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + } + + npm.flatOptions.diff = ['bar@1.0.0'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('unknown package name', t => { + t.plan(3) + + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'simple-output@latest', 'should forward single spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['simple-output'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('unknown package name, no package.json', t => { + const path = t.testdir({}) + rlp = () => { + throw new Error('ERR') + } + + npm.flatOptions.diff = ['bar'] + npm.flatOptions.prefix = path + diff([], err => { + t.match( + err, + /Needs multiple arguments to compare or run from a project dir./, + 'should throw usage error' + ) + t.end() + }) + }) + + t.test('transform single direct dep name into spec comparison', t => { + t.plan(4) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + npm.flatOptions.diff = ['bar'] + npm.flatOptions.prefix = path + + const diff = requireInject('../../lib/diff.js', { + ...mocks, + pacote: { + packument: (spec) => { + t.equal(spec.name, 'bar', 'should have expected spec name') + }, + }, + 'npm-pick-manifest': (packument, target) => { + t.equal(target, '^1.0.0', 'should use expected target') + return { version: '1.8.10' } + }, + libnpmdiff: async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, 'bar@1.8.10', 'should have possible semver range spec') + }, + }) + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('global space, transform single direct dep name', t => { + t.plan(4) + + const path = t.testdir({ + globalDir: { + lib: { + node_modules: { + lorem: { + 'package.json': JSON.stringify({ + name: 'lorem', + version: '2.0.0', + }), + }, + }, + }, + }, + project: { + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }, + }) + + npm.flatOptions.global = true + npm.flatOptions.diff = ['lorem'] + npm.flatOptions.prefix = resolve(path, 'project') + npm.globalDir = resolve(path, 'globalDir/lib/node_modules') + + const diff = requireInject('../../lib/diff.js', { + ...mocks, + pacote: { + packument: (spec) => { + t.equal(spec.name, 'lorem', 'should have expected spec name') + }, + }, + 'npm-pick-manifest': (packument, target) => { + t.equal(target, '*', 'should always want latest in global space') + return { version: '2.1.0' } + }, + libnpmdiff: async ([a, b], opts) => { + t.equal(a, `lorem@file:${resolve(path, 'globalDir/lib/node_modules/lorem')}`, 'should target local node_modules pkg') + t.equal(b, 'lorem@2.1.0', 'should have possible semver range spec') + }, + }) + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('transform single spec into spec comparison', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, 'bar@2.0.0', 'should have expected comparison spec') + } + + npm.flatOptions.diff = ['bar@2.0.0'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('transform single spec from transitive deps', t => { + t.plan(4) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + dependencies: { + lorem: '^2.0.0', + }, + }), + }, + lorem: { + 'package.json': JSON.stringify({ + name: 'lorem', + version: '2.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + const diff = requireInject('../../lib/diff.js', { + ...mocks, + '../../lib/utils/read-local-package.js': async () => 'my-project', + pacote: { + packument: (spec) => { + t.equal(spec.name, 'lorem', 'should have expected spec name') + }, + }, + 'npm-pick-manifest': (packument, target) => { + t.equal(target, '^2.0.0', 'should target first semver-range spec found') + return { version: '2.2.2' } + }, + libnpmdiff: async ([a, b], opts) => { + t.equal(a, `lorem@file:${resolve(path, 'node_modules/lorem')}`, 'should target local node_modules pkg') + t.equal(b, 'lorem@2.2.2', 'should have expected target spec') + }, + }) + + npm.flatOptions.diff = ['lorem'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('missing actual tree', t => { + t.plan(2) + + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'my-project', + }), + }) + + const diff = requireInject('../../lib/diff.js', { + ...mocks, + '../../lib/utils/read-local-package.js': async () => 'my-project', + '@npmcli/arborist': class { + constructor () { + throw new Error('ERR') + } + }, + libnpmdiff: async ([a, b], opts) => { + t.equal(a, 'lorem@latest', 'should target latest version of pkg name') + t.equal(b, `file:${path}`, 'should target current cwd') + }, + }) + + npm.flatOptions.diff = ['lorem'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('unknown package name', t => { + t.plan(2) + + const path = t.testdir({}) + rlp = async () => undefined + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@latest', 'should target latest tag of name') + t.equal(b, `file:${path}`, 'should compare to cwd') + } + + npm.flatOptions.diff = ['bar'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('use project name in project dir', t => { + t.plan(2) + + const path = t.testdir({}) + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'my-project@latest', 'should target latest tag of name') + t.equal(b, `file:${path}`, 'should compare to cwd') + } + + npm.flatOptions.diff = ['my-project'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('dir spec type', t => { + t.plan(2) + + const path = t.testdir({}) + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'file:/path/to/other-dir', 'should target dir') + t.equal(b, `file:${path}`, 'should compare to cwd') + } + + npm.flatOptions.diff = ['/path/to/other-dir'] + npm.flatOptions.prefix = path + diff([], err => { + if (err) + throw err + }) + }) + + t.test('unsupported spec type', t => { + rlp = async () => 'my-project' + + npm.flatOptions.diff = ['git+https://github.com/user/foo'] + + diff([], err => { + t.match( + err, + /Spec type not supported./, + 'should throw spec type not supported error.' + ) + t.end() + }) + }) + + t.end() +}) + +t.test('first arg is a qualified spec', t => { + t.test('second arg is ALSO a qualified spec', t => { + t.plan(3) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should set expected first spec') + t.equal(b, 'bar@^2.0.0', 'should set expected second spec') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['bar@1.0.0', 'bar@^2.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a known dependency name', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@2.0.0', 'should set expected first spec') + t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar@2.0.0', 'bar'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a valid semver version', t => { + t.plan(2) + + npm.flatOptions.diff = ['bar@1.0.0', '2.0.0'] + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should set expected first spec') + t.equal(b, 'bar@2.0.0', 'should use name from first arg') + } + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is an unknown dependency name', t => { + t.plan(2) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should set expected first spec') + t.equal(b, 'bar-fork@latest', 'should target latest tag if not a dep') + } + + npm.flatOptions.diff = ['bar@1.0.0', 'bar-fork'] + diff([], err => { + if (err) + throw err + }) + }) + + t.end() +}) + +t.test('first arg is a known dependency name', t => { + t.test('second arg is a qualified spec', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, 'bar@2.0.0', 'should set expected second spec') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar', 'bar@2.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is ALSO a known dependency', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + 'bar-fork': { + 'package.json': JSON.stringify({ + name: 'bar-fork', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, `bar-fork@file:${resolve(path, 'node_modules/bar-fork')}`, 'should target fork local node_modules pkg') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar', 'bar-fork'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a valid semver version', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, 'bar@2.0.0', 'should use package name from first arg') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar', '2.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is an unknown dependency name', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '1.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + t.equal(b, 'bar-fork@latest', 'should set expected second spec') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar', 'bar-fork'] + diff([], err => { + if (err) + throw err + }) + }) + + t.end() +}) + +t.test('first arg is a valid semver range', t => { + t.test('second arg is a qualified spec', t => { + t.plan(2) + + npm.flatOptions.diff = ['1.0.0', 'bar@2.0.0'] + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should use name from second arg') + t.equal(b, 'bar@2.0.0', 'should use expected spec') + } + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a known dependency', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '2.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should use name from second arg') + t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should set expected second spec from nm') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['1.0.0', 'bar'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is ALSO a semver version', t => { + t.plan(2) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'my-project@1.0.0', 'should use name from project dir') + t.equal(b, 'my-project@2.0.0', 'should use name from project dir') + } + + npm.flatOptions.diff = ['1.0.0', '2.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is ALSO a semver version BUT cwd not a project dir', t => { + const path = t.testdir({}) + rlp = () => { + throw new Error('ERR') + } + + npm.flatOptions.diff = ['1.0.0', '2.0.0'] + npm.flatOptions.prefix = path + diff([], err => { + t.match( + err, + /Needs to be run from a project dir in order to diff two versions./, + 'should throw two versions need project dir error usage msg' + ) + t.end() + }) + }) + + t.test('second arg is an unknown dependency name', t => { + t.plan(2) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@1.0.0', 'should use name from second arg') + t.equal(b, 'bar@latest', 'should compare against latest tag') + } + + npm.flatOptions.diff = ['1.0.0', 'bar'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a qualified spec, missing actual tree', t => { + t.plan(2) + + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'my-project', + }), + }) + + const diff = requireInject('../../lib/diff.js', { + ...mocks, + '../../lib/utils/read-local-package.js': async () => 'my-project', + '@npmcli/arborist': class { + constructor () { + throw new Error('ERR') + } + }, + libnpmdiff: async ([a, b], opts) => { + t.equal(a, 'lorem@1.0.0', 'should target latest version of pkg name') + t.equal(b, 'lorem@2.0.0', 'should target expected spec') + }, + }) + + npm.flatOptions.diff = ['1.0.0', 'lorem@2.0.0'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.end() +}) + +t.test('first arg is an unknown dependency name', t => { + t.test('second arg is a qualified spec', t => { + t.plan(3) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@latest', 'should set expected first spec') + t.equal(b, 'bar@2.0.0', 'should set expected second spec') + t.match(opts, npm.flatOptions, 'should forward flat options') + } + + npm.flatOptions.diff = ['bar', 'bar@2.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a known dependency', t => { + t.plan(2) + + const path = t.testdir({ + node_modules: { + bar: { + 'package.json': JSON.stringify({ + name: 'bar', + version: '2.0.0', + }), + }, + }, + 'package.json': JSON.stringify({ + name: 'my-project', + dependencies: { + bar: '^1.0.0', + }, + }), + }) + + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar-fork@latest', 'should use latest tag') + t.equal(b, `bar@file:${resolve(path, 'node_modules/bar')}`, 'should target local node_modules pkg') + } + + npm.flatOptions.prefix = path + npm.flatOptions.diff = ['bar-fork', 'bar'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is a valid semver version', t => { + t.plan(2) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@latest', 'should use latest tag') + t.equal(b, 'bar@^1.0.0', 'should use name from first arg') + } + + npm.flatOptions.diff = ['bar', '^1.0.0'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('second arg is ALSO an unknown dependency name', t => { + t.plan(2) + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@latest', 'should use latest tag') + t.equal(b, 'bar-fork@latest', 'should use latest tag') + } + + npm.flatOptions.diff = ['bar', 'bar-fork'] + diff([], err => { + if (err) + throw err + }) + }) + + t.test('cwd not a project dir', t => { + t.plan(2) + + const path = t.testdir({}) + rlp = () => { + throw new Error('ERR') + } + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'bar@latest', 'should use latest tag') + t.equal(b, 'bar-fork@latest', 'should use latest tag') + } + + npm.flatOptions.diff = ['bar', 'bar-fork'] + npm.flatOptions.prefix = path + + diff([], err => { + if (err) + throw err + }) + }) + + t.end() +}) + +t.test('various options', t => { + t.test('using --name-only option', t => { + t.plan(1) + + npm.flatOptions.diffNameOnly = true + + libnpmdiff = async ([a, b], opts) => { + t.match(opts, { + ...npm.flatOptions, + diffNameOnly: true, + }, 'should forward nameOnly=true option') + } + + diff([], err => { + if (err) + throw err + }) + }) + + t.test('set files after both versions', t => { + t.plan(3) + + npm.flatOptions.diff = ['2.1.4', '3.0.0'] + + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'foo@2.1.4', 'should use expected spec') + t.equal(b, 'foo@3.0.0', 'should use expected spec') + t.match(opts, { + ...npm.flatOptions, + diffFiles: [ + './foo.js', + './bar.js', + ], + }, 'should forward diffFiles values') + } + + diff(['./foo.js', './bar.js'], err => { + if (err) + throw err + }) + }) + + t.test('set files no diff args', t => { + t.plan(3) + + const path = t.testdir({}) + rlp = async () => 'my-project' + libnpmdiff = async ([a, b], opts) => { + t.equal(a, 'my-project@latest', 'should have default spec') + t.equal(b, `file:${path}`, 'should compare to cwd') + t.match(opts, { + ...npm.flatOptions, + diffFiles: [ + './foo.js', + './bar.js', + ], + }, 'should forward all remaining items as filenames') + } + + npm.flatOptions.prefix = path + diff(['./foo.js', './bar.js'], err => { + if (err) + throw err + }) + }) + + t.test('using diff option', t => { + t.plan(1) + + npm.flatOptions.diffContext = 5 + npm.flatOptions.diffIgnoreWhitespace = true + npm.flatOptions.diffNoPrefix = false + npm.flatOptions.diffSrcPrefix = 'foo/' + npm.flatOptions.diffDstPrefix = 'bar/' + npm.flatOptions.diffText = true + + libnpmdiff = async ([a, b], opts) => { + t.match(opts, { + ...npm.flatOptions, + diffContext: 5, + diffIgnoreWhitespace: true, + diffNoPrefix: false, + diffSrcPrefix: 'foo/', + diffDstPrefix: 'bar/', + diffText: true, + }, 'should forward diff options') + } + + diff([], err => { + if (err) + throw err + }) + }) + + t.end() +}) + +t.test('too many args', t => { + npm.flatOptions.diff = ['a', 'b', 'c'] + diff([], err => { + t.match( + err, + /Can't use more than two --diff arguments./, + 'should throw usage error' + ) + t.end() + }) +}) |