summaryrefslogtreecommitdiff
path: root/deps/npm
diff options
context:
space:
mode:
authornpm CLI robot <npm-cli+bot@github.com>2023-01-16 22:38:23 -0500
committerGitHub <noreply@github.com>2023-01-17 03:38:23 +0000
commit66b1356ebcf55e477639a52baba3067afd9ea7a0 (patch)
tree5cb2825cf03029d12670cd78872a596d0a019722 /deps/npm
parent17aa1958e5ee3cd879c91a882be280d75ee0587e (diff)
downloadnode-new-66b1356ebcf55e477639a52baba3067afd9ea7a0.tar.gz
deps: upgrade npm to 9.3.0
PR-URL: https://github.com/nodejs/node/pull/46193 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'deps/npm')
-rw-r--r--deps/npm/docs/content/commands/npm-access.md2
-rw-r--r--deps/npm/docs/content/commands/npm-adduser.md3
-rw-r--r--deps/npm/docs/content/commands/npm-ci.md4
-rw-r--r--deps/npm/docs/content/commands/npm-dedupe.md4
-rw-r--r--deps/npm/docs/content/commands/npm-find-dupes.md4
-rw-r--r--deps/npm/docs/content/commands/npm-init.md2
-rw-r--r--deps/npm/docs/content/commands/npm-install-ci-test.md4
-rw-r--r--deps/npm/docs/content/commands/npm-install-test.md4
-rw-r--r--deps/npm/docs/content/commands/npm-install.md4
-rw-r--r--deps/npm/docs/content/commands/npm-link.md4
-rw-r--r--deps/npm/docs/content/commands/npm-login.md3
-rw-r--r--deps/npm/docs/content/commands/npm-ls.md2
-rw-r--r--deps/npm/docs/content/commands/npm-owner.md2
-rw-r--r--deps/npm/docs/content/commands/npm-publish.md4
-rw-r--r--deps/npm/docs/content/commands/npm-root.md2
-rw-r--r--deps/npm/docs/content/commands/npm-update.md4
-rw-r--r--deps/npm/docs/content/commands/npm.md6
-rw-r--r--deps/npm/docs/content/configuring-npm/install.md6
-rw-r--r--deps/npm/docs/content/using-npm/config.md11
-rw-r--r--deps/npm/docs/content/using-npm/registry.md2
-rw-r--r--deps/npm/docs/content/using-npm/removal.md4
-rw-r--r--deps/npm/docs/content/using-npm/scripts.md2
-rw-r--r--deps/npm/docs/output/commands/npm-access.html1
-rw-r--r--deps/npm/docs/output/commands/npm-adduser.html3
-rw-r--r--deps/npm/docs/output/commands/npm-ci.html4
-rw-r--r--deps/npm/docs/output/commands/npm-dedupe.html4
-rw-r--r--deps/npm/docs/output/commands/npm-find-dupes.html4
-rw-r--r--deps/npm/docs/output/commands/npm-init.html2
-rw-r--r--deps/npm/docs/output/commands/npm-install-ci-test.html4
-rw-r--r--deps/npm/docs/output/commands/npm-install-test.html4
-rw-r--r--deps/npm/docs/output/commands/npm-install.html4
-rw-r--r--deps/npm/docs/output/commands/npm-link.html4
-rw-r--r--deps/npm/docs/output/commands/npm-login.html3
-rw-r--r--deps/npm/docs/output/commands/npm-ls.html2
-rw-r--r--deps/npm/docs/output/commands/npm-owner.html1
-rw-r--r--deps/npm/docs/output/commands/npm-publish.html4
-rw-r--r--deps/npm/docs/output/commands/npm-root.html1
-rw-r--r--deps/npm/docs/output/commands/npm-update.html4
-rw-r--r--deps/npm/docs/output/commands/npm.html5
-rw-r--r--deps/npm/docs/output/configuring-npm/install.html6
-rw-r--r--deps/npm/docs/output/using-npm/config.html11
-rw-r--r--deps/npm/docs/output/using-npm/registry.html2
-rw-r--r--deps/npm/docs/output/using-npm/removal.html4
-rw-r--r--deps/npm/docs/output/using-npm/scripts.html2
-rw-r--r--deps/npm/lib/arborist-cmd.js31
-rw-r--r--deps/npm/lib/base-command.js81
-rw-r--r--deps/npm/lib/cli.js13
-rw-r--r--deps/npm/lib/commands/access.js2
-rw-r--r--deps/npm/lib/commands/adduser.js2
-rw-r--r--deps/npm/lib/commands/audit.js2
-rw-r--r--deps/npm/lib/commands/cache.js15
-rw-r--r--deps/npm/lib/commands/ci.js9
-rw-r--r--deps/npm/lib/commands/completion.js25
-rw-r--r--deps/npm/lib/commands/config.js11
-rw-r--r--deps/npm/lib/commands/diff.js5
-rw-r--r--deps/npm/lib/commands/dist-tag.js17
-rw-r--r--deps/npm/lib/commands/edit.js16
-rw-r--r--deps/npm/lib/commands/exec.js37
-rw-r--r--deps/npm/lib/commands/find-dupes.js2
-rw-r--r--deps/npm/lib/commands/fund.js95
-rw-r--r--deps/npm/lib/commands/help-search.js9
-rw-r--r--deps/npm/lib/commands/help.js99
-rw-r--r--deps/npm/lib/commands/hook.js18
-rw-r--r--deps/npm/lib/commands/init.js39
-rw-r--r--deps/npm/lib/commands/install-ci-test.js2
-rw-r--r--deps/npm/lib/commands/install-test.js2
-rw-r--r--deps/npm/lib/commands/login.js2
-rw-r--r--deps/npm/lib/commands/logout.js2
-rw-r--r--deps/npm/lib/commands/ls.js10
-rw-r--r--deps/npm/lib/commands/org.js11
-rw-r--r--deps/npm/lib/commands/outdated.js4
-rw-r--r--deps/npm/lib/commands/owner.js7
-rw-r--r--deps/npm/lib/commands/pack.js5
-rw-r--r--deps/npm/lib/commands/ping.js7
-rw-r--r--deps/npm/lib/commands/pkg.js7
-rw-r--r--deps/npm/lib/commands/prefix.js1
-rw-r--r--deps/npm/lib/commands/profile.js4
-rw-r--r--deps/npm/lib/commands/publish.js7
-rw-r--r--deps/npm/lib/commands/query.js5
-rw-r--r--deps/npm/lib/commands/restart.js3
-rw-r--r--deps/npm/lib/commands/root.js1
-rw-r--r--deps/npm/lib/commands/run-script.js17
-rw-r--r--deps/npm/lib/commands/search.js1
-rw-r--r--deps/npm/lib/commands/start.js3
-rw-r--r--deps/npm/lib/commands/stop.js3
-rw-r--r--deps/npm/lib/commands/test.js3
-rw-r--r--deps/npm/lib/commands/token.js13
-rw-r--r--deps/npm/lib/commands/uninstall.js17
-rw-r--r--deps/npm/lib/commands/unpublish.js7
-rw-r--r--deps/npm/lib/commands/update.js4
-rw-r--r--deps/npm/lib/commands/version.js15
-rw-r--r--deps/npm/lib/commands/view.js89
-rw-r--r--deps/npm/lib/commands/whoami.js1
-rw-r--r--deps/npm/lib/lifecycle-cmd.js6
-rw-r--r--deps/npm/lib/npm.js201
-rw-r--r--deps/npm/lib/package-url-cmd.js7
-rw-r--r--deps/npm/lib/utils/config/definitions.js16
-rw-r--r--deps/npm/lib/utils/error-message.js22
-rw-r--r--deps/npm/lib/utils/exit-handler.js20
-rw-r--r--deps/npm/lib/utils/explain-dep.js6
-rw-r--r--deps/npm/lib/utils/log-file.js8
-rw-r--r--deps/npm/lib/utils/npm-usage.js3
-rw-r--r--deps/npm/lib/utils/open-url.js2
-rw-r--r--deps/npm/lib/utils/queryable.js15
-rw-r--r--deps/npm/lib/utils/read-user-info.js6
-rw-r--r--deps/npm/lib/utils/reify-output.js4
-rw-r--r--deps/npm/lib/workspaces/get-workspaces.js2
-rw-r--r--deps/npm/man/man1/npm-access.14
-rw-r--r--deps/npm/man/man1/npm-adduser.14
-rw-r--r--deps/npm/man/man1/npm-audit.12
-rw-r--r--deps/npm/man/man1/npm-bugs.12
-rw-r--r--deps/npm/man/man1/npm-cache.12
-rw-r--r--deps/npm/man/man1/npm-ci.16
-rw-r--r--deps/npm/man/man1/npm-completion.12
-rw-r--r--deps/npm/man/man1/npm-config.12
-rw-r--r--deps/npm/man/man1/npm-dedupe.16
-rw-r--r--deps/npm/man/man1/npm-deprecate.12
-rw-r--r--deps/npm/man/man1/npm-diff.12
-rw-r--r--deps/npm/man/man1/npm-dist-tag.12
-rw-r--r--deps/npm/man/man1/npm-docs.12
-rw-r--r--deps/npm/man/man1/npm-doctor.12
-rw-r--r--deps/npm/man/man1/npm-edit.12
-rw-r--r--deps/npm/man/man1/npm-exec.12
-rw-r--r--deps/npm/man/man1/npm-explain.12
-rw-r--r--deps/npm/man/man1/npm-explore.12
-rw-r--r--deps/npm/man/man1/npm-find-dupes.16
-rw-r--r--deps/npm/man/man1/npm-fund.12
-rw-r--r--deps/npm/man/man1/npm-help-search.12
-rw-r--r--deps/npm/man/man1/npm-help.12
-rw-r--r--deps/npm/man/man1/npm-hook.12
-rw-r--r--deps/npm/man/man1/npm-init.14
-rw-r--r--deps/npm/man/man1/npm-install-ci-test.16
-rw-r--r--deps/npm/man/man1/npm-install-test.16
-rw-r--r--deps/npm/man/man1/npm-install.16
-rw-r--r--deps/npm/man/man1/npm-link.16
-rw-r--r--deps/npm/man/man1/npm-login.14
-rw-r--r--deps/npm/man/man1/npm-logout.12
-rw-r--r--deps/npm/man/man1/npm-ls.14
-rw-r--r--deps/npm/man/man1/npm-org.12
-rw-r--r--deps/npm/man/man1/npm-outdated.12
-rw-r--r--deps/npm/man/man1/npm-owner.14
-rw-r--r--deps/npm/man/man1/npm-pack.12
-rw-r--r--deps/npm/man/man1/npm-ping.12
-rw-r--r--deps/npm/man/man1/npm-pkg.12
-rw-r--r--deps/npm/man/man1/npm-prefix.12
-rw-r--r--deps/npm/man/man1/npm-profile.12
-rw-r--r--deps/npm/man/man1/npm-prune.12
-rw-r--r--deps/npm/man/man1/npm-publish.14
-rw-r--r--deps/npm/man/man1/npm-query.12
-rw-r--r--deps/npm/man/man1/npm-rebuild.12
-rw-r--r--deps/npm/man/man1/npm-repo.12
-rw-r--r--deps/npm/man/man1/npm-restart.12
-rw-r--r--deps/npm/man/man1/npm-root.14
-rw-r--r--deps/npm/man/man1/npm-run-script.12
-rw-r--r--deps/npm/man/man1/npm-search.12
-rw-r--r--deps/npm/man/man1/npm-shrinkwrap.12
-rw-r--r--deps/npm/man/man1/npm-star.12
-rw-r--r--deps/npm/man/man1/npm-stars.12
-rw-r--r--deps/npm/man/man1/npm-start.12
-rw-r--r--deps/npm/man/man1/npm-stop.12
-rw-r--r--deps/npm/man/man1/npm-team.12
-rw-r--r--deps/npm/man/man1/npm-test.12
-rw-r--r--deps/npm/man/man1/npm-token.12
-rw-r--r--deps/npm/man/man1/npm-uninstall.12
-rw-r--r--deps/npm/man/man1/npm-unpublish.12
-rw-r--r--deps/npm/man/man1/npm-unstar.12
-rw-r--r--deps/npm/man/man1/npm-update.16
-rw-r--r--deps/npm/man/man1/npm-version.12
-rw-r--r--deps/npm/man/man1/npm-view.12
-rw-r--r--deps/npm/man/man1/npm-whoami.12
-rw-r--r--deps/npm/man/man1/npm.18
-rw-r--r--deps/npm/man/man1/npx.12
-rw-r--r--deps/npm/man/man5/folders.52
-rw-r--r--deps/npm/man/man5/install.58
-rw-r--r--deps/npm/man/man5/npm-global.52
-rw-r--r--deps/npm/man/man5/npm-json.52
-rw-r--r--deps/npm/man/man5/npm-shrinkwrap-json.52
-rw-r--r--deps/npm/man/man5/npmrc.52
-rw-r--r--deps/npm/man/man5/package-json.52
-rw-r--r--deps/npm/man/man5/package-lock-json.52
-rw-r--r--deps/npm/man/man7/config.710
-rw-r--r--deps/npm/man/man7/dependency-selectors.72
-rw-r--r--deps/npm/man/man7/developers.72
-rw-r--r--deps/npm/man/man7/logging.72
-rw-r--r--deps/npm/man/man7/orgs.72
-rw-r--r--deps/npm/man/man7/package-spec.72
-rw-r--r--deps/npm/man/man7/registry.74
-rw-r--r--deps/npm/man/man7/removal.74
-rw-r--r--deps/npm/man/man7/scope.72
-rw-r--r--deps/npm/man/man7/scripts.74
-rw-r--r--deps/npm/man/man7/workspaces.72
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js4
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js4
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js22
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/override-resolves.js2
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/override-set.js29
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js3
-rw-r--r--deps/npm/node_modules/@npmcli/arborist/package.json7
-rw-r--r--deps/npm/node_modules/@npmcli/config/lib/index.js49
-rw-r--r--deps/npm/node_modules/@npmcli/config/package.json4
-rw-r--r--deps/npm/node_modules/libnpmaccess/package.json2
-rw-r--r--deps/npm/node_modules/libnpmdiff/package.json6
-rw-r--r--deps/npm/node_modules/libnpmexec/package.json8
-rw-r--r--deps/npm/node_modules/libnpmfund/package.json6
-rw-r--r--deps/npm/node_modules/libnpmhook/package.json2
-rw-r--r--deps/npm/node_modules/libnpmorg/package.json2
-rw-r--r--deps/npm/node_modules/libnpmpack/package.json6
-rw-r--r--deps/npm/node_modules/libnpmpublish/package.json4
-rw-r--r--deps/npm/node_modules/libnpmsearch/package.json2
-rw-r--r--deps/npm/node_modules/libnpmteam/package.json2
-rw-r--r--deps/npm/node_modules/libnpmversion/package.json2
-rw-r--r--deps/npm/node_modules/minipass-fetch/node_modules/minipass/LICENSE15
-rw-r--r--deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.d.ts155
-rw-r--r--deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.js649
-rw-r--r--deps/npm/node_modules/minipass-fetch/node_modules/minipass/package.json56
-rw-r--r--deps/npm/node_modules/minipass-fetch/package.json11
-rw-r--r--deps/npm/package.json20
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs4
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs1
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs88
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs25
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs96
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs44
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs55
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/link.js.test.cjs34
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs388
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs161
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs3
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs44
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/stars.js.test.cjs1
-rw-r--r--deps/npm/tap-snapshots/test/lib/commands/team.js.test.cjs15
-rw-r--r--deps/npm/tap-snapshots/test/lib/docs.js.test.cjs77
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs89
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs26
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs2
-rw-r--r--deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs438
-rw-r--r--deps/npm/test/bin/npm-cli.js6
-rw-r--r--deps/npm/test/bin/npx-cli.js72
-rw-r--r--deps/npm/test/fixtures/clean-snapshot.js30
-rw-r--r--deps/npm/test/fixtures/merge-conflict.json36
-rw-r--r--deps/npm/test/fixtures/mock-globals.js34
-rw-r--r--deps/npm/test/fixtures/mock-npm.js353
-rw-r--r--deps/npm/test/fixtures/sandbox.js6
-rw-r--r--deps/npm/test/fixtures/tmock.js27
-rw-r--r--deps/npm/test/index.js32
-rw-r--r--deps/npm/test/lib/arborist-cmd.js201
-rw-r--r--deps/npm/test/lib/cli.js43
-rw-r--r--deps/npm/test/lib/commands/audit.js49
-rw-r--r--deps/npm/test/lib/commands/bugs.js142
-rw-r--r--deps/npm/test/lib/commands/config.js8
-rw-r--r--deps/npm/test/lib/commands/diff.js1691
-rw-r--r--deps/npm/test/lib/commands/dist-tag.js336
-rw-r--r--deps/npm/test/lib/commands/docs.js172
-rw-r--r--deps/npm/test/lib/commands/doctor.js40
-rw-r--r--deps/npm/test/lib/commands/edit.js8
-rw-r--r--deps/npm/test/lib/commands/exec.js9
-rw-r--r--deps/npm/test/lib/commands/explain.js416
-rw-r--r--deps/npm/test/lib/commands/explore.js352
-rw-r--r--deps/npm/test/lib/commands/fund.js700
-rw-r--r--deps/npm/test/lib/commands/help-search.js145
-rw-r--r--deps/npm/test/lib/commands/help.js420
-rw-r--r--deps/npm/test/lib/commands/hook.js419
-rw-r--r--deps/npm/test/lib/commands/init.js521
-rw-r--r--deps/npm/test/lib/commands/install.js361
-rw-r--r--deps/npm/test/lib/commands/link.js544
-rw-r--r--deps/npm/test/lib/commands/ll.js5
-rw-r--r--deps/npm/test/lib/commands/logout.js255
-rw-r--r--deps/npm/test/lib/commands/ls.js6098
-rw-r--r--deps/npm/test/lib/commands/org.js342
-rw-r--r--deps/npm/test/lib/commands/outdated.js610
-rw-r--r--deps/npm/test/lib/commands/owner.js38
-rw-r--r--deps/npm/test/lib/commands/pack.js16
-rw-r--r--deps/npm/test/lib/commands/pkg.js383
-rw-r--r--deps/npm/test/lib/commands/profile.js694
-rw-r--r--deps/npm/test/lib/commands/prune.js2
-rw-r--r--deps/npm/test/lib/commands/publish.js93
-rw-r--r--deps/npm/test/lib/commands/query.js32
-rw-r--r--deps/npm/test/lib/commands/rebuild.js231
-rw-r--r--deps/npm/test/lib/commands/repo.js110
-rw-r--r--deps/npm/test/lib/commands/restart.js4
-rw-r--r--deps/npm/test/lib/commands/run-script.js761
-rw-r--r--deps/npm/test/lib/commands/set.js99
-rw-r--r--deps/npm/test/lib/commands/stars.js105
-rw-r--r--deps/npm/test/lib/commands/start.js4
-rw-r--r--deps/npm/test/lib/commands/stop.js4
-rw-r--r--deps/npm/test/lib/commands/team.js294
-rw-r--r--deps/npm/test/lib/commands/test.js4
-rw-r--r--deps/npm/test/lib/commands/token.js752
-rw-r--r--deps/npm/test/lib/commands/uninstall.js298
-rw-r--r--deps/npm/test/lib/commands/update.js201
-rw-r--r--deps/npm/test/lib/commands/version.js489
-rw-r--r--deps/npm/test/lib/commands/view.js196
-rw-r--r--deps/npm/test/lib/docs.js2
-rw-r--r--deps/npm/test/lib/fixtures/mock-globals.js14
-rw-r--r--deps/npm/test/lib/lifecycle-cmd.js23
-rw-r--r--deps/npm/test/lib/load-all-commands.js35
-rw-r--r--deps/npm/test/lib/npm.js58
-rw-r--r--deps/npm/test/lib/utils/audit-error.js136
-rw-r--r--deps/npm/test/lib/utils/completion/installed-deep.js3
-rw-r--r--deps/npm/test/lib/utils/completion/installed-shallow.js7
-rw-r--r--deps/npm/test/lib/utils/config/definitions.js14
-rw-r--r--deps/npm/test/lib/utils/display.js7
-rw-r--r--deps/npm/test/lib/utils/error-message.js196
-rw-r--r--deps/npm/test/lib/utils/exit-handler.js61
-rw-r--r--deps/npm/test/lib/utils/explain-dep.js11
-rw-r--r--deps/npm/test/lib/utils/log-file.js20
-rw-r--r--deps/npm/test/lib/utils/log-shim.js3
-rw-r--r--deps/npm/test/lib/utils/open-url-prompt.js19
-rw-r--r--deps/npm/test/lib/utils/open-url.js3
-rw-r--r--deps/npm/test/lib/utils/otplease.js159
-rw-r--r--deps/npm/test/lib/utils/pulse-till-done.js3
-rw-r--r--deps/npm/test/lib/utils/read-user-info.js3
-rw-r--r--deps/npm/test/lib/utils/reify-finish.js8
-rw-r--r--deps/npm/test/lib/utils/reify-output.js231
-rw-r--r--deps/npm/test/lib/utils/tar.js3
-rw-r--r--deps/npm/test/lib/utils/timers.js3
-rw-r--r--deps/npm/test/lib/utils/update-notifier.js12
-rw-r--r--deps/npm/test/lib/utils/web-auth.js3
318 files changed, 11241 insertions, 13255 deletions
diff --git a/deps/npm/docs/content/commands/npm-access.md b/deps/npm/docs/content/commands/npm-access.md
index f2078e1c9c..7c7e1ffdcc 100644
--- a/deps/npm/docs/content/commands/npm-access.md
+++ b/deps/npm/docs/content/commands/npm-access.md
@@ -16,6 +16,8 @@ npm access grant <read-only|read-write> <scope:team> [<package>]
npm access revoke <scope:team> [<package>]
```
+Note: This command is unaware of workspaces.
+
### Description
Used to set access controls on private packages.
diff --git a/deps/npm/docs/content/commands/npm-adduser.md b/deps/npm/docs/content/commands/npm-adduser.md
index f0cd57be25..bc7d888a2f 100644
--- a/deps/npm/docs/content/commands/npm-adduser.md
+++ b/deps/npm/docs/content/commands/npm-adduser.md
@@ -67,7 +67,8 @@ npm init --scope=@foo --yes
* Default: "web"
* Type: "legacy" or "web"
-What authentication strategy to use with `login`.
+What authentication strategy to use with `login`. Note that if an `otp`
+config is given, this value will always be set to `legacy`.
### See Also
diff --git a/deps/npm/docs/content/commands/npm-ci.md b/deps/npm/docs/content/commands/npm-ci.md
index 4a5caf7d0c..1e9220b6a6 100644
--- a/deps/npm/docs/content/commands/npm-ci.md
+++ b/deps/npm/docs/content/commands/npm-ci.md
@@ -138,7 +138,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `omit`
@@ -173,7 +173,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-dedupe.md b/deps/npm/docs/content/commands/npm-dedupe.md
index 80353bad5d..c32b50fbc5 100644
--- a/deps/npm/docs/content/commands/npm-dedupe.md
+++ b/deps/npm/docs/content/commands/npm-dedupe.md
@@ -109,7 +109,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `strict-peer-deps`
@@ -126,7 +126,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-find-dupes.md b/deps/npm/docs/content/commands/npm-find-dupes.md
index a3ef44eb5b..e80f338239 100644
--- a/deps/npm/docs/content/commands/npm-find-dupes.md
+++ b/deps/npm/docs/content/commands/npm-find-dupes.md
@@ -49,7 +49,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `strict-peer-deps`
@@ -66,7 +66,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-init.md b/deps/npm/docs/content/commands/npm-init.md
index cf8bb3936a..d8d7acee77 100644
--- a/deps/npm/docs/content/commands/npm-init.md
+++ b/deps/npm/docs/content/commands/npm-init.md
@@ -7,7 +7,7 @@ description: Create a package.json file
### Synopsis
```bash
-npm init <package-spec> (same as `npx <package-spec>)
+npm init <package-spec> (same as `npx <package-spec>`)
npm init <@scope> (same as `npx <@scope>/create`)
aliases: create, innit
diff --git a/deps/npm/docs/content/commands/npm-install-ci-test.md b/deps/npm/docs/content/commands/npm-install-ci-test.md
index 9fd7c267b1..c7a7551023 100644
--- a/deps/npm/docs/content/commands/npm-install-ci-test.md
+++ b/deps/npm/docs/content/commands/npm-install-ci-test.md
@@ -84,7 +84,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `omit`
@@ -119,7 +119,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-install-test.md b/deps/npm/docs/content/commands/npm-install-test.md
index 5642472630..464a448748 100644
--- a/deps/npm/docs/content/commands/npm-install-test.md
+++ b/deps/npm/docs/content/commands/npm-install-test.md
@@ -85,7 +85,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `omit`
@@ -120,7 +120,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-install.md b/deps/npm/docs/content/commands/npm-install.md
index 3604aab4b9..8353ea25a9 100644
--- a/deps/npm/docs/content/commands/npm-install.md
+++ b/deps/npm/docs/content/commands/npm-install.md
@@ -475,7 +475,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `omit`
@@ -510,7 +510,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-link.md b/deps/npm/docs/content/commands/npm-link.md
index 09459cc0ca..9de0ff2c0a 100644
--- a/deps/npm/docs/content/commands/npm-link.md
+++ b/deps/npm/docs/content/commands/npm-link.md
@@ -176,7 +176,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `strict-peer-deps`
@@ -193,7 +193,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm-login.md b/deps/npm/docs/content/commands/npm-login.md
index 4feb715040..00f10ad95e 100644
--- a/deps/npm/docs/content/commands/npm-login.md
+++ b/deps/npm/docs/content/commands/npm-login.md
@@ -74,7 +74,8 @@ npm init --scope=@foo --yes
* Default: "web"
* Type: "legacy" or "web"
-What authentication strategy to use with `login`.
+What authentication strategy to use with `login`. Note that if an `otp`
+config is given, this value will always be set to `legacy`.
### See Also
diff --git a/deps/npm/docs/content/commands/npm-ls.md b/deps/npm/docs/content/commands/npm-ls.md
index 2ae99e7e7c..d8b6f4a7de 100644
--- a/deps/npm/docs/content/commands/npm-ls.md
+++ b/deps/npm/docs/content/commands/npm-ls.md
@@ -27,7 +27,7 @@ packages will *also* show the paths to the specified packages. For
example, running `npm ls promzard` in npm's source tree will show:
```bash
-npm@9.2.0 /path/to/npm
+npm@9.3.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
```
diff --git a/deps/npm/docs/content/commands/npm-owner.md b/deps/npm/docs/content/commands/npm-owner.md
index c5bace6b2b..2b04f635b1 100644
--- a/deps/npm/docs/content/commands/npm-owner.md
+++ b/deps/npm/docs/content/commands/npm-owner.md
@@ -14,8 +14,6 @@ npm owner ls <package-spec>
alias: author
```
-Note: This command is unaware of workspaces.
-
### Description
Manage ownership of published packages.
diff --git a/deps/npm/docs/content/commands/npm-publish.md b/deps/npm/docs/content/commands/npm-publish.md
index 09756aedf0..b23d9ad8a1 100644
--- a/deps/npm/docs/content/commands/npm-publish.md
+++ b/deps/npm/docs/content/commands/npm-publish.md
@@ -107,8 +107,8 @@ tarball that will be compared with the local files by default.
current level
* Type: null, "restricted", or "public"
-If do not want your scoped package to be publicly viewable (and installable)
-set `--access=restricted`.
+If you do not want your scoped package to be publicly viewable (and
+installable) set `--access=restricted`.
Unscoped packages can not be set to `restricted`.
diff --git a/deps/npm/docs/content/commands/npm-root.md b/deps/npm/docs/content/commands/npm-root.md
index 89195744c9..b34321eb96 100644
--- a/deps/npm/docs/content/commands/npm-root.md
+++ b/deps/npm/docs/content/commands/npm-root.md
@@ -10,6 +10,8 @@ description: Display npm root
npm root
```
+Note: This command is unaware of workspaces.
+
### Description
Print the effective `node_modules` folder to standard out.
diff --git a/deps/npm/docs/content/commands/npm-update.md b/deps/npm/docs/content/commands/npm-update.md
index cdd3190828..16c8e4df66 100644
--- a/deps/npm/docs/content/commands/npm-update.md
+++ b/deps/npm/docs/content/commands/npm-update.md
@@ -215,7 +215,7 @@ de-duplicating. Sets `--install-strategy=nested`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `omit`
@@ -250,7 +250,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
diff --git a/deps/npm/docs/content/commands/npm.md b/deps/npm/docs/content/commands/npm.md
index be17431b58..2396b40cf5 100644
--- a/deps/npm/docs/content/commands/npm.md
+++ b/deps/npm/docs/content/commands/npm.md
@@ -10,9 +10,11 @@ description: javascript package manager
npm
```
+Note: This command is unaware of workspaces.
+
### Version
-9.2.0
+9.3.0
### Description
@@ -132,7 +134,7 @@ npm is extremely configurable. It reads its configuration options from
in the cli, env, or user config, then that file is parsed instead.
* Defaults:
npm's default configuration options are defined in
- lib/utils/config-defs.js. These must not be changed.
+ `lib/utils/config/definitions.js`. These must not be changed.
See [`config`](/using-npm/config) for much much more information.
diff --git a/deps/npm/docs/content/configuring-npm/install.md b/deps/npm/docs/content/configuring-npm/install.md
index 43fce4868b..18b4421687 100644
--- a/deps/npm/docs/content/configuring-npm/install.md
+++ b/deps/npm/docs/content/configuring-npm/install.md
@@ -17,11 +17,11 @@ run npm packages globally.
### Overview
- [Checking your version of npm and
- Node.js](#checking-your-version-of-npm-and-node-js)
+ Node.js](#checking-your-version-of-npm-and-nodejs)
- [Using a Node version manager to install Node.js and
- npm](#using-a-node-version-manager-to-install-node-js-and-npm)
+ npm](#using-a-node-version-manager-to-install-nodejs-and-npm)
- [Using a Node installer to install Node.js and
- npm](#using-a-node-installer-to-install-node-js-and-npm)
+ npm](#using-a-node-installer-to-install-nodejs-and-npm)
### Checking your version of npm and Node.js
diff --git a/deps/npm/docs/content/using-npm/config.md b/deps/npm/docs/content/using-npm/config.md
index 0eda3ec536..c70f51d13b 100644
--- a/deps/npm/docs/content/using-npm/config.md
+++ b/deps/npm/docs/content/using-npm/config.md
@@ -142,8 +142,8 @@ safer to use a registry-provided authentication bearer token stored in the
current level
* Type: null, "restricted", or "public"
-If do not want your scoped package to be publicly viewable (and installable)
-set `--access=restricted`.
+If you do not want your scoped package to be publicly viewable (and
+installable) set `--access=restricted`.
Unscoped packages can not be set to `restricted`.
@@ -192,7 +192,8 @@ exit code.
* Default: "web"
* Type: "legacy" or "web"
-What authentication strategy to use with `login`.
+What authentication strategy to use with `login`. Note that if an `otp`
+config is given, this value will always be set to `legacy`.
#### `before`
@@ -1240,7 +1241,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's `peerDependencies` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If `--strict-peer-deps` is set, then
this warning is treated as a failure.
@@ -1521,7 +1522,7 @@ Alias for `--include=dev`.
`--install-strategy=shallow`
Only install direct dependencies in the top level `node_modules`, but hoist
-on deeper dependendencies. Sets `--install-strategy=shallow`.
+on deeper dependencies. Sets `--install-strategy=shallow`.
#### `init.author.email`
diff --git a/deps/npm/docs/content/using-npm/registry.md b/deps/npm/docs/content/using-npm/registry.md
index 8d5ac94160..035ede5b32 100644
--- a/deps/npm/docs/content/using-npm/registry.md
+++ b/deps/npm/docs/content/using-npm/registry.md
@@ -35,7 +35,7 @@ Authentication configuration such as auth tokens and certificates are configured
specifically scoped to an individual registry. See
[Auth Related Configuration](/configuring-npm/npmrc#auth-related-configuration)
-When the default registry is used in a package-lock or shrinkwrap is has the
+When the default registry is used in a package-lock or shrinkwrap it has the
special meaning of "the currently configured registry". If you create a lock
file while using the default registry you can switch to another registry and
npm will install packages from the new registry, but if you create a lock
diff --git a/deps/npm/docs/content/using-npm/removal.md b/deps/npm/docs/content/using-npm/removal.md
index c5e13b6741..25dbb80baa 100644
--- a/deps/npm/docs/content/using-npm/removal.md
+++ b/deps/npm/docs/content/using-npm/removal.md
@@ -28,8 +28,8 @@ continue reading.
Note that this is only necessary for globally-installed packages. Local
installs are completely contained within a project's `node_modules`
-folder. Delete that folder, and everything is gone less a package's
-install script is particularly ill-behaved).
+folder. Delete that folder, and everything is gone unless a package's
+install script is particularly ill-behaved.
This assumes that you installed node and npm in the default place. If
you configured node with a different `--prefix`, or installed npm with a
diff --git a/deps/npm/docs/content/using-npm/scripts.md b/deps/npm/docs/content/using-npm/scripts.md
index 9bc2bf32fe..bf212c5db2 100644
--- a/deps/npm/docs/content/using-npm/scripts.md
+++ b/deps/npm/docs/content/using-npm/scripts.md
@@ -63,7 +63,7 @@ situations. These scripts happen in addition to the `pre<event>`, `post<event>`,
* Runs BEFORE the package is prepared and packed, ONLY on `npm publish`.
**prepack**
-* Runs BEFORE a tarball is packed (on "`npm pack`", "`npm publish`", and when installing a git dependencies).
+* Runs BEFORE a tarball is packed (on "`npm pack`", "`npm publish`", and when installing a git dependency).
* NOTE: "`npm run pack`" is NOT the same as "`npm pack`". "`npm run pack`" is an arbitrary user defined script name, where as, "`npm pack`" is a CLI defined command.
**postpack**
diff --git a/deps/npm/docs/output/commands/npm-access.html b/deps/npm/docs/output/commands/npm-access.html
index 25569aabc1..9a0bb09a9c 100644
--- a/deps/npm/docs/output/commands/npm-access.html
+++ b/deps/npm/docs/output/commands/npm-access.html
@@ -154,6 +154,7 @@ npm access set mfa=none|publish|automation [&lt;package&gt;]
npm access grant &lt;read-only|read-write&gt; &lt;scope:team&gt; [&lt;package&gt;]
npm access revoke &lt;scope:team&gt; [&lt;package&gt;]
</code></pre>
+<p>Note: This command is unaware of workspaces.</p>
<h3 id="description">Description</h3>
<p>Used to set access controls on private packages.</p>
<p>For all of the subcommands, <code>npm access</code> will perform actions on the packages
diff --git a/deps/npm/docs/output/commands/npm-adduser.html b/deps/npm/docs/output/commands/npm-adduser.html
index 77cde53f2f..e515eaa5ad 100644
--- a/deps/npm/docs/output/commands/npm-adduser.html
+++ b/deps/npm/docs/output/commands/npm-adduser.html
@@ -190,7 +190,8 @@ npm init --scope=@foo --yes
<li>Default: "web"</li>
<li>Type: "legacy" or "web"</li>
</ul>
-<p>What authentication strategy to use with <code>login</code>.</p>
+<p>What authentication strategy to use with <code>login</code>. Note that if an <code>otp</code>
+config is given, this value will always be set to <code>legacy</code>.</p>
<h3 id="see-also">See Also</h3>
<ul>
<li><a href="../using-npm/registry.html">npm registry</a></li>
diff --git a/deps/npm/docs/output/commands/npm-ci.html b/deps/npm/docs/output/commands/npm-ci.html
index 76223e5b47..07f07b5630 100644
--- a/deps/npm/docs/output/commands/npm-ci.html
+++ b/deps/npm/docs/output/commands/npm-ci.html
@@ -256,7 +256,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="omit"><code>omit</code></h4>
<ul>
<li>Default: 'dev' if the <code>NODE_ENV</code> environment variable is set to
@@ -284,7 +284,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-dedupe.html b/deps/npm/docs/output/commands/npm-dedupe.html
index fb457d7d41..143398d8d7 100644
--- a/deps/npm/docs/output/commands/npm-dedupe.html
+++ b/deps/npm/docs/output/commands/npm-dedupe.html
@@ -225,7 +225,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="strict-peer-deps"><code>strict-peer-deps</code></h4>
<ul>
<li>Default: false</li>
@@ -239,7 +239,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-find-dupes.html b/deps/npm/docs/output/commands/npm-find-dupes.html
index d527c5b4f6..0dd2bc3750 100644
--- a/deps/npm/docs/output/commands/npm-find-dupes.html
+++ b/deps/npm/docs/output/commands/npm-find-dupes.html
@@ -182,7 +182,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="strict-peer-deps"><code>strict-peer-deps</code></h4>
<ul>
<li>Default: false</li>
@@ -196,7 +196,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-init.html b/deps/npm/docs/output/commands/npm-init.html
index 0f539a6ad4..e515d36c85 100644
--- a/deps/npm/docs/output/commands/npm-init.html
+++ b/deps/npm/docs/output/commands/npm-init.html
@@ -146,7 +146,7 @@ npm command-line interface
</section>
<div id="_content"><h3 id="synopsis">Synopsis</h3>
-<pre><code class="language-bash">npm init &lt;package-spec&gt; (same as `npx &lt;package-spec&gt;)
+<pre><code class="language-bash">npm init &lt;package-spec&gt; (same as `npx &lt;package-spec&gt;`)
npm init &lt;@scope&gt; (same as `npx &lt;@scope&gt;/create`)
aliases: create, innit
diff --git a/deps/npm/docs/output/commands/npm-install-ci-test.html b/deps/npm/docs/output/commands/npm-install-ci-test.html
index 634d933dc6..0d3dea5b4c 100644
--- a/deps/npm/docs/output/commands/npm-install-ci-test.html
+++ b/deps/npm/docs/output/commands/npm-install-ci-test.html
@@ -213,7 +213,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="omit"><code>omit</code></h4>
<ul>
<li>Default: 'dev' if the <code>NODE_ENV</code> environment variable is set to
@@ -241,7 +241,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-install-test.html b/deps/npm/docs/output/commands/npm-install-test.html
index 282d7755f1..ff53148d4f 100644
--- a/deps/npm/docs/output/commands/npm-install-test.html
+++ b/deps/npm/docs/output/commands/npm-install-test.html
@@ -214,7 +214,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="omit"><code>omit</code></h4>
<ul>
<li>Default: 'dev' if the <code>NODE_ENV</code> environment variable is set to
@@ -242,7 +242,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-install.html b/deps/npm/docs/output/commands/npm-install.html
index 83be6e751e..40dc5d32b3 100644
--- a/deps/npm/docs/output/commands/npm-install.html
+++ b/deps/npm/docs/output/commands/npm-install.html
@@ -540,7 +540,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="omit"><code>omit</code></h4>
<ul>
<li>Default: 'dev' if the <code>NODE_ENV</code> environment variable is set to
@@ -568,7 +568,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-link.html b/deps/npm/docs/output/commands/npm-link.html
index bf6e7f9a2f..d23f83826a 100644
--- a/deps/npm/docs/output/commands/npm-link.html
+++ b/deps/npm/docs/output/commands/npm-link.html
@@ -277,7 +277,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="strict-peer-deps"><code>strict-peer-deps</code></h4>
<ul>
<li>Default: false</li>
@@ -291,7 +291,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm-login.html b/deps/npm/docs/output/commands/npm-login.html
index 8b47a64c8e..5ffff8aa62 100644
--- a/deps/npm/docs/output/commands/npm-login.html
+++ b/deps/npm/docs/output/commands/npm-login.html
@@ -194,7 +194,8 @@ npm init --scope=@foo --yes
<li>Default: "web"</li>
<li>Type: "legacy" or "web"</li>
</ul>
-<p>What authentication strategy to use with <code>login</code>.</p>
+<p>What authentication strategy to use with <code>login</code>. Note that if an <code>otp</code>
+config is given, this value will always be set to <code>legacy</code>.</p>
<h3 id="see-also">See Also</h3>
<ul>
<li><a href="../using-npm/registry.html">npm registry</a></li>
diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html
index 6ec045612f..ffe72db7c5 100644
--- a/deps/npm/docs/output/commands/npm-ls.html
+++ b/deps/npm/docs/output/commands/npm-ls.html
@@ -160,7 +160,7 @@ tree at all, use <a href="../commands/npm-explain.html"><code>npm explain</code>
the results to only the paths to the packages named. Note that nested
packages will <em>also</em> show the paths to the specified packages. For
example, running <code>npm ls promzard</code> in npm's source tree will show:</p>
-<pre><code class="language-bash">npm@9.2.0 /path/to/npm
+<pre><code class="language-bash">npm@9.3.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
</code></pre>
diff --git a/deps/npm/docs/output/commands/npm-owner.html b/deps/npm/docs/output/commands/npm-owner.html
index 13cf1d2209..3566602a01 100644
--- a/deps/npm/docs/output/commands/npm-owner.html
+++ b/deps/npm/docs/output/commands/npm-owner.html
@@ -152,7 +152,6 @@ npm owner ls &lt;package-spec&gt;
alias: author
</code></pre>
-<p>Note: This command is unaware of workspaces.</p>
<h3 id="description">Description</h3>
<p>Manage ownership of published packages.</p>
<ul>
diff --git a/deps/npm/docs/output/commands/npm-publish.html b/deps/npm/docs/output/commands/npm-publish.html
index 864a03a5cb..80a136308a 100644
--- a/deps/npm/docs/output/commands/npm-publish.html
+++ b/deps/npm/docs/output/commands/npm-publish.html
@@ -235,8 +235,8 @@ tarball that will be compared with the local files by default.</p>
current level</li>
<li>Type: null, "restricted", or "public"</li>
</ul>
-<p>If do not want your scoped package to be publicly viewable (and installable)
-set <code>--access=restricted</code>.</p>
+<p>If you do not want your scoped package to be publicly viewable (and
+installable) set <code>--access=restricted</code>.</p>
<p>Unscoped packages can not be set to <code>restricted</code>.</p>
<p>Note: This defaults to not changing the current access level for existing
packages. Specifying a value of <code>restricted</code> or <code>public</code> during publish will
diff --git a/deps/npm/docs/output/commands/npm-root.html b/deps/npm/docs/output/commands/npm-root.html
index 292376737f..24436056c9 100644
--- a/deps/npm/docs/output/commands/npm-root.html
+++ b/deps/npm/docs/output/commands/npm-root.html
@@ -148,6 +148,7 @@ npm command-line interface
<div id="_content"><h3 id="synopsis">Synopsis</h3>
<pre><code class="language-bash">npm root
</code></pre>
+<p>Note: This command is unaware of workspaces.</p>
<h3 id="description">Description</h3>
<p>Print the effective <code>node_modules</code> folder to standard out.</p>
<p>Useful for using npm in shell scripts that do things with the
diff --git a/deps/npm/docs/output/commands/npm-update.html b/deps/npm/docs/output/commands/npm-update.html
index fbb1e8c133..162eb4fe54 100644
--- a/deps/npm/docs/output/commands/npm-update.html
+++ b/deps/npm/docs/output/commands/npm-update.html
@@ -304,7 +304,7 @@ de-duplicating. Sets <code>--install-strategy=nested</code>.</p>
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="omit"><code>omit</code></h4>
<ul>
<li>Default: 'dev' if the <code>NODE_ENV</code> environment variable is set to
@@ -332,7 +332,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="package-lock"><code>package-lock</code></h4>
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html
index 94fb3e2168..cb6d4ea3c7 100644
--- a/deps/npm/docs/output/commands/npm.html
+++ b/deps/npm/docs/output/commands/npm.html
@@ -148,8 +148,9 @@ npm command-line interface
<div id="_content"><h3 id="synopsis">Synopsis</h3>
<pre><code class="language-bash">npm
</code></pre>
+<p>Note: This command is unaware of workspaces.</p>
<h3 id="version">Version</h3>
-<p>9.2.0</p>
+<p>9.3.0</p>
<h3 id="description">Description</h3>
<p>npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
@@ -247,7 +248,7 @@ more info on the global prefix. If the <code>globalconfig</code> option is set
in the cli, env, or user config, then that file is parsed instead.</li>
<li>Defaults:
npm's default configuration options are defined in
-lib/utils/config-defs.js. These must not be changed.</li>
+<code>lib/utils/config/definitions.js</code>. These must not be changed.</li>
</ul>
<p>See <a href="../using-npm/config.html"><code>config</code></a> for much much more information.</p>
<h3 id="contributions">Contributions</h3>
diff --git a/deps/npm/docs/output/configuring-npm/install.html b/deps/npm/docs/output/configuring-npm/install.html
index b5aabb23b1..7acebd7fda 100644
--- a/deps/npm/docs/output/configuring-npm/install.html
+++ b/deps/npm/docs/output/configuring-npm/install.html
@@ -155,11 +155,11 @@ directory with local permissions and can cause permissions errors when you
run npm packages globally.</p>
<h3 id="overview">Overview</h3>
<ul>
-<li><a href="#checking-your-version-of-npm-and-node-js">Checking your version of npm and
+<li><a href="#checking-your-version-of-npm-and-nodejs">Checking your version of npm and
Node.js</a></li>
-<li><a href="#using-a-node-version-manager-to-install-node-js-and-npm">Using a Node version manager to install Node.js and
+<li><a href="#using-a-node-version-manager-to-install-nodejs-and-npm">Using a Node version manager to install Node.js and
npm</a></li>
-<li><a href="#using-a-node-installer-to-install-node-js-and-npm">Using a Node installer to install Node.js and
+<li><a href="#using-a-node-installer-to-install-nodejs-and-npm">Using a Node installer to install Node.js and
npm</a></li>
</ul>
<h3 id="checking-your-version-of-npm-and-nodejs">Checking your version of npm and Node.js</h3>
diff --git a/deps/npm/docs/output/using-npm/config.html b/deps/npm/docs/output/using-npm/config.html
index 0a31adb6c4..35bc3529ef 100644
--- a/deps/npm/docs/output/using-npm/config.html
+++ b/deps/npm/docs/output/using-npm/config.html
@@ -261,8 +261,8 @@ safer to use a registry-provided authentication bearer token stored in the
current level</li>
<li>Type: null, "restricted", or "public"</li>
</ul>
-<p>If do not want your scoped package to be publicly viewable (and installable)
-set <code>--access=restricted</code>.</p>
+<p>If you do not want your scoped package to be publicly viewable (and
+installable) set <code>--access=restricted</code>.</p>
<p>Unscoped packages can not be set to <code>restricted</code>.</p>
<p>Note: This defaults to not changing the current access level for existing
packages. Specifying a value of <code>restricted</code> or <code>public</code> during publish will
@@ -303,7 +303,8 @@ exit code.</p>
<li>Default: "web"</li>
<li>Type: "legacy" or "web"</li>
</ul>
-<p>What authentication strategy to use with <code>login</code>.</p>
+<p>What authentication strategy to use with <code>login</code>. Note that if an <code>otp</code>
+config is given, this value will always be set to <code>legacy</code>.</p>
<h4 id="before"><code>before</code></h4>
<ul>
<li>Default: null</li>
@@ -1181,7 +1182,7 @@ dependency relationships.</p>
be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's <code>peerDependencies</code> object.</p>
-<p>When such and override is performed, a warning is printed, explaining the
+<p>When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If <code>--strict-peer-deps</code> is set, then
this warning is treated as a failure.</p>
<h4 id="strict-ssl"><code>strict-ssl</code></h4>
@@ -1420,7 +1421,7 @@ registry-scoped "certfile" path like
<code>--install-strategy=shallow</code></li>
</ul>
<p>Only install direct dependencies in the top level <code>node_modules</code>, but hoist
-on deeper dependendencies. Sets <code>--install-strategy=shallow</code>.</p>
+on deeper dependencies. Sets <code>--install-strategy=shallow</code>.</p>
<h4 id="initauthoremail"><code>init.author.email</code></h4>
<ul>
<li>Default: ""</li>
diff --git a/deps/npm/docs/output/using-npm/registry.html b/deps/npm/docs/output/using-npm/registry.html
index 0d04f4dd82..8ff40109fe 100644
--- a/deps/npm/docs/output/using-npm/registry.html
+++ b/deps/npm/docs/output/using-npm/registry.html
@@ -169,7 +169,7 @@ managing npm's configuration.
Authentication configuration such as auth tokens and certificates are configured
specifically scoped to an individual registry. See
<a href="../configuring-npm/npmrc#auth-related-configuration.html">Auth Related Configuration</a></p>
-<p>When the default registry is used in a package-lock or shrinkwrap is has the
+<p>When the default registry is used in a package-lock or shrinkwrap it has the
special meaning of "the currently configured registry". If you create a lock
file while using the default registry you can switch to another registry and
npm will install packages from the new registry, but if you create a lock
diff --git a/deps/npm/docs/output/using-npm/removal.html b/deps/npm/docs/output/using-npm/removal.html
index 7e9af7040b..e54187122e 100644
--- a/deps/npm/docs/output/using-npm/removal.html
+++ b/deps/npm/docs/output/using-npm/removal.html
@@ -159,8 +159,8 @@ npm, but leave behind anything you've installed.</p>
continue reading.</p>
<p>Note that this is only necessary for globally-installed packages. Local
installs are completely contained within a project's <code>node_modules</code>
-folder. Delete that folder, and everything is gone less a package's
-install script is particularly ill-behaved).</p>
+folder. Delete that folder, and everything is gone unless a package's
+install script is particularly ill-behaved.</p>
<p>This assumes that you installed node and npm in the default place. If
you configured node with a different <code>--prefix</code>, or installed npm with a
different prefix setting, then adjust the paths accordingly, replacing
diff --git a/deps/npm/docs/output/using-npm/scripts.html b/deps/npm/docs/output/using-npm/scripts.html
index 79e14dc027..6cc14bff7a 100644
--- a/deps/npm/docs/output/using-npm/scripts.html
+++ b/deps/npm/docs/output/using-npm/scripts.html
@@ -208,7 +208,7 @@ and <code>npm install</code>. See below for more info.</li>
</ul>
<p><strong>prepack</strong></p>
<ul>
-<li>Runs BEFORE a tarball is packed (on "<code>npm pack</code>", "<code>npm publish</code>", and when installing a git dependencies).</li>
+<li>Runs BEFORE a tarball is packed (on "<code>npm pack</code>", "<code>npm publish</code>", and when installing a git dependency).</li>
<li>NOTE: "<code>npm run pack</code>" is NOT the same as "<code>npm pack</code>". "<code>npm run pack</code>" is an arbitrary user defined script name, where as, "<code>npm pack</code>" is a CLI defined command.</li>
</ul>
<p><strong>postpack</strong></p>
diff --git a/deps/npm/lib/arborist-cmd.js b/deps/npm/lib/arborist-cmd.js
index 29efe984d9..42699ece36 100644
--- a/deps/npm/lib/arborist-cmd.js
+++ b/deps/npm/lib/arborist-cmd.js
@@ -17,22 +17,35 @@ class ArboristCmd extends BaseCommand {
'install-links',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
constructor (npm) {
super(npm)
- if (this.npm.config.isDefault('audit')
- && (this.npm.global || this.npm.config.get('location') !== 'project')
- ) {
- this.npm.config.set('audit', false)
- } else if (this.npm.global && this.npm.config.get('audit')) {
- log.warn('config',
- 'includes both --global and --audit, which is currently unsupported.')
+
+ const { config } = this.npm
+
+ // when location isn't set and global isn't true check for a package.json at
+ // the localPrefix and set the location to project if found
+ const locationProject = config.get('location') === 'project' || (
+ config.isDefault('location')
+ // this is different then `npm.global` which falls back to checking
+ // location which we do not want to use here
+ && !config.get('global')
+ && npm.localPackage
+ )
+
+ // if audit is not set and we are in global mode and location is not project
+ // and we assume its not a project related context, then we set audit=false
+ if (config.isDefault('audit') && (this.npm.global || !locationProject)) {
+ config.set('audit', false)
+ } else if (this.npm.global && config.get('audit')) {
+ log.warn('config', 'includes both --global and --audit, which is currently unsupported.')
}
}
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
return this.exec(args)
}
}
diff --git a/deps/npm/lib/base-command.js b/deps/npm/lib/base-command.js
index b57b7474a5..0adff8e5d9 100644
--- a/deps/npm/lib/base-command.js
+++ b/deps/npm/lib/base-command.js
@@ -8,12 +8,21 @@ const getWorkspaces = require('./workspaces/get-workspaces.js')
const cmdAliases = require('./utils/cmd-list').aliases
class BaseCommand {
+ static workspaces = false
+ static ignoreImplicitWorkspace = true
+
constructor (npm) {
this.wrapWidth = 80
this.npm = npm
- if (!this.skipConfigValidation) {
- this.npm.config.validate()
+ const { config } = this.npm
+
+ if (!this.constructor.skipConfigValidation) {
+ config.validate()
+ }
+
+ if (config.get('workspaces') === false && config.get('workspace').length) {
+ throw new Error('Can not use --no-workspaces and --workspace at the same time')
}
}
@@ -25,35 +34,31 @@ class BaseCommand {
return this.constructor.description
}
- get ignoreImplicitWorkspace () {
- return this.constructor.ignoreImplicitWorkspace
- }
-
- get skipConfigValidation () {
- return this.constructor.skipConfigValidation
+ get params () {
+ return this.constructor.params
}
get usage () {
const usage = [
- `${this.constructor.description}`,
+ `${this.description}`,
'',
'Usage:',
]
if (!this.constructor.usage) {
- usage.push(`npm ${this.constructor.name}`)
+ usage.push(`npm ${this.name}`)
} else {
- usage.push(...this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`))
+ usage.push(...this.constructor.usage.map(u => `npm ${this.name} ${u}`))
}
- if (this.constructor.params) {
+ if (this.params) {
usage.push('')
usage.push('Options:')
usage.push(this.wrappedParams)
}
const aliases = Object.keys(cmdAliases).reduce((p, c) => {
- if (cmdAliases[c] === this.constructor.name) {
+ if (cmdAliases[c] === this.name) {
p.push(c)
}
return p
@@ -68,7 +73,7 @@ class BaseCommand {
}
usage.push('')
- usage.push(`Run "npm help ${this.constructor.name}" for more info`)
+ usage.push(`Run "npm help ${this.name}" for more info`)
return usage.join('\n')
}
@@ -77,7 +82,7 @@ class BaseCommand {
let results = ''
let line = ''
- for (const param of this.constructor.params) {
+ for (const param of this.params) {
const usage = `[${ConfigDefinitions[param].usage}]`
if (line.length && line.length + usage.length > this.wrapWidth) {
results = [results, line].filter(Boolean).join('\n')
@@ -98,26 +103,48 @@ class BaseCommand {
})
}
- async execWorkspaces (args, filters) {
- throw Object.assign(new Error('This command does not support workspaces.'), {
- code: 'ENOWORKSPACES',
- })
- }
+ async cmdExec (args) {
+ const { config } = this.npm
- async setWorkspaces (filters) {
- if (this.isArboristCmd) {
- this.includeWorkspaceRoot = false
+ if (config.get('usage')) {
+ return this.npm.output(this.usage)
}
- const relativeFrom = relative(this.npm.localPrefix, process.cwd()).startsWith('..')
- ? this.npm.localPrefix
- : process.cwd()
+ const hasWsConfig = config.get('workspaces') || config.get('workspace').length
+ // if cwd is a workspace, the default is set to [that workspace]
+ const implicitWs = config.get('workspace', 'default').length
+ // (-ws || -w foo) && (cwd is not a workspace || command is not ignoring implicit workspaces)
+ if (hasWsConfig && (!implicitWs || !this.constructor.ignoreImplicitWorkspace)) {
+ if (this.npm.global) {
+ throw new Error('Workspaces not supported for global packages')
+ }
+ if (!this.constructor.workspaces) {
+ throw Object.assign(new Error('This command does not support workspaces.'), {
+ code: 'ENOWORKSPACES',
+ })
+ }
+ return this.execWorkspaces(args)
+ }
+
+ return this.exec(args)
+ }
+
+ async setWorkspaces () {
+ const includeWorkspaceRoot = this.isArboristCmd
+ ? false
+ : this.npm.config.get('include-workspace-root')
+
+ const prefixInsideCwd = relative(this.npm.localPrefix, process.cwd()).startsWith('..')
+ const relativeFrom = prefixInsideCwd ? this.npm.localPrefix : process.cwd()
+
+ const filters = this.npm.config.get('workspace')
const ws = await getWorkspaces(filters, {
path: this.npm.localPrefix,
- includeWorkspaceRoot: this.includeWorkspaceRoot,
+ includeWorkspaceRoot,
relativeFrom,
})
+
this.workspaces = ws
this.workspaceNames = [...ws.keys()]
this.workspacePaths = [...ws.values()]
diff --git a/deps/npm/lib/cli.js b/deps/npm/lib/cli.js
index 9aaf6c5936..007778aa4b 100644
--- a/deps/npm/lib/cli.js
+++ b/deps/npm/lib/cli.js
@@ -68,6 +68,11 @@ module.exports = async process => {
// leak any private CLI configs to other programs
process.title = 'npm'
+ // if npm is called as "npmg" or "npm_g", then run in global mode.
+ if (process.argv[1][process.argv[1].length - 1] === 'g') {
+ process.argv.splice(1, 1, 'npm', '-g')
+ }
+
// Nothing should happen before this line if we can't guarantee it will
// not have syntax errors in some version of node
const validateEngines = createEnginesValidation()
@@ -78,11 +83,6 @@ module.exports = async process => {
const npm = new Npm()
exitHandler.setNpm(npm)
- // if npm is called as "npmg" or "npm_g", then run in global mode.
- if (process.argv[1][process.argv[1].length - 1] === 'g') {
- process.argv.splice(1, 1, 'npm', '-g')
- }
-
// only log node and npm paths in argv initially since argv can contain
// sensitive info. a cleaned version will be logged later
const log = require('./utils/log-shim.js')
@@ -112,6 +112,7 @@ module.exports = async process => {
// this is how to use npm programmatically:
try {
await npm.load()
+
if (npm.config.get('version', 'cli')) {
npm.output(npm.version)
return exitHandler()
@@ -130,7 +131,7 @@ module.exports = async process => {
return exitHandler()
}
- await npm.exec(cmd, npm.argv)
+ await npm.exec(cmd)
return exitHandler()
} catch (err) {
if (err.code === 'EUNKNOWNCOMMAND') {
diff --git a/deps/npm/lib/commands/access.js b/deps/npm/lib/commands/access.js
index d5ac5bb2f0..23e51f071b 100644
--- a/deps/npm/lib/commands/access.js
+++ b/deps/npm/lib/commands/access.js
@@ -37,8 +37,6 @@ class Access extends BaseCommand {
'registry',
]
- static ignoreImplicitWorkspace = true
-
static usage = [
'list packages [<user>|<scope>|<scope:team> [<package>]',
'list collaborators [<package> [<user>]]',
diff --git a/deps/npm/lib/commands/adduser.js b/deps/npm/lib/commands/adduser.js
index 1e92b35f4a..cd4cba6051 100644
--- a/deps/npm/lib/commands/adduser.js
+++ b/deps/npm/lib/commands/adduser.js
@@ -13,8 +13,6 @@ class AddUser extends BaseCommand {
'auth-type',
]
- static ignoreImplicitWorkspace = true
-
async exec (args) {
const scope = this.npm.config.get('scope')
let registry = this.npm.config.get('registry')
diff --git a/deps/npm/lib/commands/audit.js b/deps/npm/lib/commands/audit.js
index feccefda0c..13886ea635 100644
--- a/deps/npm/lib/commands/audit.js
+++ b/deps/npm/lib/commands/audit.js
@@ -152,7 +152,7 @@ class VerifySignatures {
const keys = await fetch.json('/-/npm/v1/keys', {
...this.npm.flatOptions,
registry,
- }).then(({ keys }) => keys.map((key) => ({
+ }).then(({ keys: ks }) => ks.map((key) => ({
...key,
pemkey: `-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`,
}))).catch(err => {
diff --git a/deps/npm/lib/commands/cache.js b/deps/npm/lib/commands/cache.js
index a2e6434b34..0ab40b9ed4 100644
--- a/deps/npm/lib/commands/cache.js
+++ b/deps/npm/lib/commands/cache.js
@@ -1,9 +1,8 @@
const cacache = require('cacache')
const Arborist = require('@npmcli/arborist')
-const { promisify } = require('util')
const pacote = require('pacote')
-const path = require('path')
-const rimraf = promisify(require('rimraf'))
+const fs = require('fs/promises')
+const { join } = require('path')
const semver = require('semver')
const BaseCommand = require('../base-command.js')
const npa = require('npm-package-arg')
@@ -75,8 +74,6 @@ class Cache extends BaseCommand {
'verify',
]
- static ignoreImplicitWorkspace = true
-
async completion (opts) {
const argv = opts.conf.argv.remain
if (argv.length === 2) {
@@ -112,7 +109,7 @@ class Cache extends BaseCommand {
// npm cache clean [pkg]*
async clean (args) {
- const cachePath = path.join(this.npm.cache, '_cacache')
+ const cachePath = join(this.npm.cache, '_cacache')
if (args.length === 0) {
if (!this.npm.config.get('force')) {
throw new Error(`As of npm@5, the npm cache self-heals from corruption issues
@@ -130,7 +127,7 @@ class Cache extends BaseCommand {
If you're sure you want to delete the entire cache, rerun this command
with --force.`)
}
- return rimraf(cachePath)
+ return fs.rm(cachePath, { recursive: true, force: true })
}
for (const key of args) {
let entry
@@ -170,7 +167,7 @@ class Cache extends BaseCommand {
}
async verify () {
- const cache = path.join(this.npm.cache, '_cacache')
+ const cache = join(this.npm.cache, '_cacache')
const prefix = cache.indexOf(process.env.HOME) === 0
? `~${cache.slice(process.env.HOME.length)}`
: cache
@@ -193,7 +190,7 @@ class Cache extends BaseCommand {
// npm cache ls [--package <spec> ...]
async ls (specs) {
- const cachePath = path.join(this.npm.cache, '_cacache')
+ const cachePath = join(this.npm.cache, '_cacache')
const cacheKeys = Object.keys(await cacache.ls(cachePath))
if (specs.length > 0) {
// get results for each package spec specified
diff --git a/deps/npm/lib/commands/ci.js b/deps/npm/lib/commands/ci.js
index 38ee1426d9..a2c61044eb 100644
--- a/deps/npm/lib/commands/ci.js
+++ b/deps/npm/lib/commands/ci.js
@@ -1,10 +1,7 @@
-const util = require('util')
const Arborist = require('@npmcli/arborist')
-const rimraf = util.promisify(require('rimraf'))
const reifyFinish = require('../utils/reify-finish.js')
const runScript = require('@npmcli/run-script')
-const fs = require('fs')
-const readdir = util.promisify(fs.readdir)
+const fs = require('fs/promises')
const log = require('../utils/log-shim.js')
const validateLockfile = require('../utils/validate-lockfile.js')
@@ -69,8 +66,8 @@ class CI extends ArboristWorkspaceCmd {
await this.npm.time('npm-ci:rm', async () => {
const path = `${where}/node_modules`
// get the list of entries so we can skip the glob for performance
- const entries = await readdir(path, null).catch(er => [])
- return Promise.all(entries.map(f => rimraf(`${path}/${f}`, { glob: false })))
+ const entries = await fs.readdir(path, null).catch(er => [])
+ return Promise.all(entries.map(f => fs.rm(`${path}/${f}`, { force: true })))
})
await arb.reify(opts)
diff --git a/deps/npm/lib/commands/completion.js b/deps/npm/lib/commands/completion.js
index 8fc05b2e82..f5604e099f 100644
--- a/deps/npm/lib/commands/completion.js
+++ b/deps/npm/lib/commands/completion.js
@@ -31,6 +31,7 @@
const fs = require('fs/promises')
const nopt = require('nopt')
+const { resolve } = require('path')
const { definitions, shorthands } = require('../utils/config/index.js')
const { aliases, commands, plumbing } = require('../utils/cmd-list.js')
@@ -40,21 +41,13 @@ const configNames = Object.keys(definitions)
const shorthandNames = Object.keys(shorthands)
const allConfs = configNames.concat(shorthandNames)
const { isWindowsShell } = require('../utils/is-windows.js')
-const fileExists = async (file) => {
- try {
- const stat = await fs.stat(file)
- return stat.isFile()
- } catch {
- return false
- }
-}
+const fileExists = (file) => fs.stat(file).then(s => s.isFile()).catch(() => false)
const BaseCommand = require('../base-command.js')
class Completion extends BaseCommand {
static description = 'Tab Completion for npm'
static name = 'completion'
- static ignoreImplicitWorkspace = true
// completion for the completion command
async completion (opts) {
@@ -62,7 +55,6 @@ class Completion extends BaseCommand {
return
}
- const { resolve } = require('path')
const [bashExists, zshExists] = await Promise.all([
fileExists(resolve(process.env.HOME, '.bashrc')),
fileExists(resolve(process.env.HOME, '.zshrc')),
@@ -93,7 +85,7 @@ class Completion extends BaseCommand {
if (COMP_CWORD === undefined ||
COMP_LINE === undefined ||
COMP_POINT === undefined) {
- return dumpScript()
+ return dumpScript(resolve(this.npm.npmRoot, 'lib', 'utils', 'completion.sh'))
}
// ok we're actually looking at the envs and outputting the suggestions
@@ -150,9 +142,9 @@ class Completion extends BaseCommand {
// take a little shortcut and use npm's arg parsing logic.
// don't have to worry about the last arg being implicitly
// boolean'ed, since the last block will catch that.
- const types = Object.entries(definitions).reduce((types, [key, def]) => {
- types[key] = def.type
- return types
+ const types = Object.entries(definitions).reduce((acc, [key, def]) => {
+ acc[key] = def.type
+ return acc
}, {})
const parsed = opts.conf =
nopt(types, shorthands, partialWords.slice(0, -1), 0)
@@ -196,10 +188,7 @@ class Completion extends BaseCommand {
}
}
-const dumpScript = async () => {
- const { resolve } = require('path')
- const p = resolve(__dirname, '..', 'utils', 'completion.sh')
-
+const dumpScript = async (p) => {
const d = (await fs.readFile(p, 'utf8')).replace(/^#!.*?\n/, '')
await new Promise((res, rej) => {
let done = false
diff --git a/deps/npm/lib/commands/config.js b/deps/npm/lib/commands/config.js
index 103fbb554e..ac5a74d01f 100644
--- a/deps/npm/lib/commands/config.js
+++ b/deps/npm/lib/commands/config.js
@@ -112,11 +112,6 @@ class Config extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
- log.warn('config', 'This command does not support workspaces.')
- return this.exec(args)
- }
-
async exec ([action, ...args]) {
log.disableProgress()
try {
@@ -251,14 +246,14 @@ ${defData}
`.split('\n').join(EOL)
await mkdir(dirname(file), { recursive: true })
await writeFile(file, tmpData, 'utf8')
- await new Promise((resolve, reject) => {
+ await new Promise((res, rej) => {
const [bin, ...args] = e.split(/\s+/)
const editor = spawn(bin, [...args, file], { stdio: 'inherit' })
editor.on('exit', (code) => {
if (code) {
- return reject(new Error(`editor process exited with code: ${code}`))
+ return rej(new Error(`editor process exited with code: ${code}`))
}
- return resolve()
+ return res()
})
})
}
diff --git a/deps/npm/lib/commands/diff.js b/deps/npm/lib/commands/diff.js
index c8fd734918..1f4bfd3eb1 100644
--- a/deps/npm/lib/commands/diff.js
+++ b/deps/npm/lib/commands/diff.js
@@ -32,6 +32,7 @@ class Diff extends BaseCommand {
'include-workspace-root',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
async exec (args) {
@@ -67,8 +68,8 @@ class Diff extends BaseCommand {
return this.npm.output(res)
}
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
for (const workspacePath of this.workspacePaths) {
this.top = workspacePath
this.prefix = workspacePath
diff --git a/deps/npm/lib/commands/dist-tag.js b/deps/npm/lib/commands/dist-tag.js
index 8052e4f7e4..bc61a4691e 100644
--- a/deps/npm/lib/commands/dist-tag.js
+++ b/deps/npm/lib/commands/dist-tag.js
@@ -17,6 +17,7 @@ class DistTag extends BaseCommand {
'ls [<package-spec>]',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
async completion (opts) {
@@ -57,14 +58,14 @@ class DistTag extends BaseCommand {
}
}
- async execWorkspaces ([cmdName, pkg, tag], filters) {
+ async execWorkspaces ([cmdName, pkg, tag]) {
// cmdName is some form of list
// pkg is one of:
// - unset
// - .
// - .@version
if (['ls', 'l', 'sl', 'list'].includes(cmdName) && (!pkg || pkg === '.' || /^\.@/.test(pkg))) {
- return this.listWorkspaces(filters)
+ return this.listWorkspaces()
}
// pkg is unset
@@ -73,12 +74,12 @@ class DistTag extends BaseCommand {
// - .
// - .@version
if (!pkg && (!cmdName || cmdName === '.' || /^\.@/.test(cmdName))) {
- return this.listWorkspaces(filters)
+ return this.listWorkspaces()
}
// anything else is just a regular dist-tag command
// so we fallback to the non-workspaces implementation
- log.warn('Ignoring workspaces for specified package')
+ log.warn('dist-tag', 'Ignoring workspaces for specified package')
return this.exec([cmdName, pkg, tag])
}
@@ -116,7 +117,7 @@ class DistTag extends BaseCommand {
},
spec,
}
- await otplease(this.npm, reqOpts, reqOpts => regFetch(url, reqOpts))
+ await otplease(this.npm, reqOpts, o => regFetch(url, o))
this.npm.output(`+${t}: ${spec.name}@${version}`)
}
@@ -142,7 +143,7 @@ class DistTag extends BaseCommand {
method: 'DELETE',
spec,
}
- await otplease(this.npm, reqOpts, reqOpts => regFetch(url, reqOpts))
+ await otplease(this.npm, reqOpts, o => regFetch(url, o))
this.npm.output(`-${tag}: ${spec.name}@${version}`)
}
@@ -172,8 +173,8 @@ class DistTag extends BaseCommand {
}
}
- async listWorkspaces (filters) {
- await this.setWorkspaces(filters)
+ async listWorkspaces () {
+ await this.setWorkspaces()
for (const name of this.workspaceNames) {
try {
diff --git a/deps/npm/lib/commands/edit.js b/deps/npm/lib/commands/edit.js
index 67ac32e017..a671a5d6ba 100644
--- a/deps/npm/lib/commands/edit.js
+++ b/deps/npm/lib/commands/edit.js
@@ -51,23 +51,23 @@ class Edit extends BaseCommand {
const dir = resolve(this.npm.dir, path)
// graceful-fs does not promisify
- await new Promise((resolve, reject) => {
+ await new Promise((res, rej) => {
fs.lstat(dir, (err) => {
if (err) {
- return reject(err)
+ return rej(err)
}
- const [bin, ...args] = this.npm.config.get('editor').split(/\s+/)
- const editor = cp.spawn(bin, [...args, dir], { stdio: 'inherit' })
+ const [bin, ...spawnArgs] = this.npm.config.get('editor').split(/\s+/)
+ const editor = cp.spawn(bin, [...spawnArgs, dir], { stdio: 'inherit' })
editor.on('exit', async (code) => {
if (code) {
- return reject(new Error(`editor process exited with code: ${code}`))
+ return rej(new Error(`editor process exited with code: ${code}`))
}
try {
await this.npm.exec('rebuild', [dir])
- } catch (err) {
- reject(err)
+ } catch (execErr) {
+ rej(execErr)
}
- resolve()
+ res()
})
})
})
diff --git a/deps/npm/lib/commands/exec.js b/deps/npm/lib/commands/exec.js
index a77a6326c0..a5235c7845 100644
--- a/deps/npm/lib/commands/exec.js
+++ b/deps/npm/lib/commands/exec.js
@@ -1,4 +1,4 @@
-const path = require('path')
+const { resolve } = require('path')
const libexec = require('libnpmexec')
const BaseCommand = require('../base-command.js')
@@ -20,10 +20,25 @@ class Exec extends BaseCommand {
'--package=foo -c \'<cmd> [args...]\'',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
static isShellout = true
- async exec (_args, { locationMsg, runPath } = {}) {
+ async exec (args) {
+ return this.callExec(args)
+ }
+
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
+
+ for (const [name, path] of this.workspaces) {
+ const locationMsg =
+ `in workspace ${this.npm.chalk.green(name)} at location:\n${this.npm.chalk.dim(path)}`
+ await this.callExec(args, { locationMsg, runPath: path })
+ }
+ }
+
+ async callExec (args, { locationMsg, runPath } = {}) {
// This is where libnpmexec will look for locally installed packages
const localPrefix = this.npm.localPrefix
@@ -32,7 +47,6 @@ class Exec extends BaseCommand {
runPath = process.cwd()
}
- const args = [..._args]
const call = this.npm.config.get('call')
let globalPath
const {
@@ -49,10 +63,10 @@ class Exec extends BaseCommand {
// is invalid (i.e. no lib/node_modules). This is not a trivial thing to
// untangle and fix so we work around it here.
if (this.npm.localPrefix !== this.npm.globalPrefix) {
- globalPath = path.resolve(globalDir, '..')
+ globalPath = resolve(globalDir, '..')
}
- if (call && _args.length) {
+ if (call && args.length) {
throw this.usageError()
}
@@ -61,7 +75,8 @@ class Exec extends BaseCommand {
// we explicitly set packageLockOnly to false because if it's true
// when we try to install a missing package, we won't actually install it
packageLockOnly: false,
- args,
+ // copy args so they dont get mutated
+ args: [...args],
call,
localBin,
locationMsg,
@@ -75,16 +90,6 @@ class Exec extends BaseCommand {
yes,
})
}
-
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
-
- for (const [name, path] of this.workspaces) {
- const locationMsg =
- `in workspace ${this.npm.chalk.green(name)} at location:\n${this.npm.chalk.dim(path)}`
- await this.exec(args, { locationMsg, runPath: path })
- }
- }
}
module.exports = Exec
diff --git a/deps/npm/lib/commands/find-dupes.js b/deps/npm/lib/commands/find-dupes.js
index b99ea7a14e..b1a3120860 100644
--- a/deps/npm/lib/commands/find-dupes.js
+++ b/deps/npm/lib/commands/find-dupes.js
@@ -18,7 +18,7 @@ class FindDupes extends ArboristWorkspaceCmd {
...super.params,
]
- async exec (args, cb) {
+ async exec (args) {
this.npm.config.set('dry-run', true)
return this.npm.exec('dedupe', [])
}
diff --git a/deps/npm/lib/commands/fund.js b/deps/npm/lib/commands/fund.js
index 9690cbc32e..12762533c1 100644
--- a/deps/npm/lib/commands/fund.js
+++ b/deps/npm/lib/commands/fund.js
@@ -16,12 +16,27 @@ const getPrintableName = ({ name, version }) => {
return `${name}${printableVersion}`
}
+const errCode = (msg, code) => Object.assign(new Error(msg), { code })
+
class Fund extends ArboristWorkspaceCmd {
static description = 'Retrieve funding information'
static name = 'fund'
static params = ['json', 'browser', 'unicode', 'workspace', 'which']
static usage = ['[<package-spec>]']
+ // XXX: maybe worth making this generic for all commands?
+ usageMessage (paramsObj = {}) {
+ let msg = `\`npm ${this.constructor.name}`
+ const params = Object.entries(paramsObj)
+ if (params.length) {
+ msg += ` ${this.constructor.usage}`
+ }
+ for (const [key, value] of params) {
+ msg += ` --${key}=${value}`
+ }
+ return `${msg}\``
+ }
+
// TODO
/* istanbul ignore next */
async completion (opts) {
@@ -30,25 +45,23 @@ class Fund extends ArboristWorkspaceCmd {
async exec (args) {
const spec = args[0]
- const numberArg = this.npm.config.get('which')
- const fundingSourceNumber = numberArg && parseInt(numberArg, 10)
-
- const badFundingSourceNumber =
- numberArg !== null && (String(fundingSourceNumber) !== numberArg || fundingSourceNumber < 1)
-
- if (badFundingSourceNumber) {
- const err = new Error(
- '`npm fund [<@scope>/]<pkg> [--which=fundingSourceNumber]` must be given a positive integer'
- )
- err.code = 'EFUNDNUMBER'
- throw err
+ let fundingSourceNumber = this.npm.config.get('which')
+ if (fundingSourceNumber != null) {
+ fundingSourceNumber = parseInt(fundingSourceNumber, 10)
+ if (isNaN(fundingSourceNumber) || fundingSourceNumber < 1) {
+ throw errCode(
+ `${this.usageMessage({ which: 'fundingSourceNumber' })} must be given a positive integer`,
+ 'EFUNDNUMBER'
+ )
+ }
}
if (this.npm.global) {
- const err = new Error('`npm fund` does not support global packages')
- err.code = 'EFUNDGLOBAL'
- throw err
+ throw errCode(
+ `${this.usageMessage()} does not support global packages`,
+ 'EFUNDGLOBAL'
+ )
}
const where = this.npm.prefix
@@ -146,6 +159,7 @@ class Fund extends ArboristWorkspaceCmd {
async openFundingUrl ({ path, tree, spec, fundingSourceNumber }) {
const arg = npa(spec, path)
+
const retrievePackageMetadata = () => {
if (arg.type === 'directory') {
if (tree.path === arg.fetchSpec) {
@@ -178,32 +192,35 @@ class Fund extends ArboristWorkspaceCmd {
const validSources = [].concat(normalizeFunding(funding)).filter(isValidFunding)
- const matchesValidSource =
- validSources.length === 1 ||
- (fundingSourceNumber > 0 && fundingSourceNumber <= validSources.length)
-
- if (matchesValidSource) {
- const index = fundingSourceNumber ? fundingSourceNumber - 1 : 0
- const { type, url } = validSources[index]
- const typePrefix = type ? `${type} funding` : 'Funding'
- const msg = `${typePrefix} available at the following URL`
- return openUrl(this.npm, url, msg)
- } else if (validSources.length && !(fundingSourceNumber >= 1)) {
- validSources.forEach(({ type, url }, i) => {
- const typePrefix = type ? `${type} funding` : 'Funding'
- const msg = `${typePrefix} available at the following URL`
- this.npm.output(`${i + 1}: ${msg}: ${url}`)
- })
- this.npm.output(
- /* eslint-disable-next-line max-len */
- 'Run `npm fund [<@scope>/]<pkg> --which=1`, for example, to open the first funding URL listed in that package'
- )
- } else {
- const noFundingError = new Error(`No valid funding method available for: ${spec}`)
- noFundingError.code = 'ENOFUND'
+ if (!validSources.length) {
+ throw errCode(`No valid funding method available for: ${spec}`, 'ENOFUND')
+ }
- throw noFundingError
+ const fundSource = fundingSourceNumber
+ ? validSources[fundingSourceNumber - 1]
+ : validSources.length === 1 ? validSources[0]
+ : null
+
+ if (fundSource) {
+ return openUrl(this.npm, ...this.urlMessage(fundSource))
+ }
+
+ const ambiguousUrlMsg = [
+ ...validSources.map((s, i) => `${i + 1}: ${this.urlMessage(s).reverse().join(': ')}`),
+ `Run ${this.usageMessage({ which: '1' })}` +
+ ', for example, to open the first funding URL listed in that package',
+ ]
+ if (fundingSourceNumber) {
+ ambiguousUrlMsg.unshift(`--which=${fundingSourceNumber} is not a valid index`)
}
+ this.npm.output(ambiguousUrlMsg.join('\n'))
+ }
+
+ urlMessage (source) {
+ const { type, url } = source
+ const typePrefix = type ? `${type} funding` : 'Funding'
+ const message = `${typePrefix} available at the following URL`
+ return [url, message]
}
}
module.exports = Fund
diff --git a/deps/npm/lib/commands/help-search.js b/deps/npm/lib/commands/help-search.js
index 488189bbbc..afb82bfaca 100644
--- a/deps/npm/lib/commands/help-search.js
+++ b/deps/npm/lib/commands/help-search.js
@@ -13,14 +13,13 @@ class HelpSearch extends BaseCommand {
static name = 'help-search'
static usage = ['<text>']
static params = ['long']
- static ignoreImplicitWorkspace = true
async exec (args) {
if (!args.length) {
throw this.usageError()
}
- const docPath = path.resolve(__dirname, '..', '..', 'docs/content')
+ const docPath = path.resolve(this.npm.npmRoot, 'docs/content')
const files = await glob(`${globify(docPath)}/*/*.md`)
const data = await this.readFiles(files)
const results = await this.searchFiles(args, data, files)
@@ -142,7 +141,7 @@ class HelpSearch extends BaseCommand {
formatResults (args, results) {
const cols = Math.min(process.stdout.columns || Infinity, 80) + 1
- const out = results.map(res => {
+ const output = results.map(res => {
const out = [res.cmd]
const r = Object.keys(res.hits)
.map(k => `${k}:${res.hits[k]}`)
@@ -189,10 +188,10 @@ class HelpSearch extends BaseCommand {
const finalOut = results.length && !this.npm.config.get('long')
? 'Top hits for ' + (args.map(JSON.stringify).join(' ')) + '\n' +
'—'.repeat(cols - 1) + '\n' +
- out + '\n' +
+ output + '\n' +
'—'.repeat(cols - 1) + '\n' +
'(run with -l or --long to see more context)'
- : out
+ : output
return finalOut.trim()
}
diff --git a/deps/npm/lib/commands/help.js b/deps/npm/lib/commands/help.js
index e7d6395a1b..3ab2c56319 100644
--- a/deps/npm/lib/commands/help.js
+++ b/deps/npm/lib/commands/help.js
@@ -1,4 +1,4 @@
-const { spawn } = require('child_process')
+const spawn = require('@npmcli/promise-spawn')
const path = require('path')
const openUrl = require('../utils/open-url.js')
const { promisify } = require('util')
@@ -14,19 +14,26 @@ const BaseCommand = require('../base-command.js')
const manNumberRegex = /\.(\d+)(\.[^/\\]*)?$/
// Searches for the "npm-" prefix in page names, to prefer those.
const manNpmPrefixRegex = /\/npm-/
+// hardcoded names for mansections
+// XXX: these are used in the docs workspace and should be exported
+// from npm so section names can changed more easily
+const manSectionNames = {
+ 1: 'commands',
+ 5: 'configuring-npm',
+ 7: 'using-npm',
+}
class Help extends BaseCommand {
static description = 'Get help on npm'
static name = 'help'
static usage = ['<term> [<terms..>]']
static params = ['viewer']
- static ignoreImplicitWorkspace = true
async completion (opts) {
if (opts.conf.argv.remain.length > 2) {
return []
}
- const g = path.resolve(__dirname, '../../man/man[0-9]/*.[0-9]')
+ const g = path.resolve(this.npm.npmRoot, 'man/man[0-9]/*.[0-9]')
const files = await glob(globify(g))
return Object.keys(files.reduce(function (acc, file) {
@@ -40,10 +47,7 @@ class Help extends BaseCommand {
async exec (args) {
// By default we search all of our man subdirectories, but if the user has
// asked for a specific one we limit the search to just there
- let manSearch = 'man*'
- if (/^\d+$/.test(args[0])) {
- manSearch = `man${args.shift()}`
- }
+ const manSearch = /^\d+$/.test(args[0]) ? `man${args.shift()}` : 'man*'
if (!args.length) {
return this.npm.output(await this.npm.usage)
@@ -54,20 +58,18 @@ class Help extends BaseCommand {
return this.helpSearch(args)
}
- let section = this.npm.deref(args[0]) || args[0]
-
- // support `npm help package.json`
- section = section.replace('.json', '-json')
+ // `npm help package.json`
+ const arg = (this.npm.deref(args[0]) || args[0]).replace('.json', '-json')
- const manroot = path.resolve(__dirname, '..', '..', 'man')
// find either section.n or npm-section.n
- const f = `${manroot}/${manSearch}/?(npm-)${section}.[0-9]*`
- let mans = await glob(globify(f))
- mans = mans.sort((a, b) => {
+ const f = globify(path.resolve(this.npm.npmRoot, `man/${manSearch}/?(npm-)${arg}.[0-9]*`))
+
+ const [man] = await glob(f).then(r => r.sort((a, b) => {
// Prefer the page with an npm prefix, if there's only one.
const aHasPrefix = manNpmPrefixRegex.test(a)
const bHasPrefix = manNpmPrefixRegex.test(b)
if (aHasPrefix !== bHasPrefix) {
+ /* istanbul ignore next */
return aHasPrefix ? -1 : 1
}
@@ -76,6 +78,7 @@ class Help extends BaseCommand {
const aManNumberMatch = a.match(manNumberRegex)
const bManNumberMatch = b.match(manNumberRegex)
if (aManNumberMatch) {
+ /* istanbul ignore next */
if (!bManNumberMatch) {
return -1
}
@@ -88,14 +91,9 @@ class Help extends BaseCommand {
}
return localeCompare(a, b)
- })
- const man = mans[0]
+ }))
- if (man) {
- await this.viewMan(man)
- } else {
- return this.helpSearch(args)
- }
+ return man ? this.viewMan(man) : this.helpSearch(args)
}
helpSearch (args) {
@@ -103,62 +101,31 @@ class Help extends BaseCommand {
}
async viewMan (man) {
- const env = {}
- Object.keys(process.env).forEach(function (i) {
- env[i] = process.env[i]
- })
const viewer = this.npm.config.get('viewer')
- const opts = {
- env,
- stdio: 'inherit',
+ if (viewer === 'browser') {
+ return openUrl(this.npm, this.htmlMan(man), 'help available at the following URL', true)
}
- let bin = 'man'
- const args = []
- switch (viewer) {
- case 'woman':
- bin = 'emacsclient'
- args.push('-e', `(woman-find-file '${man}')`)
- break
-
- case 'browser':
- await openUrl(this.npm, this.htmlMan(man), 'help available at the following URL', true)
- return
-
- default:
- args.push(man)
- break
+ let args = ['man', [man]]
+ if (viewer === 'woman') {
+ args = ['emacsclient', ['-e', `(woman-find-file '${man}')`]]
}
- const proc = spawn(bin, args, opts)
- return new Promise((resolve, reject) => {
- proc.on('exit', (code) => {
- if (code) {
- return reject(new Error(`help process exited with code: ${code}`))
- }
-
- return resolve()
- })
+ return spawn(...args, { stdio: 'inherit' }).catch(err => {
+ if (err.code) {
+ throw new Error(`help process exited with code: ${err.code}`)
+ } else {
+ throw err
+ }
})
}
// Returns the path to the html version of the man page
htmlMan (man) {
- let sect = man.match(manNumberRegex)[1]
+ const sect = manSectionNames[man.match(manNumberRegex)[1]]
const f = path.basename(man).replace(manNumberRegex, '')
- switch (sect) {
- case '1':
- sect = 'commands'
- break
- case '5':
- sect = 'configuring-npm'
- break
- case '7':
- sect = 'using-npm'
- break
- }
- return 'file:///' + path.resolve(__dirname, '..', '..', 'docs', 'output', sect, f + '.html')
+ return 'file:///' + path.resolve(this.npm.npmRoot, `docs/output/${sect}/${f}.html`)
}
}
module.exports = Help
diff --git a/deps/npm/lib/commands/hook.js b/deps/npm/lib/commands/hook.js
index 084741c0c5..b0f52a801f 100644
--- a/deps/npm/lib/commands/hook.js
+++ b/deps/npm/lib/commands/hook.js
@@ -19,12 +19,8 @@ class Hook extends BaseCommand {
'update <id> <url> <secret>',
]
- static ignoreImplicitWorkspace = true
-
async exec (args) {
- return otplease(this.npm, {
- ...this.npm.flatOptions,
- }, (opts) => {
+ return otplease(this.npm, { ...this.npm.flatOptions }, (opts) => {
switch (args[0]) {
case 'add':
return this.add(args[1], args[2], args[3], opts)
@@ -49,9 +45,7 @@ class Hook extends BaseCommand {
this.npm.output(Object.keys(hook).join('\t'))
this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t'))
} else if (!this.npm.silent) {
- this.npm.output(`+ ${this.hookName(hook)} ${
- opts.unicode ? ' ➜ ' : ' -> '
- } ${hook.endpoint}`)
+ this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`)
}
}
@@ -104,9 +98,7 @@ class Hook extends BaseCommand {
this.npm.output(Object.keys(hook).join('\t'))
this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t'))
} else if (!this.npm.silent) {
- this.npm.output(`- ${this.hookName(hook)} ${
- opts.unicode ? ' ✘ ' : ' X '
- } ${hook.endpoint}`)
+ this.npm.output(`- ${this.hookName(hook)} ${opts.unicode ? ' ✘ ' : ' X '} ${hook.endpoint}`)
}
}
@@ -118,9 +110,7 @@ class Hook extends BaseCommand {
this.npm.output(Object.keys(hook).join('\t'))
this.npm.output(Object.keys(hook).map(k => hook[k]).join('\t'))
} else if (!this.npm.silent) {
- this.npm.output(`+ ${this.hookName(hook)} ${
- opts.unicode ? ' ➜ ' : ' -> '
- } ${hook.endpoint}`)
+ this.npm.output(`+ ${this.hookName(hook)} ${opts.unicode ? ' ➜ ' : ' -> '} ${hook.endpoint}`)
}
}
diff --git a/deps/npm/lib/commands/init.js b/deps/npm/lib/commands/init.js
index 02a43b0ef0..16ece46589 100644
--- a/deps/npm/lib/commands/init.js
+++ b/deps/npm/lib/commands/init.js
@@ -10,6 +10,8 @@ const PackageJson = require('@npmcli/package-json')
const log = require('../utils/log-shim.js')
const updateWorkspaces = require('../workspaces/update-workspaces.js')
+const posixPath = p => p.split('\\').join('/')
+
const BaseCommand = require('../base-command.js')
class Init extends BaseCommand {
@@ -26,23 +28,24 @@ class Init extends BaseCommand {
static name = 'init'
static usage = [
- '<package-spec> (same as `npx <package-spec>)',
+ '<package-spec> (same as `npx <package-spec>`)',
'<@scope> (same as `npx <@scope>/create`)',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
async exec (args) {
// npm exec style
if (args.length) {
- return (await this.execCreate({ args, path: process.cwd() }))
+ return await this.execCreate(args)
}
// no args, uses classic init-package-json boilerplate
await this.template()
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
// if the root package is uninitiated, take care of it first
if (this.npm.flatOptions.includeWorkspaceRoot) {
await this.exec(args)
@@ -51,7 +54,16 @@ class Init extends BaseCommand {
// reads package.json for the top-level folder first, by doing this we
// ensure the command throw if no package.json is found before trying
// to create a workspace package.json file or its folders
- const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json'))
+ const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json')).catch((err) => {
+ if (err.code === 'ENOENT') {
+ log.warn('Missing package.json. Try with `--include-workspace-root`.')
+ }
+ throw err
+ })
+
+ // these are workspaces that are being created, so we cant use
+ // this.setWorkspaces()
+ const filters = this.npm.config.get('workspace')
const wPath = filterArg => resolve(this.npm.localPrefix, filterArg)
const workspacesPaths = []
@@ -61,8 +73,8 @@ class Init extends BaseCommand {
const path = wPath(filterArg)
await mkdir(path, { recursive: true })
workspacesPaths.push(path)
- await this.execCreate({ args, path })
- await this.setWorkspace({ pkg, workspacePath: path })
+ await this.execCreate(args, path)
+ await this.setWorkspace(pkg, path)
}
return
}
@@ -73,14 +85,14 @@ class Init extends BaseCommand {
await mkdir(path, { recursive: true })
workspacesPaths.push(path)
await this.template(path)
- await this.setWorkspace({ pkg, workspacePath: path })
+ await this.setWorkspace(pkg, path)
}
// reify packages once all workspaces have been initialized
await this.update(workspacesPaths)
}
- async execCreate ({ args, path }) {
+ async execCreate (args, path = process.cwd()) {
const [initerName, ...otherArgs] = args
let packageName = initerName
@@ -95,8 +107,7 @@ class Init extends BaseCommand {
const req = npa(initerName)
if (req.type === 'git' && req.hosted) {
const { user, project } = req.hosted
- packageName = initerName
- .replace(user + '/' + project, user + '/create-' + project)
+ packageName = initerName.replace(`${user}/${project}`, `${user}/create-${project}`)
} else if (req.registry) {
packageName = `${req.name.replace(/^(@[^/]+\/)?/, '$1create-')}@${req.rawSpec}`
} else {
@@ -174,7 +185,7 @@ class Init extends BaseCommand {
})
}
- async setWorkspace ({ pkg, workspacePath }) {
+ async setWorkspace (pkg, workspacePath) {
const workspaces = await mapWorkspaces({ cwd: this.npm.localPrefix, pkg })
// skip setting workspace if current package.json glob already satisfies it
@@ -199,7 +210,7 @@ class Init extends BaseCommand {
pkgJson.update({
workspaces: [
...(pkgJson.content.workspaces || []),
- relative(this.npm.localPrefix, workspacePath),
+ posixPath(relative(this.npm.localPrefix, workspacePath)),
],
})
@@ -210,9 +221,7 @@ class Init extends BaseCommand {
// translate workspaces paths into an array containing workspaces names
const workspaces = []
for (const path of workspacesPaths) {
- const pkgPath = resolve(path, 'package.json')
- const { name } = await rpj(pkgPath)
- .catch(() => ({}))
+ const { name } = await rpj(resolve(path, 'package.json')).catch(() => ({}))
if (name) {
workspaces.push(name)
diff --git a/deps/npm/lib/commands/install-ci-test.js b/deps/npm/lib/commands/install-ci-test.js
index 9977a2edc5..f7a357ba6e 100644
--- a/deps/npm/lib/commands/install-ci-test.js
+++ b/deps/npm/lib/commands/install-ci-test.js
@@ -7,7 +7,7 @@ class InstallCITest extends CI {
static description = 'Install a project with a clean slate and run tests'
static name = 'install-ci-test'
- async exec (args, cb) {
+ async exec (args) {
await this.npm.exec('ci', args)
return this.npm.exec('test', [])
}
diff --git a/deps/npm/lib/commands/install-test.js b/deps/npm/lib/commands/install-test.js
index 191d70909f..11f22e5354 100644
--- a/deps/npm/lib/commands/install-test.js
+++ b/deps/npm/lib/commands/install-test.js
@@ -7,7 +7,7 @@ class InstallTest extends Install {
static description = 'Install package(s) and run tests'
static name = 'install-test'
- async exec (args, cb) {
+ async exec (args) {
await this.npm.exec('install', args)
return this.npm.exec('test', [])
}
diff --git a/deps/npm/lib/commands/login.js b/deps/npm/lib/commands/login.js
index 7f6898d00b..dc4ed8a67a 100644
--- a/deps/npm/lib/commands/login.js
+++ b/deps/npm/lib/commands/login.js
@@ -13,8 +13,6 @@ class Login extends BaseCommand {
'auth-type',
]
- static ignoreImplicitWorkspace = true
-
async exec (args) {
const scope = this.npm.config.get('scope')
let registry = this.npm.config.get('registry')
diff --git a/deps/npm/lib/commands/logout.js b/deps/npm/lib/commands/logout.js
index 7c2a7f0b2f..aea5e93652 100644
--- a/deps/npm/lib/commands/logout.js
+++ b/deps/npm/lib/commands/logout.js
@@ -11,8 +11,6 @@ class Logout extends BaseCommand {
'scope',
]
- static ignoreImplicitWorkspace = true
-
async exec (args) {
const registry = this.npm.config.get('registry')
const scope = this.npm.config.get('scope')
diff --git a/deps/npm/lib/commands/ls.js b/deps/npm/lib/commands/ls.js
index 7eebdf6916..2213e79374 100644
--- a/deps/npm/lib/commands/ls.js
+++ b/deps/npm/lib/commands/ls.js
@@ -178,11 +178,9 @@ class LS extends ArboristWorkspaceCmd {
e.code === 'EJSONPARSE' && e.path === resolve(path, 'package.json'))
this.npm.outputBuffer(
- json
- ? jsonOutput({ path, problems, result, rootError, seenItems })
- : parseable
- ? parseableOutput({ seenNodes, global, long })
- : humanOutput({ color, result, seenItems, unicode })
+ json ? jsonOutput({ path, problems, result, rootError, seenItems }) :
+ parseable ? parseableOutput({ seenNodes, global, long }) :
+ humanOutput({ color, result, seenItems, unicode })
)
// if filtering items, should exit with error code on no results
@@ -402,7 +400,7 @@ const getJsonOutputItem = (node, { global, long }) => {
return augmentItemWithIncludeMetadata(node, item)
}
-const filterByEdgesTypes = ({ link, omit = [] }) => (edge) => {
+const filterByEdgesTypes = ({ link, omit }) => (edge) => {
for (const omitType of omit) {
if (edge[omitType]) {
return false
diff --git a/deps/npm/lib/commands/org.js b/deps/npm/lib/commands/org.js
index f49556c8d6..575ff75e2a 100644
--- a/deps/npm/lib/commands/org.js
+++ b/deps/npm/lib/commands/org.js
@@ -13,7 +13,6 @@ class Org extends BaseCommand {
]
static params = ['registry', 'otp', 'json', 'parseable']
- static ignoreImplicitWorkspace = true
async completion (opts) {
const argv = opts.conf.argv.remain
@@ -32,7 +31,7 @@ class Org extends BaseCommand {
}
}
- async exec ([cmd, orgname, username, role], cb) {
+ async exec ([cmd, orgname, username, role]) {
return otplease(this.npm, {
...this.npm.flatOptions,
}, opts => {
@@ -139,15 +138,15 @@ class Org extends BaseCommand {
this.npm.output(JSON.stringify(roster, null, 2))
} else if (opts.parseable) {
this.npm.output(['user', 'role'].join('\t'))
- Object.keys(roster).forEach(user => {
- this.npm.output([user, roster[user]].join('\t'))
+ Object.keys(roster).forEach(u => {
+ this.npm.output([u, roster[u]].join('\t'))
})
} else if (!this.npm.silent) {
const table = new Table({ head: ['user', 'role'] })
Object.keys(roster)
.sort()
- .forEach(user => {
- table.push([user, roster[user]])
+ .forEach(u => {
+ table.push([u, roster[u]])
})
this.npm.output(table.toString())
}
diff --git a/deps/npm/lib/commands/outdated.js b/deps/npm/lib/commands/outdated.js
index 9e2060658e..5e8a4e0d21 100644
--- a/deps/npm/lib/commands/outdated.js
+++ b/deps/npm/lib/commands/outdated.js
@@ -1,5 +1,5 @@
const os = require('os')
-const path = require('path')
+const { resolve } = require('path')
const pacote = require('pacote')
const table = require('text-table')
const chalk = require('chalk')
@@ -26,7 +26,7 @@ class Outdated extends ArboristWorkspaceCmd {
]
async exec (args) {
- const global = path.resolve(this.npm.globalDir, '..')
+ const global = resolve(this.npm.globalDir, '..')
const where = this.npm.global
? global
: this.npm.prefix
diff --git a/deps/npm/lib/commands/owner.js b/deps/npm/lib/commands/owner.js
index 824b64e044..3a997db800 100644
--- a/deps/npm/lib/commands/owner.js
+++ b/deps/npm/lib/commands/owner.js
@@ -32,6 +32,7 @@ class Owner extends BaseCommand {
'ls <package-spec>',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
async completion (opts) {
@@ -82,8 +83,8 @@ class Owner extends BaseCommand {
}
}
- async execWorkspaces ([action, ...args], filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces ([action, ...args]) {
+ await this.setWorkspaces()
// ls pkg or owner add/rm package
if ((action === 'ls' && args.length > 0) || args.length > 1) {
const implicitWorkspaces = this.npm.config.get('workspace', 'default')
@@ -119,7 +120,7 @@ class Owner extends BaseCommand {
this.npm.output(maintainers.map(m => `${m.name} <${m.email}>`).join('\n'))
}
} catch (err) {
- log.error('owner ls', "Couldn't get owner data", pkg)
+ log.error('owner ls', "Couldn't get owner data", npmFetch.cleanUrl(pkg))
throw err
}
}
diff --git a/deps/npm/lib/commands/pack.js b/deps/npm/lib/commands/pack.js
index c6a7480464..74e80e573c 100644
--- a/deps/npm/lib/commands/pack.js
+++ b/deps/npm/lib/commands/pack.js
@@ -18,6 +18,7 @@ class Pack extends BaseCommand {
]
static usage = ['<package-spec>']
+ static workspaces = true
static ignoreImplicitWorkspace = false
async exec (args) {
@@ -64,7 +65,7 @@ class Pack extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
// If they either ask for nothing, or explicitly include '.' in the args,
// we effectively translate that into each workspace requested
@@ -75,7 +76,7 @@ class Pack extends BaseCommand {
return this.exec(args)
}
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
return this.exec([...this.workspacePaths, ...args.filter(a => a !== '.')])
}
}
diff --git a/deps/npm/lib/commands/ping.js b/deps/npm/lib/commands/ping.js
index 2203921468..c79e6a96ce 100644
--- a/deps/npm/lib/commands/ping.js
+++ b/deps/npm/lib/commands/ping.js
@@ -1,3 +1,4 @@
+const { cleanUrl } = require('npm-registry-fetch')
const log = require('../utils/log-shim')
const pingUtil = require('../utils/ping.js')
const BaseCommand = require('../base-command.js')
@@ -6,17 +7,17 @@ class Ping extends BaseCommand {
static description = 'Ping npm registry'
static params = ['registry']
static name = 'ping'
- static ignoreImplicitWorkspace = true
async exec (args) {
- log.notice('PING', this.npm.config.get('registry'))
+ const cleanRegistry = cleanUrl(this.npm.config.get('registry'))
+ log.notice('PING', cleanRegistry)
const start = Date.now()
const details = await pingUtil({ ...this.npm.flatOptions })
const time = Date.now() - start
log.notice('PONG', `${time}ms`)
if (this.npm.config.get('json')) {
this.npm.output(JSON.stringify({
- registry: this.npm.config.get('registry'),
+ registry: cleanRegistry,
time,
details,
}, null, 2))
diff --git a/deps/npm/lib/commands/pkg.js b/deps/npm/lib/commands/pkg.js
index 5fac9bfb54..5cdcd20788 100644
--- a/deps/npm/lib/commands/pkg.js
+++ b/deps/npm/lib/commands/pkg.js
@@ -20,6 +20,7 @@ class Pkg extends BaseCommand {
'workspaces',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
async exec (args, { prefix } = {}) {
@@ -49,8 +50,8 @@ class Pkg extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
const result = {}
for (const [workspaceName, workspacePath] of this.workspaces.entries()) {
this.prefix = workspacePath
@@ -81,7 +82,7 @@ class Pkg extends BaseCommand {
// only outputs if not running with workspaces config,
// in case you're retrieving info for workspaces the pkgWorkspaces
// will handle the output to make sure it get keyed by ws name
- if (!this.workspaces) {
+ if (!this.npm.config.get('workspaces')) {
this.npm.output(JSON.stringify(result, null, 2))
}
diff --git a/deps/npm/lib/commands/prefix.js b/deps/npm/lib/commands/prefix.js
index dd0e34c3d3..264b819fc7 100644
--- a/deps/npm/lib/commands/prefix.js
+++ b/deps/npm/lib/commands/prefix.js
@@ -5,7 +5,6 @@ class Prefix extends BaseCommand {
static name = 'prefix'
static params = ['global']
static usage = ['[-g]']
- static ignoreImplicitWorkspace = true
async exec (args) {
return this.npm.output(this.npm.prefix)
diff --git a/deps/npm/lib/commands/profile.js b/deps/npm/lib/commands/profile.js
index 27060cf73a..e42ebb276d 100644
--- a/deps/npm/lib/commands/profile.js
+++ b/deps/npm/lib/commands/profile.js
@@ -54,8 +54,6 @@ class Profile extends BaseCommand {
'otp',
]
- static ignoreImplicitWorkspace = true
-
async completion (opts) {
var argv = opts.conf.argv.remain
@@ -221,7 +219,7 @@ class Profile extends BaseCommand {
newUser[prop] = value
- const result = await otplease(this.npm, conf, conf => npmProfile.set(newUser, conf))
+ const result = await otplease(this.npm, conf, c => npmProfile.set(newUser, c))
if (this.npm.config.get('json')) {
this.npm.output(JSON.stringify({ [prop]: result[prop] }, null, 2))
diff --git a/deps/npm/lib/commands/publish.js b/deps/npm/lib/commands/publish.js
index 23323a174e..76faea9457 100644
--- a/deps/npm/lib/commands/publish.js
+++ b/deps/npm/lib/commands/publish.js
@@ -38,6 +38,7 @@ class Publish extends BaseCommand {
]
static usage = ['<package-spec>']
+ static workspaces = true
static ignoreImplicitWorkspace = false
async exec (args) {
@@ -123,7 +124,7 @@ class Publish extends BaseCommand {
log.notice('', msg)
if (!dryRun) {
- await otplease(this.npm, opts, opts => libpub(manifest, tarballData, opts))
+ await otplease(this.npm, opts, o => libpub(manifest, tarballData, o))
}
if (spec.type === 'directory' && !ignoreScripts) {
@@ -155,14 +156,14 @@ class Publish extends BaseCommand {
return pkgContents
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
// Suppresses JSON output in publish() so we can handle it here
this.suppressOutput = true
const results = {}
const json = this.npm.config.get('json')
const { silent } = this.npm
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
for (const [name, workspace] of this.workspaces.entries()) {
let pkgContents
diff --git a/deps/npm/lib/commands/query.js b/deps/npm/lib/commands/query.js
index 5f05ab3164..b5f4d8e57d 100644
--- a/deps/npm/lib/commands/query.js
+++ b/deps/npm/lib/commands/query.js
@@ -41,6 +41,7 @@ class Query extends BaseCommand {
static name = 'query'
static usage = ['<selector>']
+ static workspaces = true
static ignoreImplicitWorkspace = false
static params = [
@@ -70,8 +71,8 @@ class Query extends BaseCommand {
this.npm.output(this.parsedResponse)
}
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
const opts = {
...this.npm.flatOptions,
path: this.npm.prefix,
diff --git a/deps/npm/lib/commands/restart.js b/deps/npm/lib/commands/restart.js
index 575928b220..7ca2eb323d 100644
--- a/deps/npm/lib/commands/restart.js
+++ b/deps/npm/lib/commands/restart.js
@@ -8,7 +8,6 @@ class Restart extends LifecycleCmd {
'ignore-scripts',
'script-shell',
]
-
- static ignoreImplicitWorkspace = false
}
+
module.exports = Restart
diff --git a/deps/npm/lib/commands/root.js b/deps/npm/lib/commands/root.js
index b814034def..7749c60245 100644
--- a/deps/npm/lib/commands/root.js
+++ b/deps/npm/lib/commands/root.js
@@ -3,7 +3,6 @@ class Root extends BaseCommand {
static description = 'Display npm root'
static name = 'root'
static params = ['global']
- static ignoreImplicitWorkspace = true
async exec () {
this.npm.output(this.npm.dir)
diff --git a/deps/npm/lib/commands/run-script.js b/deps/npm/lib/commands/run-script.js
index 3852f7ba18..51746c5e52 100644
--- a/deps/npm/lib/commands/run-script.js
+++ b/deps/npm/lib/commands/run-script.js
@@ -41,6 +41,7 @@ class RunScript extends BaseCommand {
static name = 'run-script'
static usage = ['<command> [-- <args>]']
+ static workspaces = true
static ignoreImplicitWorkspace = false
static isShellout = true
@@ -62,11 +63,11 @@ class RunScript extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
if (args.length) {
- return this.runWorkspaces(args, filters)
+ return this.runWorkspaces(args)
} else {
- return this.listWorkspaces(args, filters)
+ return this.listWorkspaces(args)
}
}
@@ -121,11 +122,11 @@ class RunScript extends BaseCommand {
banner: !this.npm.silent,
}
- for (const [event, args] of events) {
+ for (const [ev, evArgs] of events) {
await runScript({
...opts,
- event,
- args,
+ event: ev,
+ args: evArgs,
})
}
}
@@ -200,7 +201,7 @@ class RunScript extends BaseCommand {
async runWorkspaces (args, filters) {
const res = []
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
for (const workspacePath of this.workspacePaths) {
const pkg = await rpj(`${workspacePath}/package.json`)
@@ -233,7 +234,7 @@ class RunScript extends BaseCommand {
}
async listWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
if (this.npm.silent) {
return
diff --git a/deps/npm/lib/commands/search.js b/deps/npm/lib/commands/search.js
index 8751e9e7d2..7419e97454 100644
--- a/deps/npm/lib/commands/search.js
+++ b/deps/npm/lib/commands/search.js
@@ -51,7 +51,6 @@ class Search extends BaseCommand {
]
static usage = ['[search terms ...]']
- static ignoreImplicitWorkspace = true
async exec (args) {
const opts = {
diff --git a/deps/npm/lib/commands/start.js b/deps/npm/lib/commands/start.js
index d84ad23eba..a16eade24d 100644
--- a/deps/npm/lib/commands/start.js
+++ b/deps/npm/lib/commands/start.js
@@ -8,7 +8,6 @@ class Start extends LifecycleCmd {
'ignore-scripts',
'script-shell',
]
-
- static ignoreImplicitWorkspace = false
}
+
module.exports = Start
diff --git a/deps/npm/lib/commands/stop.js b/deps/npm/lib/commands/stop.js
index db497675a6..ae3031f06d 100644
--- a/deps/npm/lib/commands/stop.js
+++ b/deps/npm/lib/commands/stop.js
@@ -8,7 +8,6 @@ class Stop extends LifecycleCmd {
'ignore-scripts',
'script-shell',
]
-
- static ignoreImplicitWorkspace = false
}
+
module.exports = Stop
diff --git a/deps/npm/lib/commands/test.js b/deps/npm/lib/commands/test.js
index 43be934894..eccc47fc33 100644
--- a/deps/npm/lib/commands/test.js
+++ b/deps/npm/lib/commands/test.js
@@ -8,7 +8,6 @@ class Test extends LifecycleCmd {
'ignore-scripts',
'script-shell',
]
-
- static ignoreImplicitWorkspace = false
}
+
module.exports = Test
diff --git a/deps/npm/lib/commands/token.js b/deps/npm/lib/commands/token.js
index de8e61101d..8da8311875 100644
--- a/deps/npm/lib/commands/token.js
+++ b/deps/npm/lib/commands/token.js
@@ -14,7 +14,6 @@ class Token extends BaseCommand {
static name = 'token'
static usage = ['list', 'revoke <id|token>', 'create [--read-only] [--cidr=list]']
static params = ['read-only', 'cidr', 'registry', 'otp']
- static ignoreImplicitWorkspace = true
async completion (opts) {
const argv = opts.conf.argv.remain
@@ -30,7 +29,7 @@ class Token extends BaseCommand {
throw new Error(argv[2] + ' not recognized')
}
- async exec (args, cb) {
+ async exec (args) {
log.gauge.show('token')
if (args.length === 0) {
return this.list()
@@ -121,9 +120,7 @@ class Token extends BaseCommand {
})
await Promise.all(
toRemove.map(key => {
- return otplease(this.npm, conf, conf => {
- return profile.removeToken(key, conf)
- })
+ return otplease(this.npm, conf, c => profile.removeToken(key, c))
})
)
if (conf.json) {
@@ -144,9 +141,7 @@ class Token extends BaseCommand {
const validCIDR = this.validateCIDRList(cidr)
log.info('token', 'creating')
const result = await pulseTillDone.withPromise(
- otplease(this.npm, conf, conf => {
- return profile.createToken(password, readonly, validCIDR, conf)
- })
+ otplease(this.npm, conf, c => profile.createToken(password, readonly, validCIDR, c))
)
delete result.key
delete result.updated
@@ -216,7 +211,7 @@ class Token extends BaseCommand {
}
validateCIDRList (cidrs) {
- const maybeList = cidrs ? (Array.isArray(cidrs) ? cidrs : [cidrs]) : []
+ const maybeList = [].concat(cidrs).filter(Boolean)
const list = maybeList.length === 1 ? maybeList[0].split(/,\s*/) : maybeList
for (const cidr of list) {
if (isCidrV6(cidr)) {
diff --git a/deps/npm/lib/commands/uninstall.js b/deps/npm/lib/commands/uninstall.js
index e4a193cc5c..8c44f2e321 100644
--- a/deps/npm/lib/commands/uninstall.js
+++ b/deps/npm/lib/commands/uninstall.js
@@ -20,19 +20,13 @@ class Uninstall extends ArboristWorkspaceCmd {
}
async exec (args) {
- // the /path/to/node_modules/..
- const path = this.npm.global
- ? resolve(this.npm.globalDir, '..')
- : this.npm.localPrefix
-
if (!args.length) {
if (!this.npm.global) {
throw new Error('Must provide a package name to remove')
} else {
- let pkg
-
try {
- pkg = await rpj(resolve(this.npm.localPrefix, 'package.json'))
+ const pkg = await rpj(resolve(this.npm.localPrefix, 'package.json'))
+ args.push(pkg.name)
} catch (er) {
if (er.code !== 'ENOENT' && er.code !== 'ENOTDIR') {
throw er
@@ -40,11 +34,14 @@ class Uninstall extends ArboristWorkspaceCmd {
throw this.usageError()
}
}
-
- args.push(pkg.name)
}
}
+ // the /path/to/node_modules/..
+ const path = this.npm.global
+ ? resolve(this.npm.globalDir, '..')
+ : this.npm.localPrefix
+
const opts = {
...this.npm.flatOptions,
path,
diff --git a/deps/npm/lib/commands/unpublish.js b/deps/npm/lib/commands/unpublish.js
index 268c8c3dae..9985e2e39f 100644
--- a/deps/npm/lib/commands/unpublish.js
+++ b/deps/npm/lib/commands/unpublish.js
@@ -21,6 +21,7 @@ class Unpublish extends BaseCommand {
static name = 'unpublish'
static params = ['dry-run', 'force', 'workspace', 'workspaces']
static usage = ['[<package-spec>]']
+ static workspaces = true
static ignoreImplicitWorkspace = false
async getKeysOfVersions (name, opts) {
@@ -130,15 +131,15 @@ class Unpublish extends BaseCommand {
}
if (!dryRun) {
- await otplease(this.npm, opts, opts => libunpub(spec, opts))
+ await otplease(this.npm, opts, o => libunpub(spec, o))
}
if (!silent) {
this.npm.output(`- ${pkgName}${pkgVersion}`)
}
}
- async execWorkspaces (args, filters) {
- await this.setWorkspaces(filters)
+ async execWorkspaces (args) {
+ await this.setWorkspaces()
const force = this.npm.config.get('force')
if (!force) {
diff --git a/deps/npm/lib/commands/update.js b/deps/npm/lib/commands/update.js
index be9d35093d..fd30bcb41e 100644
--- a/deps/npm/lib/commands/update.js
+++ b/deps/npm/lib/commands/update.js
@@ -40,9 +40,7 @@ class Update extends ArboristWorkspaceCmd {
async exec (args) {
const update = args.length === 0 ? true : args
const global = path.resolve(this.npm.globalDir, '..')
- const where = this.npm.global
- ? global
- : this.npm.prefix
+ const where = this.npm.global ? global : this.npm.prefix
// In the context of `npm update` the save
// config value should default to `false`
diff --git a/deps/npm/lib/commands/version.js b/deps/npm/lib/commands/version.js
index ab59fff5a3..a523283671 100644
--- a/deps/npm/lib/commands/version.js
+++ b/deps/npm/lib/commands/version.js
@@ -22,6 +22,7 @@ class Version extends BaseCommand {
'include-workspace-root',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
/* eslint-disable-next-line max-len */
@@ -60,12 +61,12 @@ class Version extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
switch (args.length) {
case 0:
- return this.listWorkspaces(filters)
+ return this.listWorkspaces()
case 1:
- return this.changeWorkspaces(args, filters)
+ return this.changeWorkspaces(args)
default:
throw this.usageError()
}
@@ -80,9 +81,9 @@ class Version extends BaseCommand {
return this.npm.output(`${prefix}${version}`)
}
- async changeWorkspaces (args, filters) {
+ async changeWorkspaces (args) {
const prefix = this.npm.config.get('tag-version-prefix')
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
const updatedWorkspaces = []
for (const [name, path] of this.workspaces) {
this.npm.output(name)
@@ -120,9 +121,9 @@ class Version extends BaseCommand {
}
}
- async listWorkspaces (filters) {
+ async listWorkspaces () {
const results = {}
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
for (const path of this.workspacePaths) {
const pj = resolve(path, 'package.json')
// setWorkspaces has already parsed package.json so we know it won't error
diff --git a/deps/npm/lib/commands/view.js b/deps/npm/lib/commands/view.js
index 32b2d0f92a..855b37b81d 100644
--- a/deps/npm/lib/commands/view.js
+++ b/deps/npm/lib/commands/view.js
@@ -1,8 +1,3 @@
-/* eslint-disable no-console */
-// XXX: remove console.log later
-
-// npm view [pkg [pkg ...]]
-
const chalk = require('chalk')
const columns = require('cli-columns')
const fs = require('fs')
@@ -31,8 +26,8 @@ class View extends BaseCommand {
'include-workspace-root',
]
+ static workspaces = true
static ignoreImplicitWorkspace = false
-
static usage = ['[<package-spec>] [<field>[.subfield]...]']
async completion (opts) {
@@ -127,12 +122,12 @@ class View extends BaseCommand {
const msg = await this.jsonData(reducedData, pckmnt._id)
if (msg !== '') {
- console.log(msg)
+ this.npm.output(msg)
}
}
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
if (!args.length) {
args = ['.']
}
@@ -150,7 +145,7 @@ class View extends BaseCommand {
args = [''] // getData relies on this
}
const results = {}
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
for (const name of this.workspaceNames) {
const wsPkg = `${name}${pkg.slice(1)}`
const [pckmnt, data] = await this.getData(wsPkg, args)
@@ -166,10 +161,10 @@ class View extends BaseCommand {
if (wholePackument) {
data.map((v) => this.prettyView(pckmnt, v[Object.keys(v)[0]]['']))
} else {
- console.log(`${name}:`)
+ this.npm.output(`${name}:`)
const msg = await this.jsonData(reducedData, pckmnt._id)
if (msg !== '') {
- console.log(msg)
+ this.npm.output(msg)
}
}
} else {
@@ -180,7 +175,7 @@ class View extends BaseCommand {
}
}
if (Object.keys(results).length > 0) {
- console.log(JSON.stringify(results, null, 2))
+ this.npm.output(JSON.stringify(results, null, 2))
}
}
@@ -317,13 +312,13 @@ class View extends BaseCommand {
return msg.trim()
}
- prettyView (packument, manifest) {
+ prettyView (packu, manifest) {
// More modern, pretty printing of default view
const unicode = this.npm.config.get('unicode')
const tags = []
- Object.keys(packument['dist-tags']).forEach((t) => {
- const version = packument['dist-tags'][t]
+ Object.keys(packu['dist-tags']).forEach((t) => {
+ const version = packu['dist-tags'][t]
tags.push(`${chalk.bold.green(t)}: ${version}`)
})
const unpackedSize = manifest.dist.unpackedSize &&
@@ -333,10 +328,10 @@ class View extends BaseCommand {
name: chalk.green(manifest.name),
version: chalk.green(manifest.version),
bins: Object.keys(manifest.bin || {}),
- versions: chalk.yellow(packument.versions.length + ''),
+ versions: chalk.yellow(packu.versions.length + ''),
description: manifest.description,
deprecated: manifest.deprecated,
- keywords: packument.keywords || [],
+ keywords: packu.keywords || [],
license: typeof licenseField === 'string'
? licenseField
: (licenseField.type || 'Proprietary'),
@@ -347,9 +342,9 @@ class View extends BaseCommand {
name: chalk.yellow(manifest._npmUser.name),
email: chalk.cyan(manifest._npmUser.email),
}),
- modified: !packument.time ? undefined
- : chalk.yellow(relativeDate(packument.time[manifest.version])),
- maintainers: (packument.maintainers || []).map((u) => unparsePerson({
+ modified: !packu.time ? undefined
+ : chalk.yellow(relativeDate(packu.time[manifest.version])),
+ maintainers: (packu.maintainers || []).map((u) => unparsePerson({
name: chalk.yellow(u.name),
email: chalk.cyan(u.email),
})),
@@ -376,61 +371,61 @@ class View extends BaseCommand {
info.license = chalk.green(info.license)
}
- console.log('')
- console.log(
+ this.npm.output('')
+ this.npm.output(
chalk.underline.bold(`${info.name}@${info.version}`) +
' | ' + info.license +
' | deps: ' + (info.deps.length ? chalk.cyan(info.deps.length) : chalk.green('none')) +
' | versions: ' + info.versions
)
- info.description && console.log(info.description)
+ info.description && this.npm.output(info.description)
if (info.repo || info.site) {
- info.site && console.log(chalk.cyan(info.site))
+ info.site && this.npm.output(chalk.cyan(info.site))
}
const warningSign = unicode ? ' ⚠️ ' : '!!'
- info.deprecated && console.log(
+ info.deprecated && this.npm.output(
`\n${chalk.bold.red('DEPRECATED')}${
warningSign
} - ${info.deprecated}`
)
if (info.keywords.length) {
- console.log('')
- console.log('keywords:', chalk.yellow(info.keywords.join(', ')))
+ this.npm.output('')
+ this.npm.output('keywords:', chalk.yellow(info.keywords.join(', ')))
}
if (info.bins.length) {
- console.log('')
- console.log('bin:', chalk.yellow(info.bins.join(', ')))
+ this.npm.output('')
+ this.npm.output('bin:', chalk.yellow(info.bins.join(', ')))
}
- console.log('')
- console.log('dist')
- console.log('.tarball:', info.tarball)
- console.log('.shasum:', info.shasum)
- info.integrity && console.log('.integrity:', info.integrity)
- info.unpackedSize && console.log('.unpackedSize:', info.unpackedSize)
+ this.npm.output('')
+ this.npm.output('dist')
+ this.npm.output('.tarball:', info.tarball)
+ this.npm.output('.shasum:', info.shasum)
+ info.integrity && this.npm.output('.integrity:', info.integrity)
+ info.unpackedSize && this.npm.output('.unpackedSize:', info.unpackedSize)
const maxDeps = 24
if (info.deps.length) {
- console.log('')
- console.log('dependencies:')
- console.log(columns(info.deps.slice(0, maxDeps), { padding: 1 }))
+ this.npm.output('')
+ this.npm.output('dependencies:')
+ this.npm.output(columns(info.deps.slice(0, maxDeps), { padding: 1 }))
if (info.deps.length > maxDeps) {
- console.log(`(...and ${info.deps.length - maxDeps} more.)`)
+ this.npm.output(`(...and ${info.deps.length - maxDeps} more.)`)
}
}
if (info.maintainers && info.maintainers.length) {
- console.log('')
- console.log('maintainers:')
- info.maintainers.forEach((u) => console.log('-', u))
+ this.npm.output('')
+ this.npm.output('maintainers:')
+ info.maintainers.forEach((u) => this.npm.output('-', u))
}
- console.log('')
- console.log('dist-tags:')
- console.log(columns(info.tags))
+ this.npm.output('')
+ this.npm.output('dist-tags:')
+ this.npm.output(columns(info.tags))
if (info.publisher || info.modified) {
let publishInfo = 'published'
@@ -440,8 +435,8 @@ class View extends BaseCommand {
if (info.publisher) {
publishInfo += ` by ${info.publisher}`
}
- console.log('')
- console.log(publishInfo)
+ this.npm.output('')
+ this.npm.output(publishInfo)
}
}
}
diff --git a/deps/npm/lib/commands/whoami.js b/deps/npm/lib/commands/whoami.js
index 4497f9b3a5..154cc87039 100644
--- a/deps/npm/lib/commands/whoami.js
+++ b/deps/npm/lib/commands/whoami.js
@@ -5,7 +5,6 @@ class Whoami extends BaseCommand {
static description = 'Display npm username'
static name = 'whoami'
static params = ['registry']
- static ignoreImplicitWorkspace = true
async exec (args) {
const username = await getIdentity(this.npm, { ...this.npm.flatOptions })
diff --git a/deps/npm/lib/lifecycle-cmd.js b/deps/npm/lib/lifecycle-cmd.js
index 41633a4ba3..848771a383 100644
--- a/deps/npm/lib/lifecycle-cmd.js
+++ b/deps/npm/lib/lifecycle-cmd.js
@@ -5,12 +5,14 @@ const BaseCommand = require('./base-command.js')
class LifecycleCmd extends BaseCommand {
static usage = ['[-- <args>]']
static isShellout = true
+ static workspaces = true
+ static ignoreImplicitWorkspace = false
- async exec (args, cb) {
+ async exec (args) {
return this.npm.exec('run-script', [this.constructor.name, ...args])
}
- async execWorkspaces (args, filters, cb) {
+ async execWorkspaces (args) {
return this.npm.exec('run-script', [this.constructor.name, ...args])
}
}
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index 0bdbcdb9ef..841d145ddc 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -20,25 +20,24 @@ const updateNotifier = require('./utils/update-notifier.js')
const pkg = require('../package.json')
const cmdList = require('./utils/cmd-list.js')
-let warnedNonDashArg = false
-const _load = Symbol('_load')
-
class Npm extends EventEmitter {
static get version () {
return pkg.version
}
- command = null
updateNotification = null
loadErr = null
argv = []
+ #command = null
#runId = new Date().toISOString().replace(/[.:]/g, '_')
#loadPromise = null
#tmpFolder = null
#title = 'npm'
#argvClean = []
#chalk = null
+ #npmRoot = null
+ #warnedNonDashArg = false
#outputBuffer = []
#logFile = new LogFile()
@@ -52,12 +51,30 @@ class Npm extends EventEmitter {
},
})
- config = new Config({
- npmPath: dirname(__dirname),
- definitions,
- flatten,
- shorthands,
- })
+ // all these options are only used by tests in order to make testing more
+ // closely resemble real world usage. for now, npm has no programmatic API so
+ // it is ok to add stuff here, but we should not rely on it more than
+ // necessary. XXX: make these options not necessary by refactoring @npmcli/config
+ // - npmRoot: this is where npm looks for docs files and the builtin config
+ // - argv: this allows tests to extend argv in the same way the argv would
+ // be passed in via a CLI arg.
+ // - excludeNpmCwd: this is a hack to get @npmcli/config to stop walking up
+ // dirs to set a local prefix when it encounters the `npmRoot`. this
+ // allows tests created by tap inside this repo to not set the local
+ // prefix to `npmRoot` since that is the first dir it would encounter when
+ // doing implicit detection
+ constructor ({ npmRoot = dirname(__dirname), argv = [], excludeNpmCwd = false } = {}) {
+ super()
+ this.#npmRoot = npmRoot
+ this.config = new Config({
+ npmPath: this.#npmRoot,
+ definitions,
+ flatten,
+ shorthands,
+ argv: [...process.argv, ...argv],
+ excludeNpmCwd,
+ })
+ }
get version () {
return this.constructor.version
@@ -89,44 +106,31 @@ class Npm extends EventEmitter {
async cmd (cmd) {
await this.load()
- // when location isn't set and global isn't true
- // check for a package.json at the localPrefix
- // and set the location to project if found
- // TODO: this logic can move to the config module loadLocalPrefix to
- // avoid double stat calls and consolidate logic
- if (this.config.isDefault('location') && !this.config.get('global')) {
- const hasPackageJson = await fs.stat(resolve(this.config.localPrefix, 'package.json'))
- .then((st) => st.isFile())
- .catch(() => false)
- if (hasPackageJson) {
- this.config.set('location', 'project')
- }
- }
-
- const command = this.deref(cmd)
- if (!command) {
+ const cmdId = this.deref(cmd)
+ if (!cmdId) {
throw Object.assign(new Error(`Unknown command ${cmd}`), {
code: 'EUNKNOWNCOMMAND',
})
}
- const Impl = require(`./commands/${command}.js`)
- const impl = new Impl(this)
- return impl
- }
- // Call an npm command
- async exec (cmd, args) {
- const command = await this.cmd(cmd)
- const timeEnd = this.time(`command:${cmd}`)
+ const Impl = require(`./commands/${cmdId}.js`)
+ const command = new Impl(this)
// since 'test', 'start', 'stop', etc. commands re-enter this function
// to call the run-script command, we need to only set it one time.
- if (!this.command) {
- process.env.npm_command = command.name
- this.command = command.name
- this.commandInstance = command
+ if (!this.#command) {
+ this.#command = command
+ process.env.npm_command = this.command
}
+ return command
+ }
+
+ // Call an npm command
+ async exec (cmd, args = this.argv) {
+ const command = await this.cmd(cmd)
+ const timeEnd = this.time(`command:${cmd}`)
+
// this is async but we dont await it, since its ok if it doesnt
// finish before the command finishes running. it uses command and argv
// so it must be initiated here, after the command name is set
@@ -135,72 +139,27 @@ class Npm extends EventEmitter {
// Options are prefixed by a hyphen-minus (-, \u2d).
// Other dash-type chars look similar but are invalid.
- if (!warnedNonDashArg) {
- args
- .filter(arg => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(arg))
- .forEach(arg => {
- warnedNonDashArg = true
- log.error(
- 'arg',
- 'Argument starts with non-ascii dash, this is probably invalid:',
- arg
- )
- })
- }
-
- const workspacesEnabled = this.config.get('workspaces')
- // if cwd is a workspace, the default is set to [that workspace]
- const implicitWorkspace = this.config.get('workspace', 'default').length > 0
- const workspacesFilters = this.config.get('workspace')
- const includeWorkspaceRoot = this.config.get('include-workspace-root')
- // only call execWorkspaces when we have workspaces explicitly set
- // or when it is implicit and not in our ignore list
- const hasWorkspaceFilters = workspacesFilters.length > 0
- const invalidWorkspaceConfig = workspacesEnabled === false && hasWorkspaceFilters
-
- // (-ws || -w foo) && (cwd is not a workspace || command is not ignoring implicit workspaces)
- const filterByWorkspaces = (workspacesEnabled || hasWorkspaceFilters) &&
- (!implicitWorkspace || !command.ignoreImplicitWorkspace)
- // normally this would go in the constructor, but our tests don't
- // actually use a real npm object so this.npm.config isn't always
- // populated. this is the compromise until we can make that a reality
- // and then move this into the constructor.
- command.workspaces = workspacesEnabled
- command.workspacePaths = null
- // normally this would be evaluated in base-command#setWorkspaces, see
- // above for explanation
- command.includeWorkspaceRoot = includeWorkspaceRoot
-
- let execPromise = Promise.resolve()
- if (this.config.get('usage')) {
- this.output(command.usage)
- } else if (invalidWorkspaceConfig) {
- execPromise = Promise.reject(
- new Error('Can not use --no-workspaces and --workspace at the same time'))
- } else if (filterByWorkspaces) {
- if (this.global) {
- execPromise = Promise.reject(new Error('Workspaces not supported for global packages'))
- } else {
- execPromise = command.execWorkspaces(args, workspacesFilters)
+ if (!this.#warnedNonDashArg) {
+ const nonDashArgs = args.filter(a => /^[\u2010-\u2015\u2212\uFE58\uFE63\uFF0D]/.test(a))
+ if (nonDashArgs.length) {
+ this.#warnedNonDashArg = true
+ log.error(
+ 'arg',
+ 'Argument starts with non-ascii dash, this is probably invalid:',
+ nonDashArgs.join(', ')
+ )
}
- } else {
- execPromise = command.exec(args)
}
- return execPromise.finally(timeEnd)
+ return command.cmdExec(args).finally(timeEnd)
}
async load () {
if (!this.#loadPromise) {
- this.#loadPromise = this.time('npm:load', async () => {
- await this[_load]().catch((er) => {
- this.loadErr = er
- throw er
- })
- if (this.config.get('force')) {
- log.warn('using --force', 'Recommended protections disabled.')
- }
- })
+ this.#loadPromise = this.time('npm:load', () => this.#load().catch((er) => {
+ this.loadErr = er
+ throw er
+ }))
}
return this.#loadPromise
}
@@ -240,21 +199,17 @@ class Npm extends EventEmitter {
this.#title = t
}
- async [_load] () {
- const node = this.time('npm:load:whichnode', () => {
- try {
- return which.sync(process.argv[0])
- } catch {
- // TODO should we throw here?
+ async #load () {
+ await this.time('npm:load:whichnode', async () => {
+ // TODO should we throw here?
+ const node = await which(process.argv[0]).catch(() => {})
+ if (node && node.toUpperCase() !== process.execPath.toUpperCase()) {
+ log.verbose('node symlink', node)
+ process.execPath = node
+ this.config.execPath = node
}
})
- if (node && node.toUpperCase() !== process.execPath.toUpperCase()) {
- log.verbose('node symlink', node)
- process.execPath = node
- this.config.execPath = node
- }
-
await this.time('npm:load:configload', () => this.config.load())
// mkdir this separately since the logs dir can be set to
@@ -323,6 +278,18 @@ class Npm extends EventEmitter {
this.config.set('scope', `@${configScope}`, this.config.find('scope'))
}
})
+
+ if (this.config.get('force')) {
+ log.warn('using --force', 'Recommended protections disabled.')
+ }
+ }
+
+ get isShellout () {
+ return this.#command?.constructor?.isShellout
+ }
+
+ get command () {
+ return this.#command?.name
}
get flatOptions () {
@@ -346,6 +313,10 @@ class Npm extends EventEmitter {
return this.flatOptions.color
}
+ get logColor () {
+ return this.flatOptions.logColor
+ }
+
get chalk () {
if (!this.#chalk) {
let level = chalk.level
@@ -361,10 +332,6 @@ class Npm extends EventEmitter {
return this.config.get('global') || this.config.get('location') === 'global'
}
- get logColor () {
- return this.flatOptions.logColor
- }
-
get silent () {
return this.flatOptions.silent
}
@@ -401,6 +368,10 @@ class Npm extends EventEmitter {
return this.#timers.file
}
+ get npmRoot () {
+ return this.#npmRoot
+ }
+
get cache () {
return this.config.get('cache')
}
@@ -425,6 +396,10 @@ class Npm extends EventEmitter {
this.config.localPrefix = r
}
+ get localPackage () {
+ return this.config.localPackage
+ }
+
get globalDir () {
return process.platform !== 'win32'
? resolve(this.globalPrefix, 'lib', 'node_modules')
diff --git a/deps/npm/lib/package-url-cmd.js b/deps/npm/lib/package-url-cmd.js
index eac2bbe1b6..20e6a16fe1 100644
--- a/deps/npm/lib/package-url-cmd.js
+++ b/deps/npm/lib/package-url-cmd.js
@@ -9,7 +9,6 @@ const log = require('./utils/log-shim')
const BaseCommand = require('./base-command.js')
class PackageUrlCommand extends BaseCommand {
- static ignoreImplicitWorkspace = false
static params = [
'browser',
'registry',
@@ -18,6 +17,8 @@ class PackageUrlCommand extends BaseCommand {
'include-workspace-root',
]
+ static workspaces = true
+ static ignoreImplicitWorkspace = false
static usage = ['[<pkgname> [<pkgname> ...]]']
async exec (args) {
@@ -41,11 +42,11 @@ class PackageUrlCommand extends BaseCommand {
}
}
- async execWorkspaces (args, filters) {
+ async execWorkspaces (args) {
if (args && args.length) {
return this.exec(args)
}
- await this.setWorkspaces(filters)
+ await this.setWorkspaces()
return this.exec(this.workspacePaths)
}
diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js
index 0f401d6572..9ddbafd46f 100644
--- a/deps/npm/lib/utils/config/definitions.js
+++ b/deps/npm/lib/utils/config/definitions.js
@@ -163,7 +163,7 @@ define('access', {
`,
type: [null, 'restricted', 'public'],
description: `
- If do not want your scoped package to be publicly viewable (and
+ If you do not want your scoped package to be publicly viewable (and
installable) set \`--access=restricted\`.
Unscoped packages can not be set to \`restricted\`.
@@ -238,6 +238,7 @@ define('auth-type', {
type: ['legacy', 'web'],
description: `
What authentication strategy to use with \`login\`.
+ Note that if an \`otp\` config is given, this value will always be set to \`legacy\`.
`,
flatten,
})
@@ -848,7 +849,7 @@ define('global-style', {
type: Boolean,
description: `
Only install direct dependencies in the top level \`node_modules\`,
- but hoist on deeper dependendencies.
+ but hoist on deeper dependencies.
Sets \`--install-strategy=shallow\`.
`,
deprecated: `
@@ -1465,7 +1466,13 @@ define('otp', {
If not set, and a registry response fails with a challenge for a one-time
password, npm will prompt on the command line for one.
`,
- flatten,
+ flatten (key, obj, flatOptions) {
+ flatten(key, obj, flatOptions)
+ if (obj.otp) {
+ obj['auth-type'] = 'legacy'
+ flatten('auth-type', obj, flatOptions)
+ }
+ },
})
define('package', {
@@ -2021,7 +2028,7 @@ define('strict-peer-deps', {
even if doing so will result in some packages receiving a peer dependency
outside the range set in their package's \`peerDependencies\` object.
- When such and override is performed, a warning is printed, explaining the
+ When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If \`--strict-peer-deps\` is set,
then this warning is treated as a failure.
`,
@@ -2141,6 +2148,7 @@ define('unicode', {
When set to true, npm uses unicode characters in the tree output. When
false, it uses ascii characters instead of unicode glyphs.
`,
+ flatten,
})
define('update-notifier', {
diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js
index aee376120b..72c7b9fe45 100644
--- a/deps/npm/lib/utils/error-message.js
+++ b/deps/npm/lib/utils/error-message.js
@@ -5,7 +5,21 @@ const replaceInfo = require('./replace-info.js')
const { report } = require('./explain-eresolve.js')
const log = require('./log-shim')
-module.exports = (er, npm) => {
+const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n')
+
+const jsonError = (er, npm, { summary, detail }) => {
+ if (npm?.config.loaded && npm.config.get('json')) {
+ return {
+ error: {
+ code: er.code,
+ summary: messageText(summary),
+ detail: messageText(detail),
+ },
+ }
+ }
+}
+
+const errorMessage = (er, npm) => {
const short = []
const detail = []
const files = []
@@ -329,7 +343,7 @@ module.exports = (er, npm) => {
'Actual: ' +
JSON.stringify({
npm: npm.version,
- node: npm.config.loaded ? npm.config.get('node-version') : process.version,
+ node: process.version,
}),
].join('\n'),
])
@@ -402,5 +416,7 @@ module.exports = (er, npm) => {
break
}
- return { summary: short, detail, files }
+ return { summary: short, detail, files, json: jsonError(er, npm, { summary: short, detail }) }
}
+
+module.exports = errorMessage
diff --git a/deps/npm/lib/utils/exit-handler.js b/deps/npm/lib/utils/exit-handler.js
index a9e061de7a..b5fc7042bd 100644
--- a/deps/npm/lib/utils/exit-handler.js
+++ b/deps/npm/lib/utils/exit-handler.js
@@ -5,7 +5,6 @@ const log = require('./log-shim.js')
const errorMessage = require('./error-message.js')
const replaceInfo = require('./replace-info.js')
-const messageText = msg => msg.map(line => line.slice(1).join(' ')).join('\n')
const indent = (val) => Array.isArray(val) ? val.map(v => indent(v)) : ` ${val}`
let npm = null // set by the cli
@@ -144,7 +143,7 @@ const exitHandler = err => {
// will presumably print its own errors and exit with a proper status
// code if there's a problem. If we got an error with a code=0, then...
// something else went wrong along the way, so maybe an npm problem?
- const isShellout = npm.commandInstance && npm.commandInstance.constructor.isShellout
+ const isShellout = npm.isShellout
const quietShellout = isShellout && typeof err.code === 'number' && err.code
if (quietShellout) {
exitCode = err.code
@@ -181,7 +180,8 @@ const exitHandler = err => {
}
}
- const { summary, detail, files = [] } = errorMessage(err, npm)
+ const { summary, detail, json, files = [] } = errorMessage(err, npm)
+ jsonError = json
for (let [file, content] of files) {
file = `${npm.logPath}${file}`
@@ -189,8 +189,8 @@ const exitHandler = err => {
try {
fs.writeFileSync(file, content)
detail.push(['', `\n\nFor a full report see:\n${file}`])
- } catch (err) {
- log.warn('', `Could not write error message to ${file} due to ${err}`)
+ } catch (logFileErr) {
+ log.warn('', `Could not write error message to ${file} due to ${logFileErr}`)
}
}
@@ -198,16 +198,6 @@ const exitHandler = err => {
log.error(...errline)
}
- if (hasLoadedNpm && npm.config.get('json')) {
- jsonError = {
- error: {
- code: err.code,
- summary: messageText(summary),
- detail: messageText(detail),
- },
- }
- }
-
if (typeof err.errno === 'number') {
exitCode = err.errno
} else if (typeof err.code === 'number') {
diff --git a/deps/npm/lib/utils/explain-dep.js b/deps/npm/lib/utils/explain-dep.js
index cd53a22696..5825802649 100644
--- a/deps/npm/lib/utils/explain-dep.js
+++ b/deps/npm/lib/utils/explain-dep.js
@@ -103,13 +103,13 @@ const explainDependents = ({ name, dependents }, depth, color) => {
const maxLen = 50
const showNames = []
for (let i = max; i < dependents.length; i++) {
- const { from: { name = 'the root project' } } = dependents[i]
- len += name.length
+ const { from: { name: depName = 'the root project' } } = dependents[i]
+ len += depName.length
if (len >= maxLen && i < dependents.length - 1) {
showNames.push('...')
break
}
- showNames.push(name)
+ showNames.push(depName)
}
const show = `(${showNames.join(', ')})`
messages.push(`${dependents.length - max} more ${show}`)
diff --git a/deps/npm/lib/utils/log-file.js b/deps/npm/lib/utils/log-file.js
index 2935697ac9..f663997308 100644
--- a/deps/npm/lib/utils/log-file.js
+++ b/deps/npm/lib/utils/log-file.js
@@ -1,10 +1,10 @@
const os = require('os')
-const path = require('path')
+const { join, dirname, basename } = require('path')
const { format, promisify } = require('util')
-const rimraf = promisify(require('rimraf'))
const glob = promisify(require('glob'))
const MiniPass = require('minipass')
const fsMiniPass = require('fs-minipass')
+const fs = require('fs/promises')
const log = require('./log-shim')
const padZero = (n, length) => n.toString().padStart(length.toString().length, '0')
@@ -197,7 +197,7 @@ class LogFiles {
try {
const logPath = this.#getLogFilePath()
- const logGlob = path.join(path.dirname(logPath), path.basename(logPath)
+ const logGlob = join(dirname(logPath), basename(logPath)
// tell glob to only match digits
.replace(/\d/g, '[0123456789]')
// Handle the old (prior to 8.2.0) log file names which did not have a
@@ -217,7 +217,7 @@ class LogFiles {
for (const file of files.slice(0, toDelete)) {
try {
- await rimraf(file, { glob: false })
+ await fs.rm(file, { force: true })
} catch (e) {
log.silly('logfile', 'error removing log file', file, e)
}
diff --git a/deps/npm/lib/utils/npm-usage.js b/deps/npm/lib/utils/npm-usage.js
index 947a3073bc..b04ad33f9d 100644
--- a/deps/npm/lib/utils/npm-usage.js
+++ b/deps/npm/lib/utils/npm-usage.js
@@ -1,4 +1,3 @@
-const { dirname } = require('path')
const { commands } = require('./cmd-list')
const COL_MAX = 60
@@ -36,7 +35,7 @@ or on the command line via: npm <command> --key=value
More configuration info: npm help config
Configuration fields: npm help 7 config
-npm@${npm.version} ${dirname(dirname(__dirname))}`
+npm@${npm.version} ${npm.npmRoot}`
}
const cmdNames = () => {
diff --git a/deps/npm/lib/utils/open-url.js b/deps/npm/lib/utils/open-url.js
index 379640773f..f882d0c9d3 100644
--- a/deps/npm/lib/utils/open-url.js
+++ b/deps/npm/lib/utils/open-url.js
@@ -31,7 +31,7 @@ const open = async (npm, url, errMsg, isFile) => {
if (!/^https?:$/.test(new URL(url).protocol)) {
throw new Error()
}
- } catch (_) {
+ } catch {
throw new Error('Invalid URL: ' + url)
}
}
diff --git a/deps/npm/lib/utils/queryable.js b/deps/npm/lib/utils/queryable.js
index 7c5bb7fe87..6acc1758ce 100644
--- a/deps/npm/lib/utils/queryable.js
+++ b/deps/npm/lib/utils/queryable.js
@@ -1,5 +1,4 @@
const util = require('util')
-const _data = Symbol('data')
const _delete = Symbol('delete')
const _append = Symbol('append')
@@ -236,6 +235,8 @@ const setter = ({ data, key, value, force }) => {
}
class Queryable {
+ #data = null
+
constructor (obj) {
if (!obj || typeof obj !== 'object') {
throw Object.assign(new Error('Queryable needs an object to query properties from.'), {
@@ -243,7 +244,7 @@ class Queryable {
})
}
- this[_data] = obj
+ this.#data = obj
}
query (queries) {
@@ -251,12 +252,12 @@ class Queryable {
// with the legacy API lib/view.js is consuming, if at some point
// we refactor that command then we can revisit making this nicer
if (queries === '') {
- return { '': this[_data] }
+ return { '': this.#data }
}
const q = query =>
getter({
- data: this[_data],
+ data: this.#data,
key: query,
})
@@ -283,7 +284,7 @@ class Queryable {
// and assigns `value` to the last property of the query chain
set (query, value, { force } = {}) {
setter({
- data: this[_data],
+ data: this.#data,
key: query,
value,
force,
@@ -293,14 +294,14 @@ class Queryable {
// deletes the value of the property found at `query`
delete (query) {
setter({
- data: this[_data],
+ data: this.#data,
key: query,
value: _delete,
})
}
toJSON () {
- return this[_data]
+ return this.#data
}
[util.inspect.custom] () {
diff --git a/deps/npm/lib/utils/read-user-info.js b/deps/npm/lib/utils/read-user-info.js
index ac24396c6a..26d5b36d55 100644
--- a/deps/npm/lib/utils/read-user-info.js
+++ b/deps/npm/lib/utils/read-user-info.js
@@ -28,7 +28,7 @@ function readOTP (msg = otpPrompt, otp, isRetry) {
}
return read({ prompt: msg, default: otp || '' })
- .then((otp) => readOTP(msg, otp, true))
+ .then((rOtp) => readOTP(msg, rOtp, true))
}
function readPassword (msg = passwordPrompt, password, isRetry) {
@@ -37,7 +37,7 @@ function readPassword (msg = passwordPrompt, password, isRetry) {
}
return read({ prompt: msg, silent: true, default: password || '' })
- .then((password) => readPassword(msg, password, true))
+ .then((rPassword) => readPassword(msg, rPassword, true))
}
function readUsername (msg = usernamePrompt, username, isRetry) {
@@ -51,7 +51,7 @@ function readUsername (msg = usernamePrompt, username, isRetry) {
}
return read({ prompt: msg, default: username || '' })
- .then((username) => readUsername(msg, username, true))
+ .then((rUsername) => readUsername(msg, rUsername, true))
}
function readEmail (msg = emailPrompt, email, isRetry) {
diff --git a/deps/npm/lib/utils/reify-output.js b/deps/npm/lib/utils/reify-output.js
index b5c3a593b8..5ac7fa4b01 100644
--- a/deps/npm/lib/utils/reify-output.js
+++ b/deps/npm/lib/utils/reify-output.js
@@ -12,7 +12,7 @@
const log = require('./log-shim.js')
const { depth } = require('treeverse')
const ms = require('ms')
-const auditReport = require('npm-audit-report')
+const npmAuditReport = require('npm-audit-report')
const { readTree: getFundingInfo } = require('libnpmfund')
const auditError = require('./audit-error.js')
@@ -112,7 +112,7 @@ const getAuditReport = (npm, report) => {
const defaultAuditLevel = npm.command !== 'audit' ? 'none' : 'low'
const auditLevel = npm.flatOptions.auditLevel || defaultAuditLevel
- const res = auditReport(report, {
+ const res = npmAuditReport(report, {
reporter,
...npm.flatOptions,
auditLevel,
diff --git a/deps/npm/lib/workspaces/get-workspaces.js b/deps/npm/lib/workspaces/get-workspaces.js
index 373af1d689..2ac043d5f3 100644
--- a/deps/npm/lib/workspaces/get-workspaces.js
+++ b/deps/npm/lib/workspaces/get-workspaces.js
@@ -42,7 +42,7 @@ const getWorkspaces = async (filters, { path, includeWorkspaceRoot, relativeFrom
let msg = '!'
if (filters.length) {
msg = `:\n ${filters.reduce(
- (res, filterArg) => `${res} --workspace=${filterArg}`, '')}`
+ (acc, filterArg) => `${acc} --workspace=${filterArg}`, '')}`
}
throw new Error(`No workspaces found${msg}`)
diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1
index 7cfb97a9bd..91381c80c2 100644
--- a/deps/npm/man/man1/npm-access.1
+++ b/deps/npm/man/man1/npm-access.1
@@ -1,4 +1,4 @@
-.TH "NPM-ACCESS" "1" "December 2022" "" ""
+.TH "NPM-ACCESS" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-access\fR - Set access level on published packages
.SS "Synopsis"
@@ -14,6 +14,8 @@ npm access grant <read-only|read-write> <scope:team> \[lB]<package>\[rB]
npm access revoke <scope:team> \[lB]<package>\[rB]
.fi
.RE
+.P
+Note: This command is unaware of workspaces.
.SS "Description"
.P
Used to set access controls on private packages.
diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1
index e5de0dff8f..4e9a687fb6 100644
--- a/deps/npm/man/man1/npm-adduser.1
+++ b/deps/npm/man/man1/npm-adduser.1
@@ -1,4 +1,4 @@
-.TH "NPM-ADDUSER" "1" "December 2022" "" ""
+.TH "NPM-ADDUSER" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-adduser\fR - Add a registry user account
.SS "Synopsis"
@@ -71,7 +71,7 @@ Type: "legacy" or "web"
.RE 0
.P
-What authentication strategy to use with \fBlogin\fR.
+What authentication strategy to use with \fBlogin\fR. Note that if an \fBotp\fR config is given, this value will always be set to \fBlegacy\fR.
.SS "See Also"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-audit.1 b/deps/npm/man/man1/npm-audit.1
index e9d4063a5c..f99fa41719 100644
--- a/deps/npm/man/man1/npm-audit.1
+++ b/deps/npm/man/man1/npm-audit.1
@@ -1,4 +1,4 @@
-.TH "NPM-AUDIT" "1" "December 2022" "" ""
+.TH "NPM-AUDIT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-audit\fR - Run a security audit
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1
index 7d057e965a..61d2835a91 100644
--- a/deps/npm/man/man1/npm-bugs.1
+++ b/deps/npm/man/man1/npm-bugs.1
@@ -1,4 +1,4 @@
-.TH "NPM-BUGS" "1" "December 2022" "" ""
+.TH "NPM-BUGS" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-bugs\fR - Report bugs for a package in a web browser
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1
index 1cd9102728..026f08d17d 100644
--- a/deps/npm/man/man1/npm-cache.1
+++ b/deps/npm/man/man1/npm-cache.1
@@ -1,4 +1,4 @@
-.TH "NPM-CACHE" "1" "December 2022" "" ""
+.TH "NPM-CACHE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-cache\fR - Manipulates packages cache
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-ci.1 b/deps/npm/man/man1/npm-ci.1
index e5fa670750..9335c9aec4 100644
--- a/deps/npm/man/man1/npm-ci.1
+++ b/deps/npm/man/man1/npm-ci.1
@@ -1,4 +1,4 @@
-.TH "NPM-CI" "1" "December 2022" "" ""
+.TH "NPM-CI" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-ci\fR - Clean install a project
.SS "Synopsis"
@@ -142,7 +142,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBomit\fR"
.RS 0
.IP \(bu 4
@@ -172,7 +172,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1
index 2d66e7e042..c2f5d2a250 100644
--- a/deps/npm/man/man1/npm-completion.1
+++ b/deps/npm/man/man1/npm-completion.1
@@ -1,4 +1,4 @@
-.TH "NPM-COMPLETION" "1" "December 2022" "" ""
+.TH "NPM-COMPLETION" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-completion\fR - Tab Completion for npm
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1
index ea57fe94b0..1f4e831af8 100644
--- a/deps/npm/man/man1/npm-config.1
+++ b/deps/npm/man/man1/npm-config.1
@@ -1,4 +1,4 @@
-.TH "NPM-CONFIG" "1" "December 2022" "" ""
+.TH "NPM-CONFIG" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-config\fR - Manage the npm configuration files
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1
index bbd1fc413d..ff45a8d0fd 100644
--- a/deps/npm/man/man1/npm-dedupe.1
+++ b/deps/npm/man/man1/npm-dedupe.1
@@ -1,4 +1,4 @@
-.TH "NPM-DEDUPE" "1" "December 2022" "" ""
+.TH "NPM-DEDUPE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-dedupe\fR - Reduce duplication in the package tree
.SS "Synopsis"
@@ -98,7 +98,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBstrict-peer-deps\fR"
.RS 0
.IP \(bu 4
@@ -112,7 +112,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1
index e97357b5bc..ad4f34b53c 100644
--- a/deps/npm/man/man1/npm-deprecate.1
+++ b/deps/npm/man/man1/npm-deprecate.1
@@ -1,4 +1,4 @@
-.TH "NPM-DEPRECATE" "1" "December 2022" "" ""
+.TH "NPM-DEPRECATE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-deprecate\fR - Deprecate a version of a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-diff.1 b/deps/npm/man/man1/npm-diff.1
index b9f11879b7..410548534a 100644
--- a/deps/npm/man/man1/npm-diff.1
+++ b/deps/npm/man/man1/npm-diff.1
@@ -1,4 +1,4 @@
-.TH "NPM-DIFF" "1" "December 2022" "" ""
+.TH "NPM-DIFF" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-diff\fR - The registry diff command
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1
index bf05b601a8..f87010d601 100644
--- a/deps/npm/man/man1/npm-dist-tag.1
+++ b/deps/npm/man/man1/npm-dist-tag.1
@@ -1,4 +1,4 @@
-.TH "NPM-DIST-TAG" "1" "December 2022" "" ""
+.TH "NPM-DIST-TAG" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-dist-tag\fR - Modify package distribution tags
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1
index d590181391..c3832ae6f5 100644
--- a/deps/npm/man/man1/npm-docs.1
+++ b/deps/npm/man/man1/npm-docs.1
@@ -1,4 +1,4 @@
-.TH "NPM-DOCS" "1" "December 2022" "" ""
+.TH "NPM-DOCS" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-docs\fR - Open documentation for a package in a web browser
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1
index 776d50ea8e..a33e7acf62 100644
--- a/deps/npm/man/man1/npm-doctor.1
+++ b/deps/npm/man/man1/npm-doctor.1
@@ -1,4 +1,4 @@
-.TH "NPM-DOCTOR" "1" "December 2022" "" ""
+.TH "NPM-DOCTOR" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-doctor\fR - Check your npm environment
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1
index 80f7a55df5..4b933ac01c 100644
--- a/deps/npm/man/man1/npm-edit.1
+++ b/deps/npm/man/man1/npm-edit.1
@@ -1,4 +1,4 @@
-.TH "NPM-EDIT" "1" "December 2022" "" ""
+.TH "NPM-EDIT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-edit\fR - Edit an installed package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-exec.1 b/deps/npm/man/man1/npm-exec.1
index b13c9f3d21..b8b6cc7e96 100644
--- a/deps/npm/man/man1/npm-exec.1
+++ b/deps/npm/man/man1/npm-exec.1
@@ -1,4 +1,4 @@
-.TH "NPM-EXEC" "1" "December 2022" "" ""
+.TH "NPM-EXEC" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-exec\fR - Run a command from a local or remote npm package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-explain.1 b/deps/npm/man/man1/npm-explain.1
index 6897f44819..b1b5305d0d 100644
--- a/deps/npm/man/man1/npm-explain.1
+++ b/deps/npm/man/man1/npm-explain.1
@@ -1,4 +1,4 @@
-.TH "NPM-EXPLAIN" "1" "December 2022" "" ""
+.TH "NPM-EXPLAIN" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-explain\fR - Explain installed packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1
index fed8a1b25a..de402db28c 100644
--- a/deps/npm/man/man1/npm-explore.1
+++ b/deps/npm/man/man1/npm-explore.1
@@ -1,4 +1,4 @@
-.TH "NPM-EXPLORE" "1" "December 2022" "" ""
+.TH "NPM-EXPLORE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-explore\fR - Browse an installed package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-find-dupes.1 b/deps/npm/man/man1/npm-find-dupes.1
index fe29d9dd7f..5ec681c48c 100644
--- a/deps/npm/man/man1/npm-find-dupes.1
+++ b/deps/npm/man/man1/npm-find-dupes.1
@@ -1,4 +1,4 @@
-.TH "NPM-FIND-DUPES" "1" "December 2022" "" ""
+.TH "NPM-FIND-DUPES" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-find-dupes\fR - Find duplication in the package tree
.SS "Synopsis"
@@ -45,7 +45,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBstrict-peer-deps\fR"
.RS 0
.IP \(bu 4
@@ -59,7 +59,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-fund.1 b/deps/npm/man/man1/npm-fund.1
index b5f2cbdd58..7c1fe64f03 100644
--- a/deps/npm/man/man1/npm-fund.1
+++ b/deps/npm/man/man1/npm-fund.1
@@ -1,4 +1,4 @@
-.TH "NPM-FUND" "1" "December 2022" "" ""
+.TH "NPM-FUND" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-fund\fR - Retrieve funding information
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1
index 939aa4fd34..5d7a40e7ca 100644
--- a/deps/npm/man/man1/npm-help-search.1
+++ b/deps/npm/man/man1/npm-help-search.1
@@ -1,4 +1,4 @@
-.TH "NPM-HELP-SEARCH" "1" "December 2022" "" ""
+.TH "NPM-HELP-SEARCH" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-help-search\fR - Search npm help documentation
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1
index 15b73a5ce7..c0e77e0b5f 100644
--- a/deps/npm/man/man1/npm-help.1
+++ b/deps/npm/man/man1/npm-help.1
@@ -1,4 +1,4 @@
-.TH "NPM-HELP" "1" "December 2022" "" ""
+.TH "NPM-HELP" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-help\fR - Get help on npm
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-hook.1 b/deps/npm/man/man1/npm-hook.1
index d38ad36171..8ba80f625c 100644
--- a/deps/npm/man/man1/npm-hook.1
+++ b/deps/npm/man/man1/npm-hook.1
@@ -1,4 +1,4 @@
-.TH "NPM-HOOK" "1" "December 2022" "" ""
+.TH "NPM-HOOK" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-hook\fR - Manage registry hooks
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1
index 298bdecf3e..f5fc5fbc35 100644
--- a/deps/npm/man/man1/npm-init.1
+++ b/deps/npm/man/man1/npm-init.1
@@ -1,11 +1,11 @@
-.TH "NPM-INIT" "1" "December 2022" "" ""
+.TH "NPM-INIT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-init\fR - Create a package.json file
.SS "Synopsis"
.P
.RS 2
.nf
-npm init <package-spec> (same as `npx <package-spec>)
+npm init <package-spec> (same as `npx <package-spec>`)
npm init <@scope> (same as `npx <@scope>/create`)
aliases: create, innit
diff --git a/deps/npm/man/man1/npm-install-ci-test.1 b/deps/npm/man/man1/npm-install-ci-test.1
index 33abfcad8e..96b0bf5acc 100644
--- a/deps/npm/man/man1/npm-install-ci-test.1
+++ b/deps/npm/man/man1/npm-install-ci-test.1
@@ -1,4 +1,4 @@
-.TH "NPM-INSTALL-CI-TEST" "1" "December 2022" "" ""
+.TH "NPM-INSTALL-CI-TEST" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-install-ci-test\fR - Install a project with a clean slate and run tests
.SS "Synopsis"
@@ -90,7 +90,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBomit\fR"
.RS 0
.IP \(bu 4
@@ -120,7 +120,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1
index 9f3914208a..5b5b6823cf 100644
--- a/deps/npm/man/man1/npm-install-test.1
+++ b/deps/npm/man/man1/npm-install-test.1
@@ -1,4 +1,4 @@
-.TH "NPM-INSTALL-TEST" "1" "December 2022" "" ""
+.TH "NPM-INSTALL-TEST" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-install-test\fR - Install package(s) and run tests
.SS "Synopsis"
@@ -90,7 +90,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBomit\fR"
.RS 0
.IP \(bu 4
@@ -120,7 +120,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1
index 3211b0c6f1..55e5abe3f8 100644
--- a/deps/npm/man/man1/npm-install.1
+++ b/deps/npm/man/man1/npm-install.1
@@ -1,4 +1,4 @@
-.TH "NPM-INSTALL" "1" "December 2022" "" ""
+.TH "NPM-INSTALL" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-install\fR - Install a package
.SS "Synopsis"
@@ -452,7 +452,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBomit\fR"
.RS 0
.IP \(bu 4
@@ -482,7 +482,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1
index adbc8b4db5..42ecdee92a 100644
--- a/deps/npm/man/man1/npm-link.1
+++ b/deps/npm/man/man1/npm-link.1
@@ -1,4 +1,4 @@
-.TH "NPM-LINK" "1" "December 2022" "" ""
+.TH "NPM-LINK" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-link\fR - Symlink a package folder
.SS "Synopsis"
@@ -157,7 +157,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBstrict-peer-deps\fR"
.RS 0
.IP \(bu 4
@@ -171,7 +171,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-login.1 b/deps/npm/man/man1/npm-login.1
index 1a10ce18cd..3b99aefeec 100644
--- a/deps/npm/man/man1/npm-login.1
+++ b/deps/npm/man/man1/npm-login.1
@@ -1,4 +1,4 @@
-.TH "NPM-LOGIN" "1" "December 2022" "" ""
+.TH "NPM-LOGIN" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-login\fR - Login to a registry user account
.SS "Synopsis"
@@ -75,7 +75,7 @@ Type: "legacy" or "web"
.RE 0
.P
-What authentication strategy to use with \fBlogin\fR.
+What authentication strategy to use with \fBlogin\fR. Note that if an \fBotp\fR config is given, this value will always be set to \fBlegacy\fR.
.SS "See Also"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1
index 00201c9780..3bb5aa6714 100644
--- a/deps/npm/man/man1/npm-logout.1
+++ b/deps/npm/man/man1/npm-logout.1
@@ -1,4 +1,4 @@
-.TH "NPM-LOGOUT" "1" "December 2022" "" ""
+.TH "NPM-LOGOUT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-logout\fR - Log out of the registry
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1
index 114cd16526..2458a585b7 100644
--- a/deps/npm/man/man1/npm-ls.1
+++ b/deps/npm/man/man1/npm-ls.1
@@ -1,4 +1,4 @@
-.TH "NPM-LS" "1" "December 2022" "" ""
+.TH "NPM-LS" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-ls\fR - List installed packages
.SS "Synopsis"
@@ -20,7 +20,7 @@ Positional arguments are \fBname@version-range\fR identifiers, which will limit
.P
.RS 2
.nf
-npm@9.2.0 /path/to/npm
+npm@9.3.0 /path/to/npm
└─┬ init-package-json@0.0.4
└── promzard@0.1.5
.fi
diff --git a/deps/npm/man/man1/npm-org.1 b/deps/npm/man/man1/npm-org.1
index d070b6a941..ba4ee6c72a 100644
--- a/deps/npm/man/man1/npm-org.1
+++ b/deps/npm/man/man1/npm-org.1
@@ -1,4 +1,4 @@
-.TH "NPM-ORG" "1" "December 2022" "" ""
+.TH "NPM-ORG" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-org\fR - Manage orgs
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1
index 0893d2d7cc..0cd7762886 100644
--- a/deps/npm/man/man1/npm-outdated.1
+++ b/deps/npm/man/man1/npm-outdated.1
@@ -1,4 +1,4 @@
-.TH "NPM-OUTDATED" "1" "December 2022" "" ""
+.TH "NPM-OUTDATED" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-outdated\fR - Check for outdated packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1
index eb30d26fa6..f2015740b0 100644
--- a/deps/npm/man/man1/npm-owner.1
+++ b/deps/npm/man/man1/npm-owner.1
@@ -1,4 +1,4 @@
-.TH "NPM-OWNER" "1" "December 2022" "" ""
+.TH "NPM-OWNER" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-owner\fR - Manage package owners
.SS "Synopsis"
@@ -12,8 +12,6 @@ npm owner ls <package-spec>
alias: author
.fi
.RE
-.P
-Note: This command is unaware of workspaces.
.SS "Description"
.P
Manage ownership of published packages.
diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1
index ccb49505cd..934bc9cf4e 100644
--- a/deps/npm/man/man1/npm-pack.1
+++ b/deps/npm/man/man1/npm-pack.1
@@ -1,4 +1,4 @@
-.TH "NPM-PACK" "1" "December 2022" "" ""
+.TH "NPM-PACK" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-pack\fR - Create a tarball from a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1
index 79b3258e33..59c5191676 100644
--- a/deps/npm/man/man1/npm-ping.1
+++ b/deps/npm/man/man1/npm-ping.1
@@ -1,4 +1,4 @@
-.TH "NPM-PING" "1" "December 2022" "" ""
+.TH "NPM-PING" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-ping\fR - Ping npm registry
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-pkg.1 b/deps/npm/man/man1/npm-pkg.1
index ea1233faea..4f3437fb2f 100644
--- a/deps/npm/man/man1/npm-pkg.1
+++ b/deps/npm/man/man1/npm-pkg.1
@@ -1,4 +1,4 @@
-.TH "NPM-PKG" "1" "December 2022" "" ""
+.TH "NPM-PKG" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-pkg\fR - Manages your package.json
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1
index 0d1fcab353..c51646626a 100644
--- a/deps/npm/man/man1/npm-prefix.1
+++ b/deps/npm/man/man1/npm-prefix.1
@@ -1,4 +1,4 @@
-.TH "NPM-PREFIX" "1" "December 2022" "" ""
+.TH "NPM-PREFIX" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-prefix\fR - Display prefix
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-profile.1 b/deps/npm/man/man1/npm-profile.1
index 4a03f77be0..cd5cba9515 100644
--- a/deps/npm/man/man1/npm-profile.1
+++ b/deps/npm/man/man1/npm-profile.1
@@ -1,4 +1,4 @@
-.TH "NPM-PROFILE" "1" "December 2022" "" ""
+.TH "NPM-PROFILE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-profile\fR - Change settings on your registry profile
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1
index 958505dee0..928ccd5d80 100644
--- a/deps/npm/man/man1/npm-prune.1
+++ b/deps/npm/man/man1/npm-prune.1
@@ -1,4 +1,4 @@
-.TH "NPM-PRUNE" "1" "December 2022" "" ""
+.TH "NPM-PRUNE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-prune\fR - Remove extraneous packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1
index e191b644e0..d75c7b39eb 100644
--- a/deps/npm/man/man1/npm-publish.1
+++ b/deps/npm/man/man1/npm-publish.1
@@ -1,4 +1,4 @@
-.TH "NPM-PUBLISH" "1" "December 2022" "" ""
+.TH "NPM-PUBLISH" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-publish\fR - Publish a package
.SS "Synopsis"
@@ -84,7 +84,7 @@ Type: null, "restricted", or "public"
.RE 0
.P
-If do not want your scoped package to be publicly viewable (and installable) set \fB--access=restricted\fR.
+If you do not want your scoped package to be publicly viewable (and installable) set \fB--access=restricted\fR.
.P
Unscoped packages can not be set to \fBrestricted\fR.
.P
diff --git a/deps/npm/man/man1/npm-query.1 b/deps/npm/man/man1/npm-query.1
index 657b6a6a37..0e6d444e39 100644
--- a/deps/npm/man/man1/npm-query.1
+++ b/deps/npm/man/man1/npm-query.1
@@ -1,4 +1,4 @@
-.TH "NPM-QUERY" "1" "December 2022" "" ""
+.TH "NPM-QUERY" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-query\fR - Dependency selector query
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1
index 6a5f20689f..ce56c880b6 100644
--- a/deps/npm/man/man1/npm-rebuild.1
+++ b/deps/npm/man/man1/npm-rebuild.1
@@ -1,4 +1,4 @@
-.TH "NPM-REBUILD" "1" "December 2022" "" ""
+.TH "NPM-REBUILD" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-rebuild\fR - Rebuild a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1
index 6a7b57ed67..836ae8de25 100644
--- a/deps/npm/man/man1/npm-repo.1
+++ b/deps/npm/man/man1/npm-repo.1
@@ -1,4 +1,4 @@
-.TH "NPM-REPO" "1" "December 2022" "" ""
+.TH "NPM-REPO" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-repo\fR - Open package repository page in the browser
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1
index e9e300ebff..00b83e280b 100644
--- a/deps/npm/man/man1/npm-restart.1
+++ b/deps/npm/man/man1/npm-restart.1
@@ -1,4 +1,4 @@
-.TH "NPM-RESTART" "1" "December 2022" "" ""
+.TH "NPM-RESTART" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-restart\fR - Restart a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1
index 5157948d23..9333aa4545 100644
--- a/deps/npm/man/man1/npm-root.1
+++ b/deps/npm/man/man1/npm-root.1
@@ -1,4 +1,4 @@
-.TH "NPM-ROOT" "1" "December 2022" "" ""
+.TH "NPM-ROOT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-root\fR - Display npm root
.SS "Synopsis"
@@ -8,6 +8,8 @@
npm root
.fi
.RE
+.P
+Note: This command is unaware of workspaces.
.SS "Description"
.P
Print the effective \fBnode_modules\fR folder to standard out.
diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1
index c4f97ca328..44a6a76a8b 100644
--- a/deps/npm/man/man1/npm-run-script.1
+++ b/deps/npm/man/man1/npm-run-script.1
@@ -1,4 +1,4 @@
-.TH "NPM-RUN-SCRIPT" "1" "December 2022" "" ""
+.TH "NPM-RUN-SCRIPT" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-run-script\fR - Run arbitrary package scripts
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1
index 6a7f6aa982..3fe6f69992 100644
--- a/deps/npm/man/man1/npm-search.1
+++ b/deps/npm/man/man1/npm-search.1
@@ -1,4 +1,4 @@
-.TH "NPM-SEARCH" "1" "December 2022" "" ""
+.TH "NPM-SEARCH" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-search\fR - Search for packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1
index f158ea070f..875f0b58ba 100644
--- a/deps/npm/man/man1/npm-shrinkwrap.1
+++ b/deps/npm/man/man1/npm-shrinkwrap.1
@@ -1,4 +1,4 @@
-.TH "NPM-SHRINKWRAP" "1" "December 2022" "" ""
+.TH "NPM-SHRINKWRAP" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-shrinkwrap\fR - Lock down dependency versions for publication
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1
index 28fa89780d..627d11b366 100644
--- a/deps/npm/man/man1/npm-star.1
+++ b/deps/npm/man/man1/npm-star.1
@@ -1,4 +1,4 @@
-.TH "NPM-STAR" "1" "December 2022" "" ""
+.TH "NPM-STAR" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-star\fR - Mark your favorite packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1
index 60619f979e..6660429c89 100644
--- a/deps/npm/man/man1/npm-stars.1
+++ b/deps/npm/man/man1/npm-stars.1
@@ -1,4 +1,4 @@
-.TH "NPM-STARS" "1" "December 2022" "" ""
+.TH "NPM-STARS" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-stars\fR - View packages marked as favorites
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1
index c9f72e52d1..abdc41d8c5 100644
--- a/deps/npm/man/man1/npm-start.1
+++ b/deps/npm/man/man1/npm-start.1
@@ -1,4 +1,4 @@
-.TH "NPM-START" "1" "December 2022" "" ""
+.TH "NPM-START" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-start\fR - Start a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1
index 8c2a7e4456..9c9437aafe 100644
--- a/deps/npm/man/man1/npm-stop.1
+++ b/deps/npm/man/man1/npm-stop.1
@@ -1,4 +1,4 @@
-.TH "NPM-STOP" "1" "December 2022" "" ""
+.TH "NPM-STOP" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-stop\fR - Stop a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1
index 35e18f7cdd..917dbce667 100644
--- a/deps/npm/man/man1/npm-team.1
+++ b/deps/npm/man/man1/npm-team.1
@@ -1,4 +1,4 @@
-.TH "NPM-TEAM" "1" "December 2022" "" ""
+.TH "NPM-TEAM" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-team\fR - Manage organization teams and team memberships
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1
index dde7dfdbff..5863931a62 100644
--- a/deps/npm/man/man1/npm-test.1
+++ b/deps/npm/man/man1/npm-test.1
@@ -1,4 +1,4 @@
-.TH "NPM-TEST" "1" "December 2022" "" ""
+.TH "NPM-TEST" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-test\fR - Test a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-token.1 b/deps/npm/man/man1/npm-token.1
index 868de1e51d..1c7f976201 100644
--- a/deps/npm/man/man1/npm-token.1
+++ b/deps/npm/man/man1/npm-token.1
@@ -1,4 +1,4 @@
-.TH "NPM-TOKEN" "1" "December 2022" "" ""
+.TH "NPM-TOKEN" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-token\fR - Manage your authentication tokens
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1
index 952dac51cb..231b203955 100644
--- a/deps/npm/man/man1/npm-uninstall.1
+++ b/deps/npm/man/man1/npm-uninstall.1
@@ -1,4 +1,4 @@
-.TH "NPM-UNINSTALL" "1" "December 2022" "" ""
+.TH "NPM-UNINSTALL" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-uninstall\fR - Remove a package
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1
index b2c8ca2f2c..99024be559 100644
--- a/deps/npm/man/man1/npm-unpublish.1
+++ b/deps/npm/man/man1/npm-unpublish.1
@@ -1,4 +1,4 @@
-.TH "NPM-UNPUBLISH" "1" "December 2022" "" ""
+.TH "NPM-UNPUBLISH" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-unpublish\fR - Remove a package from the registry
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-unstar.1 b/deps/npm/man/man1/npm-unstar.1
index b05159a0e5..8263c1aad3 100644
--- a/deps/npm/man/man1/npm-unstar.1
+++ b/deps/npm/man/man1/npm-unstar.1
@@ -1,4 +1,4 @@
-.TH "NPM-UNSTAR" "1" "December 2022" "" ""
+.TH "NPM-UNSTAR" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-unstar\fR - Remove an item from your favorite packages
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1
index 9f00dfb01a..644a6787de 100644
--- a/deps/npm/man/man1/npm-update.1
+++ b/deps/npm/man/man1/npm-update.1
@@ -1,4 +1,4 @@
-.TH "NPM-UPDATE" "1" "December 2022" "" ""
+.TH "NPM-UPDATE" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-update\fR - Update packages
.SS "Synopsis"
@@ -198,7 +198,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBomit\fR"
.RS 0
.IP \(bu 4
@@ -228,7 +228,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBpackage-lock\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1
index d76672560c..59248f1a4e 100644
--- a/deps/npm/man/man1/npm-version.1
+++ b/deps/npm/man/man1/npm-version.1
@@ -1,4 +1,4 @@
-.TH "NPM-VERSION" "1" "December 2022" "" ""
+.TH "NPM-VERSION" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-version\fR - Bump a package version
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1
index f4784653a7..8de0a2d9f7 100644
--- a/deps/npm/man/man1/npm-view.1
+++ b/deps/npm/man/man1/npm-view.1
@@ -1,4 +1,4 @@
-.TH "NPM-VIEW" "1" "December 2022" "" ""
+.TH "NPM-VIEW" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-view\fR - View registry info
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1
index 89db7bcf33..a609e66bf5 100644
--- a/deps/npm/man/man1/npm-whoami.1
+++ b/deps/npm/man/man1/npm-whoami.1
@@ -1,4 +1,4 @@
-.TH "NPM-WHOAMI" "1" "December 2022" "" ""
+.TH "NPM-WHOAMI" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm-whoami\fR - Display npm username
.SS "Synopsis"
diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1
index b759c6a58e..e29df213a0 100644
--- a/deps/npm/man/man1/npm.1
+++ b/deps/npm/man/man1/npm.1
@@ -1,4 +1,4 @@
-.TH "NPM" "1" "December 2022" "" ""
+.TH "NPM" "1" "January 2023" "" ""
.SH "NAME"
\fBnpm\fR - javascript package manager
.SS "Synopsis"
@@ -8,9 +8,11 @@
npm
.fi
.RE
+.P
+Note: This command is unaware of workspaces.
.SS "Version"
.P
-9.2.0
+9.3.0
.SS "Description"
.P
npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency conflicts intelligently.
@@ -80,7 +82,7 @@ User Configs: The file at \fB$HOME/.npmrc\fR is an ini-formatted list of configs
.IP \(bu 4
Global Configs: The file found at \fB./etc/npmrc\fR (relative to the global prefix will be parsed if it is found. See npm help prefix for more info on the global prefix. If the \fBglobalconfig\fR option is set in the cli, env, or user config, then that file is parsed instead.
.IP \(bu 4
-Defaults: npm's default configuration options are defined in lib/utils/config-defs.js. These must not be changed.
+Defaults: npm's default configuration options are defined in \fBlib/utils/config/definitions.js\fR. These must not be changed.
.RE 0
.P
diff --git a/deps/npm/man/man1/npx.1 b/deps/npm/man/man1/npx.1
index f718ed321d..ab3a83236b 100644
--- a/deps/npm/man/man1/npx.1
+++ b/deps/npm/man/man1/npx.1
@@ -1,4 +1,4 @@
-.TH "NPX" "1" "December 2022" "" ""
+.TH "NPX" "1" "January 2023" "" ""
.SH "NAME"
\fBnpx\fR - Run a command from a local or remote npm package
.SS "Synopsis"
diff --git a/deps/npm/man/man5/folders.5 b/deps/npm/man/man5/folders.5
index ea0acabd33..09870f292a 100644
--- a/deps/npm/man/man5/folders.5
+++ b/deps/npm/man/man5/folders.5
@@ -1,4 +1,4 @@
-.TH "FOLDERS" "5" "December 2022" "" ""
+.TH "FOLDERS" "5" "January 2023" "" ""
.SH "NAME"
\fBfolders\fR - Folder Structures Used by npm
.SS "Description"
diff --git a/deps/npm/man/man5/install.5 b/deps/npm/man/man5/install.5
index a6758e93d7..ecc6a9b723 100644
--- a/deps/npm/man/man5/install.5
+++ b/deps/npm/man/man5/install.5
@@ -1,4 +1,4 @@
-.TH "INSTALL" "5" "December 2022" "" ""
+.TH "INSTALL" "5" "January 2023" "" ""
.SH "NAME"
\fBinstall\fR - Download and install node and npm
.SS "Description"
@@ -7,11 +7,11 @@ To publish and install packages to and from the public npm registry, you must in
.SS "Overview"
.RS 0
.IP \(bu 4
-\fBChecking your version of npm and Node.js\fR \fI\(la#checking-your-version-of-npm-and-node-js\(ra\fR
+\fBChecking your version of npm and Node.js\fR \fI(Checking your version of npm and Node.js)\fR
.IP \(bu 4
-\fBUsing a Node version manager to install Node.js and npm\fR \fI\(la#using-a-node-version-manager-to-install-node-js-and-npm\(ra\fR
+\fBUsing a Node version manager to install Node.js and npm\fR \fI(Using a Node version manager to install Node.js and npm)\fR
.IP \(bu 4
-\fBUsing a Node installer to install Node.js and npm\fR \fI\(la#using-a-node-installer-to-install-node-js-and-npm\(ra\fR
+\fBUsing a Node installer to install Node.js and npm\fR \fI(Using a Node installer to install Node.js and npm)\fR
.RE 0
.SS "Checking your version of npm and Node.js"
diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5
index ea0acabd33..09870f292a 100644
--- a/deps/npm/man/man5/npm-global.5
+++ b/deps/npm/man/man5/npm-global.5
@@ -1,4 +1,4 @@
-.TH "FOLDERS" "5" "December 2022" "" ""
+.TH "FOLDERS" "5" "January 2023" "" ""
.SH "NAME"
\fBfolders\fR - Folder Structures Used by npm
.SS "Description"
diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5
index 8c6781b6a7..6d7c946a06 100644
--- a/deps/npm/man/man5/npm-json.5
+++ b/deps/npm/man/man5/npm-json.5
@@ -1,4 +1,4 @@
-.TH "PACKAGE.JSON" "5" "December 2022" "" ""
+.TH "PACKAGE.JSON" "5" "January 2023" "" ""
.SH "NAME"
\fBpackage.json\fR - Specifics of npm's package.json handling
.SS "Description"
diff --git a/deps/npm/man/man5/npm-shrinkwrap-json.5 b/deps/npm/man/man5/npm-shrinkwrap-json.5
index dd6eba1ea3..2e498029e4 100644
--- a/deps/npm/man/man5/npm-shrinkwrap-json.5
+++ b/deps/npm/man/man5/npm-shrinkwrap-json.5
@@ -1,4 +1,4 @@
-.TH "NPM-SHRINKWRAP.JSON" "5" "December 2022" "" ""
+.TH "NPM-SHRINKWRAP.JSON" "5" "January 2023" "" ""
.SH "NAME"
\fBnpm-shrinkwrap.json\fR - A publishable lockfile
.SS "Description"
diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5
index 4846826ebb..0828d2ea7b 100644
--- a/deps/npm/man/man5/npmrc.5
+++ b/deps/npm/man/man5/npmrc.5
@@ -1,4 +1,4 @@
-.TH "NPMRC" "5" "December 2022" "" ""
+.TH "NPMRC" "5" "January 2023" "" ""
.SH "NAME"
\fBnpmrc\fR - The npm config files
.SS "Description"
diff --git a/deps/npm/man/man5/package-json.5 b/deps/npm/man/man5/package-json.5
index 8c6781b6a7..6d7c946a06 100644
--- a/deps/npm/man/man5/package-json.5
+++ b/deps/npm/man/man5/package-json.5
@@ -1,4 +1,4 @@
-.TH "PACKAGE.JSON" "5" "December 2022" "" ""
+.TH "PACKAGE.JSON" "5" "January 2023" "" ""
.SH "NAME"
\fBpackage.json\fR - Specifics of npm's package.json handling
.SS "Description"
diff --git a/deps/npm/man/man5/package-lock-json.5 b/deps/npm/man/man5/package-lock-json.5
index 4170a9cd39..d10a93bc31 100644
--- a/deps/npm/man/man5/package-lock-json.5
+++ b/deps/npm/man/man5/package-lock-json.5
@@ -1,4 +1,4 @@
-.TH "PACKAGE-LOCK.JSON" "5" "December 2022" "" ""
+.TH "PACKAGE-LOCK.JSON" "5" "January 2023" "" ""
.SH "NAME"
\fBpackage-lock.json\fR - A manifestation of the manifest
.SS "Description"
diff --git a/deps/npm/man/man7/config.7 b/deps/npm/man/man7/config.7
index 9a0d98c4d5..6f8d20d6ef 100644
--- a/deps/npm/man/man7/config.7
+++ b/deps/npm/man/man7/config.7
@@ -1,4 +1,4 @@
-.TH "CONFIG" "7" "December 2022" "" ""
+.TH "CONFIG" "7" "January 2023" "" ""
.SH "NAME"
\fBconfig\fR - More than you probably want to know about npm configuration
.SS "Description"
@@ -161,7 +161,7 @@ Type: null, "restricted", or "public"
.RE 0
.P
-If do not want your scoped package to be publicly viewable (and installable) set \fB--access=restricted\fR.
+If you do not want your scoped package to be publicly viewable (and installable) set \fB--access=restricted\fR.
.P
Unscoped packages can not be set to \fBrestricted\fR.
.P
@@ -216,7 +216,7 @@ Type: "legacy" or "web"
.RE 0
.P
-What authentication strategy to use with \fBlogin\fR.
+What authentication strategy to use with \fBlogin\fR. Note that if an \fBotp\fR config is given, this value will always be set to \fBlegacy\fR.
.SS "\fBbefore\fR"
.RS 0
.IP \(bu 4
@@ -1445,7 +1445,7 @@ If set to \fBtrue\fR, and \fB--legacy-peer-deps\fR is not set, then \fIany\fR co
.P
By default, conflicting \fBpeerDependencies\fR deep in the dependency graph will be resolved using the nearest non-peer dependency specification, even if doing so will result in some packages receiving a peer dependency outside the range set in their package's \fBpeerDependencies\fR object.
.P
-When such and override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
+When such an override is performed, a warning is printed, explaining the conflict and the packages involved. If \fB--strict-peer-deps\fR is set, then this warning is treated as a failure.
.SS "\fBstrict-ssl\fR"
.RS 0
.IP \(bu 4
@@ -1770,7 +1770,7 @@ DEPRECATED: This option has been deprecated in favor of \fB--install-strategy=sh
.RE 0
.P
-Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependendencies. Sets \fB--install-strategy=shallow\fR.
+Only install direct dependencies in the top level \fBnode_modules\fR, but hoist on deeper dependencies. Sets \fB--install-strategy=shallow\fR.
.SS "\fBinit.author.email\fR"
.RS 0
.IP \(bu 4
diff --git a/deps/npm/man/man7/dependency-selectors.7 b/deps/npm/man/man7/dependency-selectors.7
index d10fc0e4cf..e3b0271a26 100644
--- a/deps/npm/man/man7/dependency-selectors.7
+++ b/deps/npm/man/man7/dependency-selectors.7
@@ -1,4 +1,4 @@
-.TH "QUERYING" "7" "December 2022" "" ""
+.TH "QUERYING" "7" "January 2023" "" ""
.SH "NAME"
\fBQuerying\fR - Dependency Selector Syntax & Querying
.SS "Description"
diff --git a/deps/npm/man/man7/developers.7 b/deps/npm/man/man7/developers.7
index 2614a67657..8b5184dcb6 100644
--- a/deps/npm/man/man7/developers.7
+++ b/deps/npm/man/man7/developers.7
@@ -1,4 +1,4 @@
-.TH "DEVELOPERS" "7" "December 2022" "" ""
+.TH "DEVELOPERS" "7" "January 2023" "" ""
.SH "NAME"
\fBdevelopers\fR - Developer Guide
.SS "Description"
diff --git a/deps/npm/man/man7/logging.7 b/deps/npm/man/man7/logging.7
index c605c3a69c..f894a4b36f 100644
--- a/deps/npm/man/man7/logging.7
+++ b/deps/npm/man/man7/logging.7
@@ -1,4 +1,4 @@
-.TH "LOGGING" "7" "December 2022" "" ""
+.TH "LOGGING" "7" "January 2023" "" ""
.SH "NAME"
\fBLogging\fR - Why, What & How We Log
.SS "Description"
diff --git a/deps/npm/man/man7/orgs.7 b/deps/npm/man/man7/orgs.7
index a87c11222e..1aefdbb414 100644
--- a/deps/npm/man/man7/orgs.7
+++ b/deps/npm/man/man7/orgs.7
@@ -1,4 +1,4 @@
-.TH "ORGS" "7" "December 2022" "" ""
+.TH "ORGS" "7" "January 2023" "" ""
.SH "NAME"
\fBorgs\fR - Working with Teams & Orgs
.SS "Description"
diff --git a/deps/npm/man/man7/package-spec.7 b/deps/npm/man/man7/package-spec.7
index f9da11f2c0..9c376719ce 100644
--- a/deps/npm/man/man7/package-spec.7
+++ b/deps/npm/man/man7/package-spec.7
@@ -1,4 +1,4 @@
-.TH "PACKAGE-SPEC" "7" "December 2022" "" ""
+.TH "PACKAGE-SPEC" "7" "January 2023" "" ""
.SH "NAME"
\fBpackage-spec\fR - Package name specifier
.SS "Description"
diff --git a/deps/npm/man/man7/registry.7 b/deps/npm/man/man7/registry.7
index a3368a441a..da418a4240 100644
--- a/deps/npm/man/man7/registry.7
+++ b/deps/npm/man/man7/registry.7
@@ -1,4 +1,4 @@
-.TH "REGISTRY" "7" "December 2022" "" ""
+.TH "REGISTRY" "7" "January 2023" "" ""
.SH "NAME"
\fBregistry\fR - The JavaScript Package Registry
.SS "Description"
@@ -15,7 +15,7 @@ The npm public registry is powered by a CouchDB database, of which there is a pu
.P
The registry URL used is determined by the scope of the package (see npm help scope. If no scope is specified, the default registry is used, which is supplied by the \fB\fBregistry\fR config\fR \fI\(la/using-npm/config#registry\(ra\fR parameter. See npm help config, npm help npmrc, and npm help config for more on managing npm's configuration. Authentication configuration such as auth tokens and certificates are configured specifically scoped to an individual registry. See \fBAuth Related Configuration\fR \fI\(la/configuring-npm/npmrc#auth-related-configuration\(ra\fR
.P
-When the default registry is used in a package-lock or shrinkwrap is has the special meaning of "the currently configured registry". If you create a lock file while using the default registry you can switch to another registry and npm will install packages from the new registry, but if you create a lock file while using a custom registry packages will be installed from that registry even after you change to another registry.
+When the default registry is used in a package-lock or shrinkwrap it has the special meaning of "the currently configured registry". If you create a lock file while using the default registry you can switch to another registry and npm will install packages from the new registry, but if you create a lock file while using a custom registry packages will be installed from that registry even after you change to another registry.
.SS "Does npm send any information about me back to the registry?"
.P
Yes.
diff --git a/deps/npm/man/man7/removal.7 b/deps/npm/man/man7/removal.7
index dbbeddaeca..aea330f2f6 100644
--- a/deps/npm/man/man7/removal.7
+++ b/deps/npm/man/man7/removal.7
@@ -1,4 +1,4 @@
-.TH "REMOVAL" "7" "December 2022" "" ""
+.TH "REMOVAL" "7" "January 2023" "" ""
.SH "NAME"
\fBremoval\fR - Cleaning the Slate
.SS "Synopsis"
@@ -24,7 +24,7 @@ Usually, the above instructions are sufficient. That will remove npm, but leave
.P
If that doesn't work, or if you require more drastic measures, continue reading.
.P
-Note that this is only necessary for globally-installed packages. Local installs are completely contained within a project's \fBnode_modules\fR folder. Delete that folder, and everything is gone less a package's install script is particularly ill-behaved).
+Note that this is only necessary for globally-installed packages. Local installs are completely contained within a project's \fBnode_modules\fR folder. Delete that folder, and everything is gone unless a package's install script is particularly ill-behaved.
.P
This assumes that you installed node and npm in the default place. If you configured node with a different \fB--prefix\fR, or installed npm with a different prefix setting, then adjust the paths accordingly, replacing \fB/usr/local\fR with your install prefix.
.P
diff --git a/deps/npm/man/man7/scope.7 b/deps/npm/man/man7/scope.7
index 7edbff22b6..9b892290e9 100644
--- a/deps/npm/man/man7/scope.7
+++ b/deps/npm/man/man7/scope.7
@@ -1,4 +1,4 @@
-.TH "SCOPE" "7" "December 2022" "" ""
+.TH "SCOPE" "7" "January 2023" "" ""
.SH "NAME"
\fBscope\fR - Scoped packages
.SS "Description"
diff --git a/deps/npm/man/man7/scripts.7 b/deps/npm/man/man7/scripts.7
index 78756bf6d2..443d9430e7 100644
--- a/deps/npm/man/man7/scripts.7
+++ b/deps/npm/man/man7/scripts.7
@@ -1,4 +1,4 @@
-.TH "SCRIPTS" "7" "December 2022" "" ""
+.TH "SCRIPTS" "7" "January 2023" "" ""
.SH "NAME"
\fBscripts\fR - How npm handles the "scripts" field
.SS "Description"
@@ -62,7 +62,7 @@ Runs BEFORE the package is prepared and packed, ONLY on \fBnpm publish\fR.
\fBprepack\fR
.RS 0
.IP \(bu 4
-Runs BEFORE a tarball is packed (on "\fBnpm pack\fR", "\fBnpm publish\fR", and when installing a git dependencies).
+Runs BEFORE a tarball is packed (on "\fBnpm pack\fR", "\fBnpm publish\fR", and when installing a git dependency).
.IP \(bu 4
NOTE: "\fBnpm run pack\fR" is NOT the same as "\fBnpm pack\fR". "\fBnpm run pack\fR" is an arbitrary user defined script name, where as, "\fBnpm pack\fR" is a CLI defined command.
.RE 0
diff --git a/deps/npm/man/man7/workspaces.7 b/deps/npm/man/man7/workspaces.7
index 427e3eeb84..e0ec139dd3 100644
--- a/deps/npm/man/man7/workspaces.7
+++ b/deps/npm/man/man7/workspaces.7
@@ -1,4 +1,4 @@
-.TH "WORKSPACES" "7" "December 2022" "" ""
+.TH "WORKSPACES" "7" "January 2023" "" ""
.SH "NAME"
\fBworkspaces\fR - Working with workspaces
.SS "Description"
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
index 89584e5814..a9c4b4bc0b 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/build-ideal-tree.js
@@ -12,6 +12,7 @@ const { readdirScoped } = require('@npmcli/fs')
const { lstat, readlink } = require('fs/promises')
const { depth } = require('treeverse')
const log = require('proc-log')
+const { cleanUrl } = require('npm-registry-fetch')
const {
OK,
@@ -1210,7 +1211,8 @@ This is a one-time fix-up, please be patient...
if (this[_manifests].has(spec.raw)) {
return this[_manifests].get(spec.raw)
} else {
- log.silly('fetch manifest', spec.raw)
+ const cleanRawSpec = cleanUrl(spec.rawSpec)
+ log.silly('fetch manifest', spec.raw.replace(spec.rawSpec, cleanRawSpec))
const p = pacote.manifest(spec, options)
.then(mani => {
this[_manifests].set(spec.raw, mani)
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js
index 947659f177..b2a6ec2315 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-virtual.js
@@ -1,5 +1,6 @@
// mixin providing the loadVirtual method
const localeCompare = require('@isaacs/string-locale-compare')('en')
+const mapWorkspaces = require('@npmcli/map-workspaces')
const { resolve } = require('path')
@@ -21,7 +22,6 @@ const loadRoot = Symbol('loadRoot')
const loadNode = Symbol('loadVirtualNode')
const loadLink = Symbol('loadVirtualLink')
const loadWorkspaces = Symbol.for('loadWorkspaces')
-const loadWorkspacesVirtual = Symbol.for('loadWorkspacesVirtual')
const flagsSuspect = Symbol.for('flagsSuspect')
const reCalcDepFlags = Symbol('reCalcDepFlags')
const checkRootEdges = Symbol('checkRootEdges')
@@ -157,7 +157,7 @@ module.exports = cls => class VirtualLoader extends cls {
}
const lockWS = []
- const workspaces = this[loadWorkspacesVirtual]({
+ const workspaces = mapWorkspaces.virtual({
cwd: this.path,
lockfile: s.data,
})
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js
index 0a7965ae30..effa5a0cda 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/arborist/load-workspaces.js
@@ -1,33 +1,19 @@
const mapWorkspaces = require('@npmcli/map-workspaces')
-const _appendWorkspaces = Symbol('appendWorkspaces')
// shared ref used by other mixins/Arborist
const _loadWorkspaces = Symbol.for('loadWorkspaces')
-const _loadWorkspacesVirtual = Symbol.for('loadWorkspacesVirtual')
module.exports = cls => class MapWorkspaces extends cls {
- [_appendWorkspaces] (node, workspaces) {
- if (node && workspaces.size) {
- node.workspaces = workspaces
- }
-
- return node
- }
-
async [_loadWorkspaces] (node) {
- if (node.workspaces) {
- return node
- }
-
const workspaces = await mapWorkspaces({
cwd: node.path,
pkg: node.package,
})
- return this[_appendWorkspaces](node, workspaces)
- }
+ if (node && workspaces.size) {
+ node.workspaces = workspaces
+ }
- [_loadWorkspacesVirtual] (opts) {
- return mapWorkspaces.virtual(opts)
+ return node
}
}
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/override-resolves.js b/deps/npm/node_modules/@npmcli/arborist/lib/override-resolves.js
index 794b2c335d..c061cbce18 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/override-resolves.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/override-resolves.js
@@ -1,4 +1,4 @@
-function overrideResolves (resolved, opts = {}) {
+function overrideResolves (resolved, opts) {
const { omitLockfileRegistryResolved = false } = opts
if (omitLockfileRegistryResolved) {
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/override-set.js b/deps/npm/node_modules/@npmcli/arborist/lib/override-set.js
index 742e3f08ec..bfc5a5d790 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/override-set.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/override-set.js
@@ -50,9 +50,36 @@ class OverrideSet {
continue
}
- if (semver.intersects(edge.spec, rule.keySpec)) {
+ // if keySpec is * we found our override
+ if (rule.keySpec === '*') {
return rule
}
+
+ let spec = npa(`${edge.name}@${edge.spec}`)
+ if (spec.type === 'alias') {
+ spec = spec.subSpec
+ }
+
+ if (spec.type === 'git') {
+ if (spec.gitRange && semver.intersects(spec.gitRange, rule.keySpec)) {
+ return rule
+ }
+
+ continue
+ }
+
+ if (spec.type === 'range' || spec.type === 'version') {
+ if (semver.intersects(spec.fetchSpec, rule.keySpec)) {
+ return rule
+ }
+
+ continue
+ }
+
+ // if we got this far, the spec type is one of tag, directory or file
+ // which means we have no real way to make version comparisons, so we
+ // just accept the override
+ return rule
}
return this
diff --git a/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js b/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js
index 16a0095fa0..e757d0c38a 100644
--- a/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js
+++ b/deps/npm/node_modules/@npmcli/arborist/lib/place-dep.js
@@ -9,6 +9,7 @@
const localeCompare = require('@isaacs/string-locale-compare')('en')
const log = require('proc-log')
+const { cleanUrl } = require('npm-registry-fetch')
const deepestNestingTarget = require('./deepest-nesting-target.js')
const CanPlaceDep = require('./can-place-dep.js')
const {
@@ -187,7 +188,7 @@ class PlaceDep {
`${this.dep.name}@${this.dep.version}`,
this.canPlace.description,
`for: ${this.edge.from.package._id || this.edge.from.location}`,
- `want: ${this.edge.spec || '*'}`
+ `want: ${cleanUrl(this.edge.spec || '*')}`
)
const placementType = this.canPlace.canPlace === CONFLICT
diff --git a/deps/npm/node_modules/@npmcli/arborist/package.json b/deps/npm/node_modules/@npmcli/arborist/package.json
index 075fb93b91..a7e8132123 100644
--- a/deps/npm/node_modules/@npmcli/arborist/package.json
+++ b/deps/npm/node_modules/@npmcli/arborist/package.json
@@ -1,6 +1,6 @@
{
"name": "@npmcli/arborist",
- "version": "6.1.5",
+ "version": "6.1.6",
"description": "Manage node_modules trees",
"dependencies": {
"@isaacs/string-locale-compare": "^1.1.0",
@@ -42,9 +42,9 @@
"@npmcli/template-oss": "4.11.0",
"benchmark": "^2.1.4",
"chalk": "^4.1.0",
- "minify-registry-metadata": "^2.1.0",
+ "minify-registry-metadata": "^3.0.0",
"nock": "^13.2.0",
- "tap": "^16.0.1",
+ "tap": "^16.3.2",
"tcompare": "^5.0.6"
},
"scripts": {
@@ -81,7 +81,6 @@
"tap": {
"color": true,
"after": "test/fixtures/cleanup.js",
- "coverage-map": "map.js",
"test-env": [
"NODE_OPTIONS=--no-warnings",
"LC_ALL=sk"
diff --git a/deps/npm/node_modules/@npmcli/config/lib/index.js b/deps/npm/node_modules/@npmcli/config/lib/index.js
index e1d47ffcd3..1ddf267839 100644
--- a/deps/npm/node_modules/@npmcli/config/lib/index.js
+++ b/deps/npm/node_modules/@npmcli/config/lib/index.js
@@ -17,6 +17,14 @@ const {
mkdir,
} = require('fs/promises')
+const fileExists = (...p) => stat(resolve(...p))
+ .then((st) => st.isFile())
+ .catch(() => false)
+
+const dirExists = (...p) => stat(resolve(...p))
+ .then((st) => st.isDirectory())
+ .catch(() => false)
+
const hasOwnProperty = (obj, key) =>
Object.prototype.hasOwnProperty.call(obj, key)
@@ -90,6 +98,7 @@ class Config {
platform = process.platform,
execPath = process.execPath,
cwd = process.cwd(),
+ excludeNpmCwd = false,
}) {
// turn the definitions into nopt's weirdo syntax
this.definitions = definitions
@@ -117,10 +126,12 @@ class Config {
this.execPath = execPath
this.platform = platform
this.cwd = cwd
+ this.excludeNpmCwd = excludeNpmCwd
// set when we load configs
this.globalPrefix = null
this.localPrefix = null
+ this.localPackage = null
// defaults to env.HOME, but will always be *something*
this.home = null
@@ -311,15 +322,11 @@ class Config {
// default the globalconfig file to that location, instead of the default
// global prefix. It's weird that `npm get globalconfig --prefix=/foo`
// returns `/foo/etc/npmrc`, but better to not change it at this point.
- settableGetter(data, 'globalconfig', () =>
- resolve(this[_get]('prefix'), 'etc/npmrc'))
+ settableGetter(data, 'globalconfig', () => resolve(this[_get]('prefix'), 'etc/npmrc'))
}
loadHome () {
- if (this.env.HOME) {
- return this.home = this.env.HOME
- }
- this.home = homedir()
+ this.home = this.env.HOME || homedir()
}
loadGlobalPrefix () {
@@ -330,7 +337,7 @@ class Config {
if (this.env.PREFIX) {
this.globalPrefix = this.env.PREFIX
} else if (this.platform === 'win32') {
- // c:\node\node.exe --> prefix=c:\node\
+ // c:\node\node.exe --> prefix=c:\node\
this.globalPrefix = dirname(this.execPath)
} else {
// /usr/local/bin/node --> prefix=/usr/local
@@ -599,6 +606,12 @@ class Config {
// we return to make sure localPrefix is set
await this.loadLocalPrefix()
+ // if we have not detected a local package json yet, try now that we
+ // have a local prefix
+ if (this.localPackage == null) {
+ this.localPackage = await fileExists(this.localPrefix, 'package.json')
+ }
+
if (this[_get]('global') === true || this[_get]('location') === 'global') {
this.data.get('project').source = '(global mode enabled, ignored)'
this.sources.set(this.data.get('project').source, 'project')
@@ -630,16 +643,17 @@ class Config {
const isGlobal = this[_get]('global') || this[_get]('location') === 'global'
for (const p of walkUp(this.cwd)) {
- const hasNodeModules = await stat(resolve(p, 'node_modules'))
- .then((st) => st.isDirectory())
- .catch(() => false)
+ // HACK: this is an option set in tests to stop the local prefix from being set
+ // on tests that are created inside the npm repo
+ if (this.excludeNpmCwd && p === this.npmPath) {
+ break
+ }
- const hasPackageJson = await stat(resolve(p, 'package.json'))
- .then((st) => st.isFile())
- .catch(() => false)
+ const hasPackageJson = await fileExists(p, 'package.json')
- if (!this.localPrefix && (hasNodeModules || hasPackageJson)) {
+ if (!this.localPrefix && (hasPackageJson || await dirExists(p, 'node_modules'))) {
this.localPrefix = p
+ this.localPackage = hasPackageJson
// if workspaces are disabled, or we're in global mode, return now
if (cliWorkspaces === false || isGlobal) {
@@ -663,11 +677,7 @@ class Config {
for (const w of workspaces.values()) {
if (w === this.localPrefix) {
// see if there's a .npmrc file in the workspace, if so log a warning
- const hasNpmrc = await stat(resolve(this.localPrefix, '.npmrc'))
- .then((st) => st.isFile())
- .catch(() => false)
-
- if (hasNpmrc) {
+ if (await fileExists(this.localPrefix, '.npmrc')) {
log.warn(`ignoring workspace config at ${this.localPrefix}/.npmrc`)
}
@@ -675,6 +685,7 @@ class Config {
const { data } = this.data.get('default')
data.workspace = [this.localPrefix]
this.localPrefix = p
+ this.localPackage = hasPackageJson
log.info(`found workspace root at ${this.localPrefix}`)
// we found a root, so we return now
return
diff --git a/deps/npm/node_modules/@npmcli/config/package.json b/deps/npm/node_modules/@npmcli/config/package.json
index 28074afe68..50d860c1c9 100644
--- a/deps/npm/node_modules/@npmcli/config/package.json
+++ b/deps/npm/node_modules/@npmcli/config/package.json
@@ -1,6 +1,6 @@
{
"name": "@npmcli/config",
- "version": "6.1.0",
+ "version": "6.1.1",
"files": [
"bin/",
"lib/"
@@ -34,7 +34,7 @@
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"dependencies": {
"@npmcli/map-workspaces": "^3.0.0",
diff --git a/deps/npm/node_modules/libnpmaccess/package.json b/deps/npm/node_modules/libnpmaccess/package.json
index 8f89d4b271..1e27f79597 100644
--- a/deps/npm/node_modules/libnpmaccess/package.json
+++ b/deps/npm/node_modules/libnpmaccess/package.json
@@ -19,7 +19,7 @@
"@npmcli/mock-registry": "^1.0.0",
"@npmcli/template-oss": "4.11.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
diff --git a/deps/npm/node_modules/libnpmdiff/package.json b/deps/npm/node_modules/libnpmdiff/package.json
index 8979bc9199..9e7e3bdb41 100644
--- a/deps/npm/node_modules/libnpmdiff/package.json
+++ b/deps/npm/node_modules/libnpmdiff/package.json
@@ -1,6 +1,6 @@
{
"name": "libnpmdiff",
- "version": "5.0.6",
+ "version": "5.0.7",
"description": "The registry diff",
"repository": {
"type": "git",
@@ -44,10 +44,10 @@
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"dependencies": {
- "@npmcli/arborist": "^6.1.5",
+ "@npmcli/arborist": "^6.1.6",
"@npmcli/disparity-colors": "^3.0.0",
"@npmcli/installed-package-contents": "^2.0.0",
"binary-extensions": "^2.2.0",
diff --git a/deps/npm/node_modules/libnpmexec/package.json b/deps/npm/node_modules/libnpmexec/package.json
index cc77321caa..c0092d4c87 100644
--- a/deps/npm/node_modules/libnpmexec/package.json
+++ b/deps/npm/node_modules/libnpmexec/package.json
@@ -1,6 +1,6 @@
{
"name": "libnpmexec",
- "version": "5.0.6",
+ "version": "5.0.7",
"files": [
"bin/",
"lib/"
@@ -56,12 +56,12 @@
"bin-links": "^4.0.1",
"just-extend": "^6.1.1",
"just-safe-set": "^4.1.1",
- "minify-registry-metadata": "^2.2.0",
+ "minify-registry-metadata": "^3.0.0",
"mkdirp": "^1.0.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"dependencies": {
- "@npmcli/arborist": "^6.1.5",
+ "@npmcli/arborist": "^6.1.6",
"@npmcli/run-script": "^6.0.0",
"chalk": "^4.1.0",
"ci-info": "^3.7.0",
diff --git a/deps/npm/node_modules/libnpmfund/package.json b/deps/npm/node_modules/libnpmfund/package.json
index f7fca06d4f..c0de224fba 100644
--- a/deps/npm/node_modules/libnpmfund/package.json
+++ b/deps/npm/node_modules/libnpmfund/package.json
@@ -1,6 +1,6 @@
{
"name": "libnpmfund",
- "version": "4.0.6",
+ "version": "4.0.7",
"main": "lib/index.js",
"files": [
"bin/",
@@ -43,10 +43,10 @@
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"dependencies": {
- "@npmcli/arborist": "^6.1.5"
+ "@npmcli/arborist": "^6.1.6"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
diff --git a/deps/npm/node_modules/libnpmhook/package.json b/deps/npm/node_modules/libnpmhook/package.json
index 606dfc7d9e..b157f97e68 100644
--- a/deps/npm/node_modules/libnpmhook/package.json
+++ b/deps/npm/node_modules/libnpmhook/package.json
@@ -39,7 +39,7 @@
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
diff --git a/deps/npm/node_modules/libnpmorg/package.json b/deps/npm/node_modules/libnpmorg/package.json
index c0b1a09ee2..529a7ff9d2 100644
--- a/deps/npm/node_modules/libnpmorg/package.json
+++ b/deps/npm/node_modules/libnpmorg/package.json
@@ -31,7 +31,7 @@
"@npmcli/template-oss": "4.11.0",
"minipass": "^4.0.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
diff --git a/deps/npm/node_modules/libnpmpack/package.json b/deps/npm/node_modules/libnpmpack/package.json
index 5ad21875fd..035edaa980 100644
--- a/deps/npm/node_modules/libnpmpack/package.json
+++ b/deps/npm/node_modules/libnpmpack/package.json
@@ -1,6 +1,6 @@
{
"name": "libnpmpack",
- "version": "5.0.6",
+ "version": "5.0.7",
"description": "Programmatic API for the bits behind npm pack",
"author": "GitHub Inc.",
"main": "lib/index.js",
@@ -26,7 +26,7 @@
"@npmcli/template-oss": "4.11.0",
"nock": "^13.0.7",
"spawk": "^1.7.1",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
@@ -36,7 +36,7 @@
"bugs": "https://github.com/npm/libnpmpack/issues",
"homepage": "https://npmjs.com/package/libnpmpack",
"dependencies": {
- "@npmcli/arborist": "^6.1.5",
+ "@npmcli/arborist": "^6.1.6",
"@npmcli/run-script": "^6.0.0",
"npm-package-arg": "^10.1.0",
"pacote": "^15.0.7"
diff --git a/deps/npm/node_modules/libnpmpublish/package.json b/deps/npm/node_modules/libnpmpublish/package.json
index eece07bee2..c293d566d1 100644
--- a/deps/npm/node_modules/libnpmpublish/package.json
+++ b/deps/npm/node_modules/libnpmpublish/package.json
@@ -25,11 +25,11 @@
},
"devDependencies": {
"@npmcli/eslint-config": "^4.0.0",
+ "@npmcli/mock-registry": "^1.0.0",
"@npmcli/template-oss": "4.11.0",
- "libnpmpack": "^5.0.6",
"lodash.clonedeep": "^4.5.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
diff --git a/deps/npm/node_modules/libnpmsearch/package.json b/deps/npm/node_modules/libnpmsearch/package.json
index 6d22ce3568..e0d67afbbf 100644
--- a/deps/npm/node_modules/libnpmsearch/package.json
+++ b/deps/npm/node_modules/libnpmsearch/package.json
@@ -28,7 +28,7 @@
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
diff --git a/deps/npm/node_modules/libnpmteam/package.json b/deps/npm/node_modules/libnpmteam/package.json
index 9154a12991..b3444c77b8 100644
--- a/deps/npm/node_modules/libnpmteam/package.json
+++ b/deps/npm/node_modules/libnpmteam/package.json
@@ -18,7 +18,7 @@
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
"nock": "^13.2.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"repository": {
"type": "git",
diff --git a/deps/npm/node_modules/libnpmversion/package.json b/deps/npm/node_modules/libnpmversion/package.json
index d77bf51e1b..ff3855ae6c 100644
--- a/deps/npm/node_modules/libnpmversion/package.json
+++ b/deps/npm/node_modules/libnpmversion/package.json
@@ -34,7 +34,7 @@
"@npmcli/eslint-config": "^4.0.0",
"@npmcli/template-oss": "4.11.0",
"require-inject": "^1.4.4",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"dependencies": {
"@npmcli/git": "^4.0.1",
diff --git a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/LICENSE b/deps/npm/node_modules/minipass-fetch/node_modules/minipass/LICENSE
deleted file mode 100644
index bf1dece2e1..0000000000
--- a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/LICENSE
+++ /dev/null
@@ -1,15 +0,0 @@
-The ISC License
-
-Copyright (c) 2017-2022 npm, Inc., Isaac Z. Schlueter, and Contributors
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
-IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.d.ts b/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.d.ts
deleted file mode 100644
index 65faf63686..0000000000
--- a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.d.ts
+++ /dev/null
@@ -1,155 +0,0 @@
-/// <reference types="node" />
-import { EventEmitter } from 'events'
-import { Stream } from 'stream'
-
-declare namespace Minipass {
- type Encoding = BufferEncoding | 'buffer' | null
-
- interface Writable extends EventEmitter {
- end(): any
- write(chunk: any, ...args: any[]): any
- }
-
- interface Readable extends EventEmitter {
- pause(): any
- resume(): any
- pipe(): any
- }
-
- interface Pipe<R, W> {
- src: Minipass<R, W>
- dest: Writable
- opts: PipeOptions
- }
-
- type DualIterable<T> = Iterable<T> & AsyncIterable<T>
-
- type ContiguousData = Buffer | ArrayBufferLike | ArrayBufferView | string
-
- type BufferOrString = Buffer | string
-
- interface StringOptions {
- encoding: BufferEncoding
- objectMode?: boolean
- async?: boolean
- }
-
- interface BufferOptions {
- encoding?: null | 'buffer'
- objectMode?: boolean
- async?: boolean
- }
-
- interface ObjectModeOptions {
- objectMode: true
- async?: boolean
- }
-
- interface PipeOptions {
- end?: boolean
- proxyErrors?: boolean
- }
-
- type Options<T> = T extends string
- ? StringOptions
- : T extends Buffer
- ? BufferOptions
- : ObjectModeOptions
-}
-
-declare class Minipass<
- RType extends any = Buffer,
- WType extends any = RType extends Minipass.BufferOrString
- ? Minipass.ContiguousData
- : RType
- >
- extends Stream
- implements Minipass.DualIterable<RType>
-{
- static isStream(stream: any): stream is Minipass.Readable | Minipass.Writable
-
- readonly bufferLength: number
- readonly flowing: boolean
- readonly writable: boolean
- readonly readable: boolean
- readonly paused: boolean
- readonly emittedEnd: boolean
- readonly destroyed: boolean
-
- /**
- * Not technically private or readonly, but not safe to mutate.
- */
- private readonly buffer: RType[]
- private readonly pipes: Minipass.Pipe<RType, WType>[]
-
- /**
- * Technically writable, but mutating it can change the type,
- * so is not safe to do in TypeScript.
- */
- readonly objectMode: boolean
- async: boolean
-
- /**
- * Note: encoding is not actually read-only, and setEncoding(enc)
- * exists. However, this type definition will insist that TypeScript
- * programs declare the type of a Minipass stream up front, and if
- * that type is string, then an encoding MUST be set in the ctor. If
- * the type is Buffer, then the encoding must be missing, or set to
- * 'buffer' or null. If the type is anything else, then objectMode
- * must be set in the constructor options. So there is effectively
- * no allowed way that a TS program can set the encoding after
- * construction, as doing so will destroy any hope of type safety.
- * TypeScript does not provide many options for changing the type of
- * an object at run-time, which is what changing the encoding does.
- */
- readonly encoding: Minipass.Encoding
- // setEncoding(encoding: Encoding): void
-
- // Options required if not reading buffers
- constructor(
- ...args: RType extends Buffer
- ? [] | [Minipass.Options<RType>]
- : [Minipass.Options<RType>]
- )
-
- write(chunk: WType, cb?: () => void): boolean
- write(chunk: WType, encoding?: Minipass.Encoding, cb?: () => void): boolean
- read(size?: number): RType
- end(cb?: () => void): this
- end(chunk: any, cb?: () => void): this
- end(chunk: any, encoding?: Minipass.Encoding, cb?: () => void): this
- pause(): void
- resume(): void
- promise(): Promise<void>
- collect(): Promise<RType[]>
-
- concat(): RType extends Minipass.BufferOrString ? Promise<RType> : never
- destroy(er?: any): void
- pipe<W extends Minipass.Writable>(dest: W, opts?: Minipass.PipeOptions): W
- unpipe<W extends Minipass.Writable>(dest: W): void
-
- /**
- * alias for on()
- */
- addEventHandler(event: string, listener: (...args: any[]) => any): this
-
- on(event: string, listener: (...args: any[]) => any): this
- on(event: 'data', listener: (chunk: RType) => any): this
- on(event: 'error', listener: (error: any) => any): this
- on(
- event:
- | 'readable'
- | 'drain'
- | 'resume'
- | 'end'
- | 'prefinish'
- | 'finish'
- | 'close',
- listener: () => any
- ): this
-
- [Symbol.iterator](): Iterator<RType>
- [Symbol.asyncIterator](): AsyncIterator<RType>
-}
-
-export = Minipass
diff --git a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.js b/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.js
deleted file mode 100644
index e8797aab6c..0000000000
--- a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/index.js
+++ /dev/null
@@ -1,649 +0,0 @@
-'use strict'
-const proc = typeof process === 'object' && process ? process : {
- stdout: null,
- stderr: null,
-}
-const EE = require('events')
-const Stream = require('stream')
-const SD = require('string_decoder').StringDecoder
-
-const EOF = Symbol('EOF')
-const MAYBE_EMIT_END = Symbol('maybeEmitEnd')
-const EMITTED_END = Symbol('emittedEnd')
-const EMITTING_END = Symbol('emittingEnd')
-const EMITTED_ERROR = Symbol('emittedError')
-const CLOSED = Symbol('closed')
-const READ = Symbol('read')
-const FLUSH = Symbol('flush')
-const FLUSHCHUNK = Symbol('flushChunk')
-const ENCODING = Symbol('encoding')
-const DECODER = Symbol('decoder')
-const FLOWING = Symbol('flowing')
-const PAUSED = Symbol('paused')
-const RESUME = Symbol('resume')
-const BUFFERLENGTH = Symbol('bufferLength')
-const BUFFERPUSH = Symbol('bufferPush')
-const BUFFERSHIFT = Symbol('bufferShift')
-const OBJECTMODE = Symbol('objectMode')
-const DESTROYED = Symbol('destroyed')
-const EMITDATA = Symbol('emitData')
-const EMITEND = Symbol('emitEnd')
-const EMITEND2 = Symbol('emitEnd2')
-const ASYNC = Symbol('async')
-
-const defer = fn => Promise.resolve().then(fn)
-
-// TODO remove when Node v8 support drops
-const doIter = global._MP_NO_ITERATOR_SYMBOLS_ !== '1'
-const ASYNCITERATOR = doIter && Symbol.asyncIterator
- || Symbol('asyncIterator not implemented')
-const ITERATOR = doIter && Symbol.iterator
- || Symbol('iterator not implemented')
-
-// events that mean 'the stream is over'
-// these are treated specially, and re-emitted
-// if they are listened for after emitting.
-const isEndish = ev =>
- ev === 'end' ||
- ev === 'finish' ||
- ev === 'prefinish'
-
-const isArrayBuffer = b => b instanceof ArrayBuffer ||
- typeof b === 'object' &&
- b.constructor &&
- b.constructor.name === 'ArrayBuffer' &&
- b.byteLength >= 0
-
-const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b)
-
-class Pipe {
- constructor (src, dest, opts) {
- this.src = src
- this.dest = dest
- this.opts = opts
- this.ondrain = () => src[RESUME]()
- dest.on('drain', this.ondrain)
- }
- unpipe () {
- this.dest.removeListener('drain', this.ondrain)
- }
- // istanbul ignore next - only here for the prototype
- proxyErrors () {}
- end () {
- this.unpipe()
- if (this.opts.end)
- this.dest.end()
- }
-}
-
-class PipeProxyErrors extends Pipe {
- unpipe () {
- this.src.removeListener('error', this.proxyErrors)
- super.unpipe()
- }
- constructor (src, dest, opts) {
- super(src, dest, opts)
- this.proxyErrors = er => dest.emit('error', er)
- src.on('error', this.proxyErrors)
- }
-}
-
-module.exports = class Minipass extends Stream {
- constructor (options) {
- super()
- this[FLOWING] = false
- // whether we're explicitly paused
- this[PAUSED] = false
- this.pipes = []
- this.buffer = []
- this[OBJECTMODE] = options && options.objectMode || false
- if (this[OBJECTMODE])
- this[ENCODING] = null
- else
- this[ENCODING] = options && options.encoding || null
- if (this[ENCODING] === 'buffer')
- this[ENCODING] = null
- this[ASYNC] = options && !!options.async || false
- this[DECODER] = this[ENCODING] ? new SD(this[ENCODING]) : null
- this[EOF] = false
- this[EMITTED_END] = false
- this[EMITTING_END] = false
- this[CLOSED] = false
- this[EMITTED_ERROR] = null
- this.writable = true
- this.readable = true
- this[BUFFERLENGTH] = 0
- this[DESTROYED] = false
- }
-
- get bufferLength () { return this[BUFFERLENGTH] }
-
- get encoding () { return this[ENCODING] }
- set encoding (enc) {
- if (this[OBJECTMODE])
- throw new Error('cannot set encoding in objectMode')
-
- if (this[ENCODING] && enc !== this[ENCODING] &&
- (this[DECODER] && this[DECODER].lastNeed || this[BUFFERLENGTH]))
- throw new Error('cannot change encoding')
-
- if (this[ENCODING] !== enc) {
- this[DECODER] = enc ? new SD(enc) : null
- if (this.buffer.length)
- this.buffer = this.buffer.map(chunk => this[DECODER].write(chunk))
- }
-
- this[ENCODING] = enc
- }
-
- setEncoding (enc) {
- this.encoding = enc
- }
-
- get objectMode () { return this[OBJECTMODE] }
- set objectMode (om) { this[OBJECTMODE] = this[OBJECTMODE] || !!om }
-
- get ['async'] () { return this[ASYNC] }
- set ['async'] (a) { this[ASYNC] = this[ASYNC] || !!a }
-
- write (chunk, encoding, cb) {
- if (this[EOF])
- throw new Error('write after end')
-
- if (this[DESTROYED]) {
- this.emit('error', Object.assign(
- new Error('Cannot call write after a stream was destroyed'),
- { code: 'ERR_STREAM_DESTROYED' }
- ))
- return true
- }
-
- if (typeof encoding === 'function')
- cb = encoding, encoding = 'utf8'
-
- if (!encoding)
- encoding = 'utf8'
-
- const fn = this[ASYNC] ? defer : f => f()
-
- // convert array buffers and typed array views into buffers
- // at some point in the future, we may want to do the opposite!
- // leave strings and buffers as-is
- // anything else switches us into object mode
- if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
- if (isArrayBufferView(chunk))
- chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength)
- else if (isArrayBuffer(chunk))
- chunk = Buffer.from(chunk)
- else if (typeof chunk !== 'string')
- // use the setter so we throw if we have encoding set
- this.objectMode = true
- }
-
- // handle object mode up front, since it's simpler
- // this yields better performance, fewer checks later.
- if (this[OBJECTMODE]) {
- /* istanbul ignore if - maybe impossible? */
- if (this.flowing && this[BUFFERLENGTH] !== 0)
- this[FLUSH](true)
-
- if (this.flowing)
- this.emit('data', chunk)
- else
- this[BUFFERPUSH](chunk)
-
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable')
-
- if (cb)
- fn(cb)
-
- return this.flowing
- }
-
- // at this point the chunk is a buffer or string
- // don't buffer it up or send it to the decoder
- if (!chunk.length) {
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable')
- if (cb)
- fn(cb)
- return this.flowing
- }
-
- // fast-path writing strings of same encoding to a stream with
- // an empty buffer, skipping the buffer/decoder dance
- if (typeof chunk === 'string' &&
- // unless it is a string already ready for us to use
- !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) {
- chunk = Buffer.from(chunk, encoding)
- }
-
- if (Buffer.isBuffer(chunk) && this[ENCODING])
- chunk = this[DECODER].write(chunk)
-
- // Note: flushing CAN potentially switch us into not-flowing mode
- if (this.flowing && this[BUFFERLENGTH] !== 0)
- this[FLUSH](true)
-
- if (this.flowing)
- this.emit('data', chunk)
- else
- this[BUFFERPUSH](chunk)
-
- if (this[BUFFERLENGTH] !== 0)
- this.emit('readable')
-
- if (cb)
- fn(cb)
-
- return this.flowing
- }
-
- read (n) {
- if (this[DESTROYED])
- return null
-
- if (this[BUFFERLENGTH] === 0 || n === 0 || n > this[BUFFERLENGTH]) {
- this[MAYBE_EMIT_END]()
- return null
- }
-
- if (this[OBJECTMODE])
- n = null
-
- if (this.buffer.length > 1 && !this[OBJECTMODE]) {
- if (this.encoding)
- this.buffer = [this.buffer.join('')]
- else
- this.buffer = [Buffer.concat(this.buffer, this[BUFFERLENGTH])]
- }
-
- const ret = this[READ](n || null, this.buffer[0])
- this[MAYBE_EMIT_END]()
- return ret
- }
-
- [READ] (n, chunk) {
- if (n === chunk.length || n === null)
- this[BUFFERSHIFT]()
- else {
- this.buffer[0] = chunk.slice(n)
- chunk = chunk.slice(0, n)
- this[BUFFERLENGTH] -= n
- }
-
- this.emit('data', chunk)
-
- if (!this.buffer.length && !this[EOF])
- this.emit('drain')
-
- return chunk
- }
-
- end (chunk, encoding, cb) {
- if (typeof chunk === 'function')
- cb = chunk, chunk = null
- if (typeof encoding === 'function')
- cb = encoding, encoding = 'utf8'
- if (chunk)
- this.write(chunk, encoding)
- if (cb)
- this.once('end', cb)
- this[EOF] = true
- this.writable = false
-
- // if we haven't written anything, then go ahead and emit,
- // even if we're not reading.
- // we'll re-emit if a new 'end' listener is added anyway.
- // This makes MP more suitable to write-only use cases.
- if (this.flowing || !this[PAUSED])
- this[MAYBE_EMIT_END]()
- return this
- }
-
- // don't let the internal resume be overwritten
- [RESUME] () {
- if (this[DESTROYED])
- return
-
- this[PAUSED] = false
- this[FLOWING] = true
- this.emit('resume')
- if (this.buffer.length)
- this[FLUSH]()
- else if (this[EOF])
- this[MAYBE_EMIT_END]()
- else
- this.emit('drain')
- }
-
- resume () {
- return this[RESUME]()
- }
-
- pause () {
- this[FLOWING] = false
- this[PAUSED] = true
- }
-
- get destroyed () {
- return this[DESTROYED]
- }
-
- get flowing () {
- return this[FLOWING]
- }
-
- get paused () {
- return this[PAUSED]
- }
-
- [BUFFERPUSH] (chunk) {
- if (this[OBJECTMODE])
- this[BUFFERLENGTH] += 1
- else
- this[BUFFERLENGTH] += chunk.length
- this.buffer.push(chunk)
- }
-
- [BUFFERSHIFT] () {
- if (this.buffer.length) {
- if (this[OBJECTMODE])
- this[BUFFERLENGTH] -= 1
- else
- this[BUFFERLENGTH] -= this.buffer[0].length
- }
- return this.buffer.shift()
- }
-
- [FLUSH] (noDrain) {
- do {} while (this[FLUSHCHUNK](this[BUFFERSHIFT]()))
-
- if (!noDrain && !this.buffer.length && !this[EOF])
- this.emit('drain')
- }
-
- [FLUSHCHUNK] (chunk) {
- return chunk ? (this.emit('data', chunk), this.flowing) : false
- }
-
- pipe (dest, opts) {
- if (this[DESTROYED])
- return
-
- const ended = this[EMITTED_END]
- opts = opts || {}
- if (dest === proc.stdout || dest === proc.stderr)
- opts.end = false
- else
- opts.end = opts.end !== false
- opts.proxyErrors = !!opts.proxyErrors
-
- // piping an ended stream ends immediately
- if (ended) {
- if (opts.end)
- dest.end()
- } else {
- this.pipes.push(!opts.proxyErrors ? new Pipe(this, dest, opts)
- : new PipeProxyErrors(this, dest, opts))
- if (this[ASYNC])
- defer(() => this[RESUME]())
- else
- this[RESUME]()
- }
-
- return dest
- }
-
- unpipe (dest) {
- const p = this.pipes.find(p => p.dest === dest)
- if (p) {
- this.pipes.splice(this.pipes.indexOf(p), 1)
- p.unpipe()
- }
- }
-
- addListener (ev, fn) {
- return this.on(ev, fn)
- }
-
- on (ev, fn) {
- const ret = super.on(ev, fn)
- if (ev === 'data' && !this.pipes.length && !this.flowing)
- this[RESUME]()
- else if (ev === 'readable' && this[BUFFERLENGTH] !== 0)
- super.emit('readable')
- else if (isEndish(ev) && this[EMITTED_END]) {
- super.emit(ev)
- this.removeAllListeners(ev)
- } else if (ev === 'error' && this[EMITTED_ERROR]) {
- if (this[ASYNC])
- defer(() => fn.call(this, this[EMITTED_ERROR]))
- else
- fn.call(this, this[EMITTED_ERROR])
- }
- return ret
- }
-
- get emittedEnd () {
- return this[EMITTED_END]
- }
-
- [MAYBE_EMIT_END] () {
- if (!this[EMITTING_END] &&
- !this[EMITTED_END] &&
- !this[DESTROYED] &&
- this.buffer.length === 0 &&
- this[EOF]) {
- this[EMITTING_END] = true
- this.emit('end')
- this.emit('prefinish')
- this.emit('finish')
- if (this[CLOSED])
- this.emit('close')
- this[EMITTING_END] = false
- }
- }
-
- emit (ev, data, ...extra) {
- // error and close are only events allowed after calling destroy()
- if (ev !== 'error' && ev !== 'close' && ev !== DESTROYED && this[DESTROYED])
- return
- else if (ev === 'data') {
- return !data ? false
- : this[ASYNC] ? defer(() => this[EMITDATA](data))
- : this[EMITDATA](data)
- } else if (ev === 'end') {
- return this[EMITEND]()
- } else if (ev === 'close') {
- this[CLOSED] = true
- // don't emit close before 'end' and 'finish'
- if (!this[EMITTED_END] && !this[DESTROYED])
- return
- const ret = super.emit('close')
- this.removeAllListeners('close')
- return ret
- } else if (ev === 'error') {
- this[EMITTED_ERROR] = data
- const ret = super.emit('error', data)
- this[MAYBE_EMIT_END]()
- return ret
- } else if (ev === 'resume') {
- const ret = super.emit('resume')
- this[MAYBE_EMIT_END]()
- return ret
- } else if (ev === 'finish' || ev === 'prefinish') {
- const ret = super.emit(ev)
- this.removeAllListeners(ev)
- return ret
- }
-
- // Some other unknown event
- const ret = super.emit(ev, data, ...extra)
- this[MAYBE_EMIT_END]()
- return ret
- }
-
- [EMITDATA] (data) {
- for (const p of this.pipes) {
- if (p.dest.write(data) === false)
- this.pause()
- }
- const ret = super.emit('data', data)
- this[MAYBE_EMIT_END]()
- return ret
- }
-
- [EMITEND] () {
- if (this[EMITTED_END])
- return
-
- this[EMITTED_END] = true
- this.readable = false
- if (this[ASYNC])
- defer(() => this[EMITEND2]())
- else
- this[EMITEND2]()
- }
-
- [EMITEND2] () {
- if (this[DECODER]) {
- const data = this[DECODER].end()
- if (data) {
- for (const p of this.pipes) {
- p.dest.write(data)
- }
- super.emit('data', data)
- }
- }
-
- for (const p of this.pipes) {
- p.end()
- }
- const ret = super.emit('end')
- this.removeAllListeners('end')
- return ret
- }
-
- // const all = await stream.collect()
- collect () {
- const buf = []
- if (!this[OBJECTMODE])
- buf.dataLength = 0
- // set the promise first, in case an error is raised
- // by triggering the flow here.
- const p = this.promise()
- this.on('data', c => {
- buf.push(c)
- if (!this[OBJECTMODE])
- buf.dataLength += c.length
- })
- return p.then(() => buf)
- }
-
- // const data = await stream.concat()
- concat () {
- return this[OBJECTMODE]
- ? Promise.reject(new Error('cannot concat in objectMode'))
- : this.collect().then(buf =>
- this[OBJECTMODE]
- ? Promise.reject(new Error('cannot concat in objectMode'))
- : this[ENCODING] ? buf.join('') : Buffer.concat(buf, buf.dataLength))
- }
-
- // stream.promise().then(() => done, er => emitted error)
- promise () {
- return new Promise((resolve, reject) => {
- this.on(DESTROYED, () => reject(new Error('stream destroyed')))
- this.on('error', er => reject(er))
- this.on('end', () => resolve())
- })
- }
-
- // for await (let chunk of stream)
- [ASYNCITERATOR] () {
- const next = () => {
- const res = this.read()
- if (res !== null)
- return Promise.resolve({ done: false, value: res })
-
- if (this[EOF])
- return Promise.resolve({ done: true })
-
- let resolve = null
- let reject = null
- const onerr = er => {
- this.removeListener('data', ondata)
- this.removeListener('end', onend)
- reject(er)
- }
- const ondata = value => {
- this.removeListener('error', onerr)
- this.removeListener('end', onend)
- this.pause()
- resolve({ value: value, done: !!this[EOF] })
- }
- const onend = () => {
- this.removeListener('error', onerr)
- this.removeListener('data', ondata)
- resolve({ done: true })
- }
- const ondestroy = () => onerr(new Error('stream destroyed'))
- return new Promise((res, rej) => {
- reject = rej
- resolve = res
- this.once(DESTROYED, ondestroy)
- this.once('error', onerr)
- this.once('end', onend)
- this.once('data', ondata)
- })
- }
-
- return { next }
- }
-
- // for (let chunk of stream)
- [ITERATOR] () {
- const next = () => {
- const value = this.read()
- const done = value === null
- return { value, done }
- }
- return { next }
- }
-
- destroy (er) {
- if (this[DESTROYED]) {
- if (er)
- this.emit('error', er)
- else
- this.emit(DESTROYED)
- return this
- }
-
- this[DESTROYED] = true
-
- // throw away all buffered data, it's never coming out
- this.buffer.length = 0
- this[BUFFERLENGTH] = 0
-
- if (typeof this.close === 'function' && !this[CLOSED])
- this.close()
-
- if (er)
- this.emit('error', er)
- else // if no error to emit, still reject pending promises
- this.emit(DESTROYED)
-
- return this
- }
-
- static isStream (s) {
- return !!s && (s instanceof Minipass || s instanceof Stream ||
- s instanceof EE && (
- typeof s.pipe === 'function' || // readable
- (typeof s.write === 'function' && typeof s.end === 'function') // writable
- ))
- }
-}
diff --git a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/package.json b/deps/npm/node_modules/minipass-fetch/node_modules/minipass/package.json
deleted file mode 100644
index 548d03fa6d..0000000000
--- a/deps/npm/node_modules/minipass-fetch/node_modules/minipass/package.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "name": "minipass",
- "version": "3.3.6",
- "description": "minimal implementation of a PassThrough stream",
- "main": "index.js",
- "types": "index.d.ts",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "devDependencies": {
- "@types/node": "^17.0.41",
- "end-of-stream": "^1.4.0",
- "prettier": "^2.6.2",
- "tap": "^16.2.0",
- "through2": "^2.0.3",
- "ts-node": "^10.8.1",
- "typescript": "^4.7.3"
- },
- "scripts": {
- "test": "tap",
- "preversion": "npm test",
- "postversion": "npm publish",
- "postpublish": "git push origin --follow-tags"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/isaacs/minipass.git"
- },
- "keywords": [
- "passthrough",
- "stream"
- ],
- "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
- "license": "ISC",
- "files": [
- "index.d.ts",
- "index.js"
- ],
- "tap": {
- "check-coverage": true
- },
- "engines": {
- "node": ">=8"
- },
- "prettier": {
- "semi": false,
- "printWidth": 80,
- "tabWidth": 2,
- "useTabs": false,
- "singleQuote": true,
- "jsxSingleQuote": false,
- "bracketSameLine": true,
- "arrowParens": "avoid",
- "endOfLine": "lf"
- }
-}
diff --git a/deps/npm/node_modules/minipass-fetch/package.json b/deps/npm/node_modules/minipass-fetch/package.json
index 45bd36ae71..fc6f884733 100644
--- a/deps/npm/node_modules/minipass-fetch/package.json
+++ b/deps/npm/node_modules/minipass-fetch/package.json
@@ -1,10 +1,11 @@
{
"name": "minipass-fetch",
- "version": "3.0.0",
+ "version": "3.0.1",
"description": "An implementation of window.fetch in Node.js using Minipass streams",
"license": "MIT",
"main": "lib/index.js",
"scripts": {
+ "test:tls-fixtures": "./test/fixtures/tls/setup.sh",
"test": "tap",
"snap": "tap",
"lint": "eslint \"**/*.js\"",
@@ -22,8 +23,8 @@
]
},
"devDependencies": {
- "@npmcli/eslint-config": "^3.1.0",
- "@npmcli/template-oss": "4.5.1",
+ "@npmcli/eslint-config": "^4.0.0",
+ "@npmcli/template-oss": "4.10.0",
"@ungap/url-search-params": "^0.2.2",
"abort-controller": "^3.0.0",
"abortcontroller-polyfill": "~1.7.3",
@@ -35,7 +36,7 @@
"tap": "^16.0.0"
},
"dependencies": {
- "minipass": "^3.1.6",
+ "minipass": "^4.0.0",
"minipass-sized": "^1.0.3",
"minizlib": "^2.1.2"
},
@@ -62,6 +63,6 @@
"author": "GitHub Inc.",
"templateOSS": {
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
- "version": "4.5.1"
+ "version": "4.10.0"
}
}
diff --git a/deps/npm/package.json b/deps/npm/package.json
index ebfcc0eec2..73c41bc2b4 100644
--- a/deps/npm/package.json
+++ b/deps/npm/package.json
@@ -1,5 +1,5 @@
{
- "version": "9.2.0",
+ "version": "9.3.0",
"name": "npm",
"description": "a package manager for JavaScript",
"workspaces": [
@@ -53,8 +53,8 @@
},
"dependencies": {
"@isaacs/string-locale-compare": "^1.1.0",
- "@npmcli/arborist": "^6.1.5",
- "@npmcli/config": "^6.1.0",
+ "@npmcli/arborist": "^6.1.6",
+ "@npmcli/config": "^6.1.1",
"@npmcli/map-workspaces": "^3.0.0",
"@npmcli/package-json": "^3.0.0",
"@npmcli/run-script": "^6.0.0",
@@ -76,12 +76,12 @@
"is-cidr": "^4.0.2",
"json-parse-even-better-errors": "^3.0.0",
"libnpmaccess": "^7.0.1",
- "libnpmdiff": "^5.0.6",
- "libnpmexec": "^5.0.6",
- "libnpmfund": "^4.0.6",
+ "libnpmdiff": "^5.0.7",
+ "libnpmexec": "^5.0.7",
+ "libnpmfund": "^4.0.7",
"libnpmhook": "^9.0.1",
"libnpmorg": "^5.0.1",
- "libnpmpack": "^5.0.6",
+ "libnpmpack": "^5.0.7",
"libnpmpublish": "^7.0.6",
"libnpmsearch": "^6.0.1",
"libnpmteam": "^5.0.1",
@@ -110,7 +110,6 @@
"read": "~1.0.7",
"read-package-json": "^6.0.0",
"read-package-json-fast": "^3.0.1",
- "rimraf": "^3.0.2",
"semver": "^7.3.8",
"ssri": "^10.0.1",
"tar": "^6.1.13",
@@ -180,7 +179,6 @@
"read",
"read-package-json",
"read-package-json-fast",
- "rimraf",
"semver",
"ssri",
"tar",
@@ -199,14 +197,14 @@
"@npmcli/mock-registry": "^1.0.0",
"@npmcli/promise-spawn": "^6.0.1",
"@npmcli/template-oss": "4.11.0",
- "licensee": "^9.0.0",
+ "licensee": "^10.0.0",
"nock": "^13.2.4",
"npm-packlist": "^7.0.4",
"remark": "^14.0.2",
"remark-gfm": "^3.0.1",
"remark-github": "^11.2.4",
"spawk": "^1.7.1",
- "tap": "^16.0.1"
+ "tap": "^16.3.2"
},
"scripts": {
"dependencies": "node scripts/bundle-and-gitignore-deps.js && node scripts/dependency-graph.js",
diff --git a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs
index 3e7658c14b..9262e0b51a 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/audit.js.test.cjs
@@ -123,7 +123,7 @@ audited 1 package in xxx
1 package has an invalid registry signature:
-@npmcli/arborist@1.0.14 (https://verdaccio-clone.org)
+@npmcli/arborist@1.0.14 (https://verdaccio-clone.org/)
Someone might have tampered with this package since it was published on the registry!
@@ -134,7 +134,7 @@ audited 1 package in xxx
1 package has a missing registry signature but the registry is providing signing keys:
-@npmcli/arborist@1.0.14 (https://verdaccio-clone.org)
+@npmcli/arborist@1.0.14 (https://verdaccio-clone.org/)
`
exports[`test/lib/commands/audit.js TAP audit signatures third-party registry with keys and signatures > must match snapshot 1`] = `
diff --git a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
index 2c2646bb29..667a7c78b3 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/config.js.test.cjs
@@ -354,7 +354,6 @@ exports[`test/lib/commands/config.js TAP config list with publishConfig > output
; "cli" config from command line options
cache = "{NPMDIR}/test/lib/commands/tap-testdir-config-config-list-with-publishConfig-sandbox/cache"
-location = "project"
prefix = "{LOCALPREFIX}"
userconfig = "{HOME}/.npmrc"
diff --git a/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs
new file mode 100644
index 0000000000..533b4f196e
--- /dev/null
+++ b/deps/npm/tap-snapshots/test/lib/commands/diff.js.test.cjs
@@ -0,0 +1,88 @@
+/* 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/commands/diff.js TAP no args in a project dir > must match snapshot 1`] = `
+diff --git a/a.js b/a.js
+index v0.1.0..v1.0.0 100644
+--- a/a.js
++++ b/a.js
+@@ -1,1 +1,1 @@
+-const a = "a@0.1.0"
++const a = "a@1.0.0"
+diff --git a/b.js b/b.js
+index v0.1.0..v1.0.0 100644
+--- a/b.js
++++ b/b.js
+@@ -1,1 +1,1 @@
+-const b = "b@0.1.0"
++const b = "b@1.0.0"
+diff --git a/index.js b/index.js
+index v0.1.0..v1.0.0 100644
+--- a/index.js
++++ b/index.js
+@@ -1,1 +1,1 @@
+-const version = "0.1.0"
++const version = "1.0.0"
+diff --git a/package.json b/package.json
+index v0.1.0..v1.0.0 100644
+--- a/package.json
++++ b/package.json
+@@ -1,4 +1,4 @@
+ {
+ "name": "foo",
+- "version": "0.1.0"
++ "version": "1.0.0"
+ }
+`
+
+exports[`test/lib/commands/diff.js TAP single arg version, filtering by files > must match snapshot 1`] = `
+diff --git a/a.js b/a.js
+index v0.1.0..v1.0.0 100644
+--- a/a.js
++++ b/a.js
+@@ -1,1 +1,1 @@
+-const a = "a@0.1.0"
++const a = "a@1.0.0"
+diff --git a/b.js b/b.js
+index v0.1.0..v1.0.0 100644
+--- a/b.js
++++ b/b.js
+@@ -1,1 +1,1 @@
+-const b = "b@0.1.0"
++const b = "b@1.0.0"
+`
+
+exports[`test/lib/commands/diff.js TAP various options using --name-only option > must match snapshot 1`] = `
+index.js
+package.json
+`
+
+exports[`test/lib/commands/diff.js TAP various options using diff option > must match snapshot 1`] = `
+diff --git a/index.js b/index.js
+index v2.0.0..v3.0.0 100644
+--- a/index.js
++++ b/index.js
+@@ -18,7 +18,7 @@
+ 17
+ 18
+ 19
+-202.0.0
++203.0.0
+ 21
+ 22
+ 23
+diff --git a/package.json b/package.json
+index v2.0.0..v3.0.0 100644
+--- a/package.json
++++ b/package.json
+@@ -1,4 +1,4 @@
+ {
+ "name": "bar",
+- "version": "2.0.0"
++ "version": "3.0.0"
+ }
+`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs
index 2b75899e4e..ebc823e7e0 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/dist-tag.js.test.cjs
@@ -11,7 +11,6 @@ exports[`test/lib/commands/dist-tag.js TAP add new tag > should return success m
exports[`test/lib/commands/dist-tag.js TAP add using valid semver range as name > should return success msg 1`] = `
dist-tag add 1.0.0 to @scoped/another@7.7.7
-
`
exports[`test/lib/commands/dist-tag.js TAP ls in current package > should list available tags for current package 1`] = `
@@ -22,7 +21,6 @@ latest: 1.0.0
exports[`test/lib/commands/dist-tag.js TAP ls on missing package > should log no dist-tag found msg 1`] = `
dist-tag ls Couldn't get dist-tag data for foo@*
-
`
exports[`test/lib/commands/dist-tag.js TAP ls on named package > should list tags for the specified package 1`] = `
@@ -45,7 +43,6 @@ latest: 2.0.0
exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should log remove info 1`] = `
dist-tag del c from @scoped/another
-
`
exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should return success msg 1`] = `
@@ -55,13 +52,11 @@ exports[`test/lib/commands/dist-tag.js TAP remove existing tag > should return s
exports[`test/lib/commands/dist-tag.js TAP remove non-existing tag > should log error msg 1`] = `
dist-tag del nonexistent from @scoped/another
dist-tag del nonexistent is not a dist-tag on @scoped/another
-
`
exports[`test/lib/commands/dist-tag.js TAP set existing version > should log warn msg 1`] = `
dist-tag add b to @scoped/another@0.6.0
dist-tag add b is already set to version 0.6.0
-
`
exports[`test/lib/commands/dist-tag.js TAP workspaces no args > printed the expected output 1`] = `
@@ -95,7 +90,7 @@ latest-a: 1.0.0
latest: 1.0.0
`
-exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- . > printed the expected output 1`] = `
+exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- .@1, ignores version spec > printed the expected output 1`] = `
workspace-a:
latest-a: 1.0.0
latest: 1.0.0
@@ -107,7 +102,7 @@ latest-c: 3.0.0
latest: 3.0.0
`
-exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- .@1, ignores version spec > printed the expected output 1`] = `
+exports[`test/lib/commands/dist-tag.js TAP workspaces one arg -- cwd > printed the expected output 1`] = `
workspace-a:
latest-a: 1.0.0
latest: 1.0.0
@@ -131,7 +126,7 @@ latest-c: 3.0.0
latest: 3.0.0
`
-exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, . > printed the expected output 1`] = `
+exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, .@1, ignores version spec > printed the expected output 1`] = `
workspace-a:
latest-a: 1.0.0
latest: 1.0.0
@@ -143,7 +138,13 @@ latest-c: 3.0.0
latest: 3.0.0
`
-exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, .@1, ignores version spec > printed the expected output 1`] = `
+exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, @scoped/pkg, logs a warning and ignores workspaces > printed the expected output 1`] = `
+a: 0.0.1
+b: 0.5.0
+latest: 1.0.0
+`
+
+exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, cwd > printed the expected output 1`] = `
workspace-a:
latest-a: 1.0.0
latest: 1.0.0
@@ -154,9 +155,3 @@ workspace-c:
latest-c: 3.0.0
latest: 3.0.0
`
-
-exports[`test/lib/commands/dist-tag.js TAP workspaces two args -- list, @scoped/pkg, logs a warning and ignores workspaces > printed the expected output 1`] = `
-a: 0.0.1
-b: 0.5.0
-latest: 1.0.0
-`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
index 861aad3e25..2cf8dca12b 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/doctor.js.test.cjs
@@ -59,7 +59,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-all-clear/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -75,7 +75,7 @@ npm -v  ok  curren
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-all-clear-in-color/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -185,7 +185,7 @@ npm -v  not ok Error: unsupport
node -v  not ok Error: unsupported proxy protocol: 'ssh:'
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-bad-proxy/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -201,7 +201,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-cacache-badContent/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -329,7 +329,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-cacache-missingContent/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -345,7 +345,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-cacache-reclaimedCount/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -482,7 +482,7 @@ Object {
exports[`test/lib/commands/doctor.js TAP discrete checks invalid environment > output 1`] = `
Check  Value  Recommendation/Notes
git executable in PATH  ok  /path/to/git
-global bin folder in PATH not ok Error: Add {CWD}/test/lib/commands/tap-testdir-doctor-discrete-checks-invalid-environment/global/bin to your $PATH
+global bin folder in PATH not ok Error: Add {CWD}/global/bin to your $PATH
`
exports[`test/lib/commands/doctor.js TAP discrete checks permissions - not windows > logs 1`] = `
@@ -637,23 +637,23 @@ Object {
"warn": Array [
Array [
"checkFilesPermission",
- "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/cache",
+ "error reading directory {CWD}/cache",
],
Array [
"checkFilesPermission",
- "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules",
+ "error reading directory {CWD}/prefix/node_modules",
],
Array [
"checkFilesPermission",
- "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/lib/node_modules",
+ "error reading directory {CWD}/global/node_modules",
],
Array [
"checkFilesPermission",
- "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules/.bin",
+ "error reading directory {CWD}/prefix/node_modules/.bin",
],
Array [
"checkFilesPermission",
- "error reading directory {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/bin",
+ "error reading directory {CWD}/global/bin",
],
],
}
@@ -666,12 +666,12 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/bin
-Perms check on cached files  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/cache (should be owned by current user)
-Perms check on local node_modules  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules (should be owned by current user)
-Perms check on global node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/lib/node_modules
-Perms check on local bin folder  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/prefix/node_modules/.bin
-Perms check on global bin folder  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-error-reading-directory/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
+Perms check on cached files  not ok Check the permissions of files in {CWD}/cache (should be owned by current user)
+Perms check on local node_modules  not ok Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user)
+Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules
+Perms check on local bin folder  not ok Check the permissions of files in {CWD}/prefix/node_modules/.bin
+Perms check on global bin folder  not ok Check the permissions of files in {CWD}/global/bin
Verify cache contents  ok  verified 0 tarballs
`
@@ -682,8 +682,8 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/global/bin
-Perms check on cached files  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache (should be owned by current user)
+global bin folder in PATH  ok  {CWD}/global/bin
+Perms check on cached files  not ok Check the permissions of files in {CWD}/cache (should be owned by current user)
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
Perms check on local bin folder  ok  
@@ -737,7 +737,7 @@ Object {
"warn": Array [
Array [
"checkFilesPermission",
- "should be owner of {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-owner/cache/_cacache",
+ "should be owner of {CWD}/cache/_cacache",
],
],
}
@@ -750,12 +750,12 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/bin
-Perms check on cached files  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/cache (should be owned by current user)
-Perms check on local node_modules  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules (should be owned by current user)
-Perms check on global node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/lib/node_modules
-Perms check on local bin folder  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules/.bin
-Perms check on global bin folder  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
+Perms check on cached files  not ok Check the permissions of files in {CWD}/cache (should be owned by current user)
+Perms check on local node_modules  not ok Check the permissions of files in {CWD}/prefix/node_modules (should be owned by current user)
+Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules
+Perms check on local bin folder  not ok Check the permissions of files in {CWD}/prefix/node_modules/.bin
+Perms check on global bin folder  not ok Check the permissions of files in {CWD}/global/bin
Verify cache contents  ok  verified 0 tarballs
`
@@ -764,23 +764,23 @@ Object {
"error": Array [
Array [
"checkFilesPermission",
- "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/cache (expect: readable)",
+ "Missing permissions on {CWD}/cache (expect: readable)",
],
Array [
"checkFilesPermission",
- "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules (expect: readable, writable)",
+ "Missing permissions on {CWD}/prefix/node_modules (expect: readable, writable)",
],
Array [
"checkFilesPermission",
- "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/lib/node_modules (expect: readable)",
+ "Missing permissions on {CWD}/global/node_modules (expect: readable)",
],
Array [
"checkFilesPermission",
- "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/prefix/node_modules/.bin (expect: readable, writable, executable)",
+ "Missing permissions on {CWD}/prefix/node_modules/.bin (expect: readable, writable, executable)",
],
Array [
"checkFilesPermission",
- "Missing permissions on {CWD}/test/lib/commands/tap-testdir-doctor-incorrect-permissions/global/bin (expect: executable)",
+ "Missing permissions on {CWD}/global/bin (expect: executable)",
],
],
"info": Array [
@@ -885,7 +885,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  not ok Error: Install git and ensure it's in your PATH.
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-missing-git/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -940,11 +940,11 @@ Object {
"warn": Array [
Array [
"checkFilesPermission",
- "error getting info for {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/lib/node_modules",
+ "error getting info for {CWD}/global/node_modules",
],
Array [
"checkFilesPermission",
- "error getting info for {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/bin",
+ "error getting info for {CWD}/global/bin",
],
],
}
@@ -957,12 +957,12 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
-Perms check on global node_modules not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/lib/node_modules
+Perms check on global node_modules not ok Check the permissions of files in {CWD}/global/node_modules
Perms check on local bin folder  ok  
-Perms check on global bin folder  not ok Check the permissions of files in {CWD}/test/lib/commands/tap-testdir-doctor-missing-global-directories/global/bin
+Perms check on global bin folder  not ok Check the permissions of files in {CWD}/global/bin
Verify cache contents  ok  verified 0 tarballs
`
@@ -1020,7 +1020,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-missing-local-node_modules/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1083,7 +1083,7 @@ npm -v  ok  current: v1.0.0,
node -v  not ok Use node v2.0.1 (current: v2.0.0)
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-node-out-of-date---current/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1146,7 +1146,7 @@ npm -v  ok  current: v1.0.0,
node -v  not ok Use node v1.0.0 (current: v0.0.1)
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-node-out-of-date---lts/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1209,7 +1209,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  not ok Try \`npm config set registry=https://registry.npmjs.org/\`
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-non-default-registry/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1272,7 +1272,7 @@ npm -v  not ok Use npm v2.0.0
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-npm-out-of-date/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1335,7 +1335,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-ping-404/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1398,7 +1398,7 @@ npm -v  ok  curren
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-ping-404-in-color/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1461,7 +1461,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-ping-exception-with-code/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1524,7 +1524,7 @@ npm -v  ok  current: v1.0.0,
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH  ok  {CWD}/test/lib/commands/tap-testdir-doctor-ping-exception-without-code/global/bin
+global bin folder in PATH  ok  {CWD}/global/bin
Perms check on cached files  ok  
Perms check on local node_modules  ok  
Perms check on global node_modules ok  
@@ -1643,5 +1643,5 @@ npm -v  ok  current: v1.0.0, latest:
node -v  ok  current: v1.0.0, recommended: v1.0.0
npm config get registry  ok  using default registry (https://registry.npmjs.org/)
git executable in PATH  ok  /path/to/git
-global bin folder in PATH ok  {CWD}/test/lib/commands/tap-testdir-doctor-windows-skips-permissions-checks/global
+global bin folder in PATH ok  {CWD}/global
`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs
index f0df1e1c58..011315a921 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/fund.js.test.cjs
@@ -8,8 +8,7 @@
exports[`test/lib/commands/fund.js TAP fund a package with type and multiple sources > should print prompt select message 1`] = `
1: Foo funding available at the following URL: http://example.com/foo
2: Lorem funding available at the following URL: http://example.com/foo-lorem
-Run \`npm fund [<@scope>/]<pkg> --which=1\`, for example, to open the first funding URL listed in that package
-
+Run \`npm fund [<package-spec>] --which=1\`, for example, to open the first funding URL listed in that package
`
exports[`test/lib/commands/fund.js TAP fund colors > should print output with color info 1`] = `
@@ -23,7 +22,6 @@ exports[`test/lib/commands/fund.js TAP fund colors > should print output with co
 \`-- http://example.com/e
 \`-- e@1.0.0

-
`
exports[`test/lib/commands/fund.js TAP fund containing multi-level nested deps with no funding > should omit dependencies with no funding declared 1`] = `
@@ -33,54 +31,37 @@ nested-no-funding-packages@1.0.0
\`-- http://example.com/donate
\`-- bar@1.0.0
-
`
exports[`test/lib/commands/fund.js TAP fund in which same maintainer owns all its deps > should print stack packages together 1`] = `
http://example.com/donate
\`-- maintainer-owns-all-deps@1.0.0, dep-foo@1.0.0, dep-sub-foo@1.0.0, dep-bar@1.0.0
-
`
exports[`test/lib/commands/fund.js TAP fund pkg missing version number > should print name only 1`] = `
http://example.com/foo
\`-- foo
+`
+exports[`test/lib/commands/fund.js TAP fund using bad which value: index too high > should print message about invalid which 1`] = `
+--which=100 is not a valid index
+1: Funding available at the following URL: http://example.com
+2: Funding available at the following URL: http://sponsors.example.com/me
+3: Funding available at the following URL: http://collective.example.com
+Run \`npm fund [<package-spec>] --which=1\`, for example, to open the first funding URL listed in that package
`
exports[`test/lib/commands/fund.js TAP fund using nested packages with multiple sources > should prompt with all available URLs 1`] = `
1: Funding available at the following URL: https://one.example.com
2: Funding available at the following URL: https://two.example.com
-Run \`npm fund [<@scope>/]<pkg> --which=1\`, for example, to open the first funding URL listed in that package
-
-`
-
-exports[`test/lib/commands/fund.js TAP fund using nested packages with multiple sources, with a source number > should open the numbered URL 1`] = `
-Funding available at the following URL:
- https://one.example.com
-`
-
-exports[`test/lib/commands/fund.js TAP fund using package argument > should open funding url 1`] = `
-individual funding available at the following URL:
- http://example.com/donate
-`
-
-exports[`test/lib/commands/fund.js TAP fund using pkg name while having conflicting versions > should open greatest version 1`] = `
-Funding available at the following URL:
- http://example.com/2
-`
-
-exports[`test/lib/commands/fund.js TAP fund using string shorthand > should open string-only url 1`] = `
-Funding available at the following URL:
- https://example.com/sponsor
+Run \`npm fund [<package-spec>] --which=1\`, for example, to open the first funding URL listed in that package
`
exports[`test/lib/commands/fund.js TAP fund with no package containing funding > should print empty funding info 1`] = `
no-funding-package@0.0.0
-
`
exports[`test/lib/commands/fund.js TAP sub dep with fund info and a parent with no funding info > should nest sub dep as child of root 1`] = `
@@ -90,25 +71,22 @@ test-multiple-funding-sources@1.0.0
\`-- http://example.com/c
\`-- c@1.0.0
-
`
-exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace > should display only filtered workspace name and its deps 1`] = `
+exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace name > should display only filtered workspace name and its deps 1`] = `
workspaces-support@1.0.0
\`-- https://example.com/a
| \`-- a@1.0.0
\`-- http://example.com/c
\`-- c@1.0.0
-
`
-exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace > should display only filtered workspace path and its deps 1`] = `
+exports[`test/lib/commands/fund.js TAP workspaces filter funding info by a specific workspace path > should display only filtered workspace name and its deps 1`] = `
workspaces-support@1.0.0
\`-- https://example.com/a
| \`-- a@1.0.0
\`-- http://example.com/c
\`-- c@1.0.0
-
`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs
index 677f29a1ab..821193a55e 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/init.js.test.cjs
@@ -5,55 +5,20 @@
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
-exports[`test/lib/commands/init.js TAP npm init workspces with root > does not print helper info 1`] = `
-Array []
-`
-
-exports[`test/lib/commands/init.js TAP workspaces no args > should print helper info 1`] = `
-Array []
-`
+exports[`test/lib/commands/init.js TAP displays output > displays 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.
-exports[`test/lib/commands/init.js TAP workspaces no args, existing folder > should print helper info 1`] = `
-Array []
-`
+See \`npm help init\` for definitive documentation on these fields
+and exactly what they do.
-exports[`test/lib/commands/init.js TAP workspaces post workspace-init reify > should print helper info 1`] = `
-Array [
- Array [
- String(
+Use \`npm install <pkg>\` afterwards to install a package and
+save it as a dependency in the package.json file.
- added 1 package in 100ms
- ),
- ],
-]
+Press ^C at any time to quit.
`
-exports[`test/lib/commands/init.js TAP workspaces post workspace-init reify > should reify tree on init ws complete 1`] = `
-{
- "name": "top-level",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "top-level",
- "workspaces": [
- "a"
- ]
- },
- "a": {
- "version": "1.0.0",
- "license": "ISC",
- "devDependencies": {}
- },
- "node_modules/a": {
- "resolved": "a",
- "link": true
- }
- }
-}
-
-`
+exports[`test/lib/commands/init.js TAP workspaces no args -- yes > should print helper info 1`] = `
-exports[`test/lib/commands/init.js TAP workspaces with arg but missing workspace folder > should print helper info 1`] = `
-Array []
+added 1 package in {TIME}
`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/link.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/link.js.test.cjs
index 0c34bd972d..c26e30da1e 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/link.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/link.js.test.cjs
@@ -6,50 +6,50 @@
*/
'use strict'
exports[`test/lib/commands/link.js TAP hash character in working directory path > should create a global link to current pkg, even within path with hash 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-hash-character-in-working-directory-path/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-hash-character-in-working-directory-path/i_like_#_in_my_paths/test-pkg-link
+{CWD}/global/node_modules/test-pkg-link -> {CWD}/other/i_like_#_in_my_paths/test-pkg-link
`
exports[`test/lib/commands/link.js TAP link global linked pkg to local nm when using args > should create a local symlink to global pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/@myscope/bar
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/scoped-linked
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/global-prefix/lib/node_modules/a
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/link-me-too -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/link-me-too
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-nm-when-using-args/test-pkg-link
+{CWD}/prefix/node_modules/@myscope/bar -> {CWD}/global/node_modules/@myscope/bar
+{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked
+{CWD}/prefix/node_modules/a -> {CWD}/global/node_modules/a
+{CWD}/prefix/node_modules/link-me-too -> {CWD}/other/link-me-too
+{CWD}/prefix/node_modules/test-pkg-link -> {CWD}/other/test-pkg-link
`
exports[`test/lib/commands/link.js TAP link global linked pkg to local workspace using args > should create a local symlink to global pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/@myscope/bar -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/global-prefix/lib/node_modules/@myscope/bar
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/scoped-linked
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/global-prefix/lib/node_modules/a
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/link-me-too -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/link-me-too
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/test-pkg-link
-{CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/node_modules/x -> {CWD}/test/lib/commands/tap-testdir-link-link-global-linked-pkg-to-local-workspace-using-args/my-project/packages/x
+{CWD}/prefix/node_modules/@myscope/bar -> {CWD}/global/node_modules/@myscope/bar
+{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked
+{CWD}/prefix/node_modules/a -> {CWD}/global/node_modules/a
+{CWD}/prefix/node_modules/link-me-too -> {CWD}/other/link-me-too
+{CWD}/prefix/node_modules/test-pkg-link -> {CWD}/other/test-pkg-link
+{CWD}/prefix/node_modules/x -> {CWD}/prefix/packages/x
`
exports[`test/lib/commands/link.js TAP link pkg already in global space > should create a local symlink to global pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space/scoped-linked
+{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked
`
exports[`test/lib/commands/link.js TAP link pkg already in global space when prefix is a symlink > should create a local symlink to global pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/my-project/node_modules/@myscope/linked -> {CWD}/test/lib/commands/tap-testdir-link-link-pkg-already-in-global-space-when-prefix-is-a-symlink/scoped-linked
+{CWD}/prefix/node_modules/@myscope/linked -> {CWD}/other/scoped-linked
`
exports[`test/lib/commands/link.js TAP link to globalDir when in current working dir of pkg and no args > should create a global link to current pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/global-prefix/lib/node_modules/test-pkg-link -> {CWD}/test/lib/commands/tap-testdir-link-link-to-globalDir-when-in-current-working-dir-of-pkg-and-no-args/test-pkg-link
+{CWD}/global/node_modules/test-pkg-link -> {CWD}/prefix
`
exports[`test/lib/commands/link.js TAP link ws to globalDir when workspace specified and no args > should create a global link to current pkg 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/global-prefix/lib/node_modules/a -> {CWD}/test/lib/commands/tap-testdir-link-link-ws-to-globalDir-when-workspace-specified-and-no-args/test-pkg-link/packages/a
+{CWD}/global/node_modules/a -> {CWD}/prefix/packages/a
`
exports[`test/lib/commands/link.js TAP test linked installed as symlinks > linked package should not be installed 1`] = `
-{CWD}/test/lib/commands/tap-testdir-link-test-linked-installed-as-symlinks/prefix/node_modules/mylink -> {CWD}/test/lib/commands/tap-testdir-link-test-linked-installed-as-symlinks/other/mylink
+{CWD}/prefix/node_modules/mylink -> {CWD}/other/mylink
`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs
index 84bfed4c91..a6e4472cae 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/ls.js.test.cjs
@@ -7,53 +7,53 @@
'use strict'
exports[`test/lib/commands/ls.js TAP ignore missing optional deps --json > ls --json problems 1`] = `
Array [
- "invalid: optional-wrong@3.2.1 {project}/node_modules/optional-wrong",
+ "invalid: optional-wrong@3.2.1 {CWD}/prefix/node_modules/optional-wrong",
"missing: peer-missing@1, required by test-npm-ls-ignore-missing-optional@1.2.3",
- "invalid: peer-optional-wrong@3.2.1 {project}/node_modules/peer-optional-wrong",
- "invalid: peer-wrong@3.2.1 {project}/node_modules/peer-wrong",
+ "invalid: peer-optional-wrong@3.2.1 {CWD}/prefix/node_modules/peer-optional-wrong",
+ "invalid: peer-wrong@3.2.1 {CWD}/prefix/node_modules/peer-wrong",
"missing: prod-missing@1, required by test-npm-ls-ignore-missing-optional@1.2.3",
- "invalid: prod-wrong@3.2.1 {project}/node_modules/prod-wrong",
+ "invalid: prod-wrong@3.2.1 {CWD}/prefix/node_modules/prod-wrong",
]
`
exports[`test/lib/commands/ls.js TAP ignore missing optional deps --parseable > ls --parseable result 1`] = `
-{project}
-{project}/node_modules/optional-ok
-{project}/node_modules/optional-wrong
-{project}/node_modules/peer-ok
-{project}/node_modules/peer-optional-ok
-{project}/node_modules/peer-optional-wrong
-{project}/node_modules/peer-wrong
-{project}/node_modules/prod-ok
-{project}/node_modules/prod-wrong
+{CWD}/prefix
+{CWD}/prefix/node_modules/optional-ok
+{CWD}/prefix/node_modules/optional-wrong
+{CWD}/prefix/node_modules/peer-ok
+{CWD}/prefix/node_modules/peer-optional-ok
+{CWD}/prefix/node_modules/peer-optional-wrong
+{CWD}/prefix/node_modules/peer-wrong
+{CWD}/prefix/node_modules/prod-ok
+{CWD}/prefix/node_modules/prod-wrong
`
exports[`test/lib/commands/ls.js TAP ignore missing optional deps human output > ls result 1`] = `
-test-npm-ls-ignore-missing-optional@1.2.3 {project}
-+-- unmet optional dependency optional-missing@1
+test-npm-ls-ignore-missing-optional@1.2.3 {CWD}/prefix
++-- UNMET OPTIONAL DEPENDENCY optional-missing@1
+-- optional-ok@1.2.3
+-- optional-wrong@3.2.1 invalid: "1" from the root project
-+-- unmet dependency peer-missing@1
++-- UNMET DEPENDENCY peer-missing@1
+-- peer-ok@1.2.3
-+-- unmet optional dependency peer-optional-missing@1
++-- UNMET OPTIONAL DEPENDENCY peer-optional-missing@1
+-- peer-optional-ok@1.2.3
+-- peer-optional-wrong@3.2.1 invalid: "1" from the root project
+-- peer-wrong@3.2.1 invalid: "1" from the root project
-+-- unmet dependency prod-missing@1
++-- UNMET DEPENDENCY prod-missing@1
+-- prod-ok@1.2.3
\`-- prod-wrong@3.2.1 invalid: "1" from the root project
`
exports[`test/lib/commands/ls.js TAP ls --depth=0 > should output tree containing only top-level dependencies 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---depth-0
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
\`-- foo@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --depth=1 > should output tree containing top-level deps and their deps only 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---depth-1
+test-npm-ls@1.0.0 {CWD}/prefix
+-- a@1.0.0
| \`-- b@1.0.0
\`-- e@1.0.0
@@ -61,7 +61,7 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---depth-1
`
exports[`test/lib/commands/ls.js TAP ls --dev > should output tree containing dev deps 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---dev
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- dev-dep@1.0.0
\`-- foo@1.0.0
\`-- dog@1.0.0
@@ -69,14 +69,14 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---dev
`
exports[`test/lib/commands/ls.js TAP ls --link > should output tree containing linked deps 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---link
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- linked-dep@1.0.0 -> ./linked-dep
`
exports[`test/lib/commands/ls.js TAP ls --long --depth=0 > should output tree containing top-level deps with descriptions 1`] = `
test-npm-ls@1.0.0
-| {CWD}/tap-testdir-ls-ls---long---depth-0
+| {CWD}/prefix
|
+-- chai@1.0.0
|
@@ -93,7 +93,7 @@ test-npm-ls@1.0.0
exports[`test/lib/commands/ls.js TAP ls --long > should output tree info with descriptions 1`] = `
test-npm-ls@1.0.0
-| {CWD}/tap-testdir-ls-ls---long
+| {CWD}/prefix
|
+-- chai@1.0.0
|
@@ -115,192 +115,192 @@ test-npm-ls@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --depth=0 > should output tree containing only top-level dependencies 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---depth-0
-{CWD}/tap-testdir-ls-ls---parseable---depth-0/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable---depth-0/node_modules/foo
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
`
exports[`test/lib/commands/ls.js TAP ls --parseable --depth=1 > should output parseable containing top-level deps and their deps only 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---depth-1
-{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable---depth-1/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable --dev > should output tree containing dev deps 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---dev
-{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/dev-dep
-{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable---dev/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/dev-dep
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable --link > should output tree containing linked deps 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---link
-{CWD}/tap-testdir-ls-ls---parseable---link/node_modules/linked-dep
+{CWD}/prefix
+{CWD}/prefix/node_modules/linked-dep
`
exports[`test/lib/commands/ls.js TAP ls --parseable --long --depth=0 > should output tree containing top-level deps with descriptions 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0:test-npm-ls@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/chai:chai@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/dev-dep:dev-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/optional-dep:optional-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/peer-dep:peer-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long---depth-0/node_modules/prod-dep:prod-dep@1.0.0
+{CWD}/prefix:test-npm-ls@1.0.0
+{CWD}/prefix/node_modules/chai:chai@1.0.0
+{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0
+{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0
+{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0
+{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --long > should output tree info with descriptions 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---long:test-npm-ls@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/chai:chai@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/dev-dep:dev-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/optional-dep:optional-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/peer-dep:peer-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/prod-dep:prod-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/foo:foo@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/prod-dep/node_modules/dog:dog@2.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long/node_modules/dog:dog@1.0.0
+{CWD}/prefix:test-npm-ls@1.0.0
+{CWD}/prefix/node_modules/chai:chai@1.0.0
+{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0
+{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0
+{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0
+{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0
+{CWD}/prefix/node_modules/foo:foo@1.0.0
+{CWD}/prefix/node_modules/prod-dep/node_modules/dog:dog@2.0.0
+{CWD}/prefix/node_modules/dog:dog@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --long missing/invalid/extraneous > should output parseable result containing EXTRANEOUS/INVALID labels 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous:test-npm-ls@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/chai:chai@1.0.0:EXTRANEOUS
-{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/foo:foo@1.0.0:INVALID
-{CWD}/tap-testdir-ls-ls---parseable---long-missing-invalid-extraneous/node_modules/dog:dog@1.0.0
+{CWD}/prefix:test-npm-ls@1.0.0
+{CWD}/prefix/node_modules/chai:chai@1.0.0:EXTRANEOUS
+{CWD}/prefix/node_modules/foo:foo@1.0.0:INVALID
+{CWD}/prefix/node_modules/dog:dog@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --long print symlink target location > should output parseable results with symlink targets 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location:test-npm-ls@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/chai:chai@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/dev-dep:dev-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/linked-dep:linked-dep@1.0.0:{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/linked-dep
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/optional-dep:optional-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/peer-dep:peer-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/prod-dep:prod-dep@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/foo:foo@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/prod-dep/node_modules/dog:dog@2.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-print-symlink-target-location/node_modules/dog:dog@1.0.0
+{CWD}/prefix:test-npm-ls@1.0.0
+{CWD}/prefix/node_modules/chai:chai@1.0.0
+{CWD}/prefix/node_modules/dev-dep:dev-dep@1.0.0
+{CWD}/prefix/node_modules/linked-dep:linked-dep@1.0.0:{CWD}/prefix/linked-dep
+{CWD}/prefix/node_modules/optional-dep:optional-dep@1.0.0
+{CWD}/prefix/node_modules/peer-dep:peer-dep@1.0.0
+{CWD}/prefix/node_modules/prod-dep:prod-dep@1.0.0
+{CWD}/prefix/node_modules/foo:foo@1.0.0
+{CWD}/prefix/node_modules/prod-dep/node_modules/dog:dog@2.0.0
+{CWD}/prefix/node_modules/dog:dog@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --long with extraneous deps > should output long parseable output with extraneous info 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps:test-npm-ls@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/chai:chai@1.0.0:EXTRANEOUS
-{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/foo:foo@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable---long-with-extraneous-deps/node_modules/dog:dog@1.0.0
+{CWD}/prefix:test-npm-ls@1.0.0
+{CWD}/prefix/node_modules/chai:chai@1.0.0:EXTRANEOUS
+{CWD}/prefix/node_modules/foo:foo@1.0.0
+{CWD}/prefix/node_modules/dog:dog@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls --parseable --production > should output tree containing production deps 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable---production
-{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/optional-dep
-{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/prod-dep
-{CWD}/tap-testdir-ls-ls---parseable---production/node_modules/prod-dep/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/optional-dep
+{CWD}/prefix/node_modules/prod-dep
+{CWD}/prefix/node_modules/prod-dep/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable cycle deps > should print tree output omitting deduped ref 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-cycle-deps
-{CWD}/tap-testdir-ls-ls---parseable-cycle-deps/node_modules/a
-{CWD}/tap-testdir-ls-ls---parseable-cycle-deps/node_modules/b
+{CWD}/prefix
+{CWD}/prefix/node_modules/a
+{CWD}/prefix/node_modules/b
`
exports[`test/lib/commands/ls.js TAP ls --parseable default --depth value should be 0 > should output parseable output containing only top-level dependencies 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0
-{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-default---depth-value-should-be-0/node_modules/foo
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
`
exports[`test/lib/commands/ls.js TAP ls --parseable empty location > should print empty result 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-empty-location
+{CWD}/prefix
`
exports[`test/lib/commands/ls.js TAP ls --parseable extraneous deps > should output containing problems info 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps
-{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable-extraneous-deps/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable from and resolved properties > should not be printed in tree output 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-from-and-resolved-properties
-{CWD}/tap-testdir-ls-ls---parseable-from-and-resolved-properties/node_modules/simple-output
+{CWD}/prefix
+{CWD}/prefix/node_modules/simple-output
`
exports[`test/lib/commands/ls.js TAP ls --parseable global > should print parseable output for global deps 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-global
-{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/a
-{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/b
-{CWD}/tap-testdir-ls-ls---parseable-global/node_modules/b/node_modules/c
+{CWD}/global
+{CWD}/global/node_modules/a
+{CWD}/global/node_modules/b
+{CWD}/global/node_modules/b/node_modules/c
`
exports[`test/lib/commands/ls.js TAP ls --parseable json read problems > should print empty result 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-json-read-problems
+{CWD}/prefix
`
exports[`test/lib/commands/ls.js TAP ls --parseable missing package.json > should output parseable missing name/version of top-level package 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-missing-package.json
-{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/dog
-{CWD}/tap-testdir-ls-ls---parseable-missing-package.json/node_modules/foo
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/dog
+{CWD}/prefix/node_modules/foo
`
exports[`test/lib/commands/ls.js TAP ls --parseable missing/invalid/extraneous > should output parseable containing top-level deps and their deps only 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous
-{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable-missing-invalid-extraneous/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable no args > should output parseable representation of dependencies structure 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-no-args
-{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable-no-args/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable overridden dep > should contain overridden outout 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-overridden-dep:test-overridden@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable-overridden-dep/node_modules/foo:foo@1.0.0
-{CWD}/tap-testdir-ls-ls---parseable-overridden-dep/node_modules/bar:bar@1.0.0:OVERRIDDEN
+{CWD}/prefix:test-overridden@1.0.0
+{CWD}/prefix/node_modules/foo:foo@1.0.0
+{CWD}/prefix/node_modules/bar:bar@1.0.0:OVERRIDDEN
`
exports[`test/lib/commands/ls.js TAP ls --parseable resolved points to git ref > should output tree containing git refs 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref
-{CWD}/tap-testdir-ls-ls---parseable-resolved-points-to-git-ref/node_modules/abbrev
+{CWD}/prefix
+{CWD}/prefix/node_modules/abbrev
`
exports[`test/lib/commands/ls.js TAP ls --parseable unmet optional dep > should output parseable with empty entry for missing optional deps 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/dev-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/optional-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/peer-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/prod-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/prod-dep/node_modules/dog
-{CWD}/tap-testdir-ls-ls---parseable-unmet-optional-dep/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/dev-dep
+{CWD}/prefix/node_modules/optional-dep
+{CWD}/prefix/node_modules/peer-dep
+{CWD}/prefix/node_modules/prod-dep
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/prod-dep/node_modules/dog
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable unmet peer dep > should output parseable signaling missing peer dep in problems 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/dev-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/optional-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/peer-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/prod-dep
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/foo
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/prod-dep/node_modules/dog
-{CWD}/tap-testdir-ls-ls---parseable-unmet-peer-dep/node_modules/dog
+{CWD}/prefix
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/dev-dep
+{CWD}/prefix/node_modules/optional-dep
+{CWD}/prefix/node_modules/peer-dep
+{CWD}/prefix/node_modules/prod-dep
+{CWD}/prefix/node_modules/foo
+{CWD}/prefix/node_modules/prod-dep/node_modules/dog
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable using aliases > should output tree containing aliases 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-using-aliases
-{CWD}/tap-testdir-ls-ls---parseable-using-aliases/node_modules/a
+{CWD}/prefix
+{CWD}/prefix/node_modules/a
`
exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg > should output parseable contaning only occurrences of filtered by package 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-with-filter-arg/node_modules/chai
+{CWD}/prefix/node_modules/chai
`
exports[`test/lib/commands/ls.js TAP ls --parseable with filter arg nested dep > should output parseable contaning only occurrences of filtered package 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-with-filter-arg-nested-dep/node_modules/dog
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --parseable with missing filter arg > should output parseable output containing no dependencies info 1`] = `
@@ -308,12 +308,12 @@ exports[`test/lib/commands/ls.js TAP ls --parseable with missing filter arg > sh
`
exports[`test/lib/commands/ls.js TAP ls --parseable with multiple filter args > should output parseable contaning only occurrences of multiple filtered packages and their ancestors 1`] = `
-{CWD}/tap-testdir-ls-ls---parseable-with-multiple-filter-args/node_modules/chai
-{CWD}/tap-testdir-ls-ls---parseable-with-multiple-filter-args/node_modules/dog
+{CWD}/prefix/node_modules/chai
+{CWD}/prefix/node_modules/dog
`
exports[`test/lib/commands/ls.js TAP ls --production > should output tree containing production deps 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---production
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
+-- optional-dep@1.0.0
\`-- prod-dep@1.0.0
@@ -322,13 +322,13 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls---production
`
exports[`test/lib/commands/ls.js TAP ls broken resolved field > should NOT print git refs in output tree 1`] = `
-npm-broken-resolved-field-test@1.0.0 {CWD}/tap-testdir-ls-ls-broken-resolved-field
+npm-broken-resolved-field-test@1.0.0 {CWD}/prefix
\`-- a@1.0.1
`
exports[`test/lib/commands/ls.js TAP ls colored output > should output tree containing color info 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-colored-output
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0 extraneous
+-- foo@1.0.0 invalid: "^2.0.0" from the root project
| \`-- dog@1.0.0
@@ -337,7 +337,7 @@ exports[`test/lib/commands/ls.js TAP ls colored output > should output tree cont
`
exports[`test/lib/commands/ls.js TAP ls cycle deps > should print tree output containing deduped ref 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-cycle-deps
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- a@1.0.0
\`-- b@1.0.0
\`-- a@1.0.0 deduped
@@ -345,7 +345,7 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-cycle-deps
`
exports[`test/lib/commands/ls.js TAP ls cycle deps with filter args > should print tree output containing deduped ref 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-cycle-deps-with-filter-args
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- a@1.0.0
 \`-- b@1.0.0
 \`-- a@1.0.0 deduped
@@ -353,7 +353,7 @@ exports[`test/lib/commands/ls.js TAP ls cycle deps with filter args > should pri
`
exports[`test/lib/commands/ls.js TAP ls deduped missing dep > should output parseable signaling missing peer dep in problems 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-deduped-missing-dep
+test-npm-ls@1.0.0 {CWD}/prefix
+-- a@1.0.0
| \`-- UNMET DEPENDENCY b@^1.0.0
\`-- UNMET DEPENDENCY b@^1.0.0
@@ -361,40 +361,40 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-deduped-missing-dep
`
exports[`test/lib/commands/ls.js TAP ls default --depth value should be 0 > should output tree containing only top-level dependencies 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-default---depth-value-should-be-0
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
\`-- foo@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls empty location > should print empty result 1`] = `
-{CWD}/tap-testdir-ls-ls-empty-location
+{CWD}/prefix
\`-- (empty)
`
exports[`test/lib/commands/ls.js TAP ls extraneous deps > should output containing problems info 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-extraneous-deps
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0 extraneous
\`-- foo@1.0.0
\`-- dog@1.0.0
`
-exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option > should list a in top-level only 1`] = `
-test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option
+exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should list a in top-level only > output 1`] = `
+test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix
\`-- a@1.0.0
`
-exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option > should print empty results msg 1`] = `
-test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option
+exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should print empty results msg > output 1`] = `
+test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix
\`-- (empty)
`
-exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option > should print expected result 1`] = `
-test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-using-depth-option
+exports[`test/lib/commands/ls.js TAP ls filter pkg arg using depth option should print expected result > output 1`] = `
+test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/prefix
\`-- b@1.0.0
\`-- c@1.0.0
\`-- d@1.0.0
@@ -402,7 +402,7 @@ test-pkg-arg-filter-with-depth-opt@1.0.0 {CWD}/tap-testdir-ls-ls-filter-pkg-arg-
`
exports[`test/lib/commands/ls.js TAP ls filtering by child of missing dep > should print tree and not duplicate child of missing items 1`] = `
-filter-by-child-of-missing-dep@1.0.0 {CWD}/tap-testdir-ls-ls-filtering-by-child-of-missing-dep
+filter-by-child-of-missing-dep@1.0.0 {CWD}/prefix
+-- b@1.0.0 extraneous
| \`-- c@1.0.0 deduped
+-- c@1.0.0 extraneous
@@ -412,13 +412,13 @@ filter-by-child-of-missing-dep@1.0.0 {CWD}/tap-testdir-ls-ls-filtering-by-child-
`
exports[`test/lib/commands/ls.js TAP ls from and resolved properties > should not be printed in tree output 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-from-and-resolved-properties
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- simple-output@2.1.1
`
exports[`test/lib/commands/ls.js TAP ls global > should print tree and not mark top-level items extraneous 1`] = `
-{CWD}/tap-testdir-ls-ls-global
+{CWD}/global
+-- a@1.0.0
\`-- b@1.0.0
\`-- c@1.0.0
@@ -426,7 +426,7 @@ exports[`test/lib/commands/ls.js TAP ls global > should print tree and not mark
`
exports[`test/lib/commands/ls.js TAP ls invalid deduped dep > should output tree signaling mismatching peer dep in problems 1`] = `
-invalid-deduped-dep@1.0.0 {CWD}/tap-testdir-ls-ls-invalid-deduped-dep
+invalid-deduped-dep@1.0.0 {CWD}/prefix
+-- a@1.0.0
| \`-- b@1.0.0 deduped invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a
\`-- b@1.0.0 invalid: "^2.0.0" from the root project, "^2.0.0" from node_modules/a
@@ -434,7 +434,7 @@ exports[`test/lib/commands/ls.js TAP ls invalid deduped dep > should output tree
`
exports[`test/lib/commands/ls.js TAP ls invalid peer dep > should output tree signaling mismatching peer dep in problems 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-invalid-peer-dep
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
+-- dev-dep@1.0.0
| \`-- foo@1.0.0
@@ -447,28 +447,28 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-invalid-peer-dep
`
exports[`test/lib/commands/ls.js TAP ls json read problems > should print empty result 1`] = `
-{CWD}/tap-testdir-ls-ls-json-read-problems
+{CWD}/prefix
\`-- (empty)
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should filter by parent folder workspace config 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter by parent folder workspace config > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- e@1.0.0 -> ./group/e
\`-- f@1.0.0 -> ./group/f
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should filter single workspace 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter single workspace > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- a@1.0.0 -> ./a
| \`-- d@1.0.0 deduped -> ./d
\`-- d@1.0.0 -> ./d
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should filter using workspace config 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should filter using workspace config > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
\`-- a@1.0.0 -> ./a
+-- baz@1.0.0
+-- c@1.0.0
@@ -478,8 +478,8 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should inlude root and specified workspace 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should inlude root and specified workspace > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- d@1.0.0 -> ./d
| \`-- foo@1.1.1
| \`-- bar@1.0.0
@@ -487,8 +487,8 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should list --all workspaces properly 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list --all workspaces properly > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- a@1.0.0 -> ./a
| +-- baz@1.0.0
| +-- c@1.0.0
@@ -503,8 +503,8 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should list only prod deps of workspaces 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list only prod deps of workspaces > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- a@1.0.0 -> ./a
| +-- c@1.0.0
| \`-- d@1.0.0 deduped -> ./d
@@ -518,8 +518,8 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac
`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should list workspaces properly with default configs 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should list workspaces properly with default configs > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
+-- a@1.0.0 -> ./a
| +-- baz@1.0.0
| +-- c@1.0.0
@@ -533,14 +533,14 @@ exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > s

`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should not list workspaces with --no-workspaces 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should not list workspaces with --no-workspaces > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
\`-- pacote@1.0.0

`
-exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces > should print all tree and filter by dep within only the ws subtree 1`] = `
-workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspaces
+exports[`test/lib/commands/ls.js TAP ls loading a tree containing workspaces should print all tree and filter by dep within only the ws subtree > output 1`] = `
+workspaces-tree@1.0.0 {CWD}/prefix
\`-- d@1.0.0 -> ./d
\`-- foo@1.1.1
\`-- bar@1.0.0
@@ -548,7 +548,7 @@ workspaces-tree@1.0.0 {CWD}/tap-testdir-ls-ls-loading-a-tree-containing-workspac
`
exports[`test/lib/commands/ls.js TAP ls missing package.json > should output tree missing name/version of top-level package 1`] = `
-{CWD}/tap-testdir-ls-ls-missing-package.json
+{CWD}/prefix
+-- chai@1.0.0 extraneous
+-- dog@1.0.0 extraneous
\`-- foo@1.0.0 extraneous
@@ -557,7 +557,7 @@ exports[`test/lib/commands/ls.js TAP ls missing package.json > should output tre
`
exports[`test/lib/commands/ls.js TAP ls missing/invalid/extraneous > should output tree containing missing, invalid, extraneous labels 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-missing-invalid-extraneous
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0 extraneous
+-- foo@1.0.0 invalid: "^2.0.0" from the root project
| \`-- dog@1.0.0
@@ -566,7 +566,7 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-missing-invalid-extraneous
`
exports[`test/lib/commands/ls.js TAP ls no args > should output tree representation of dependencies structure 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-no-args
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
\`-- foo@1.0.0
\`-- dog@1.0.0
@@ -574,21 +574,21 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-no-args
`
exports[`test/lib/commands/ls.js TAP ls overridden dep > should contain overridden outout 1`] = `
-test-overridden@1.0.0 {CWD}/tap-testdir-ls-ls-overridden-dep
+test-overridden@1.0.0 {CWD}/prefix
\`-- foo@1.0.0
\`-- bar@1.0.0 overridden
`
exports[`test/lib/commands/ls.js TAP ls overridden dep w/ color > should contain overridden outout 1`] = `
-test-overridden@1.0.0 {CWD}/tap-testdir-ls-ls-overridden-dep-w-color
+test-overridden@1.0.0 {CWD}/prefix
\`-- foo@1.0.0
 \`-- bar@1.0.0 overridden

`
exports[`test/lib/commands/ls.js TAP ls print deduped symlinks > should output tree containing linked deps 1`] = `
-print-deduped-symlinks@1.0.0 {CWD}/tap-testdir-ls-ls-print-deduped-symlinks
+print-deduped-symlinks@1.0.0 {CWD}/prefix
+-- a@1.0.0
| \`-- b@1.0.0 deduped -> ./b
\`-- b@1.0.0 -> ./b
@@ -596,13 +596,13 @@ print-deduped-symlinks@1.0.0 {CWD}/tap-testdir-ls-ls-print-deduped-symlinks
`
exports[`test/lib/commands/ls.js TAP ls resolved points to git ref > should output tree containing git refs 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-resolved-points-to-git-ref
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- abbrev@1.1.1 (git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c)
`
exports[`test/lib/commands/ls.js TAP ls unmet optional dep > should output tree with empty entry for missing optional deps 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-unmet-optional-dep
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
+-- dev-dep@1.0.0
| \`-- foo@1.0.0
@@ -616,19 +616,19 @@ exports[`test/lib/commands/ls.js TAP ls unmet optional dep > should output tree
`
exports[`test/lib/commands/ls.js TAP ls unmet peer dep > should output tree signaling missing peer dep in problems 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-unmet-peer-dep
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- UNMET DEPENDENCY peer-dep@*
`
exports[`test/lib/commands/ls.js TAP ls using aliases > should output tree containing aliases 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-using-aliases
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- a@npm:b@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls with args and dedupe entries > should print tree output containing deduped ref 1`] = `
-dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-args-and-dedupe-entries
+dedupe-entries@1.0.0 {CWD}/prefix
+-- @npmcli/a@1.0.0
| \`-- @npmcli/b@1.1.2 deduped
+-- @npmcli/b@1.1.2
@@ -638,7 +638,7 @@ exports[`test/lib/commands/ls.js TAP ls with args and dedupe entries > should pr
`
exports[`test/lib/commands/ls.js TAP ls with args and different order of items > should print tree output containing deduped ref 1`] = `
-dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-args-and-different-order-of-items
+dedupe-entries@1.0.0 {CWD}/prefix
+-- @npmcli/a@1.0.0
| \`-- @npmcli/c@1.0.0 deduped
+-- @npmcli/b@1.1.2
@@ -648,32 +648,32 @@ dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-args-and-different-order-of-it
`
exports[`test/lib/commands/ls.js TAP ls with dot filter arg > should output tree contaning only occurrences of filtered by package and colored output 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-dot-filter-arg
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- (empty)
`
exports[`test/lib/commands/ls.js TAP ls with filter arg > should output tree contaning only occurrences of filtered by package and colored output 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-filter-arg
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- chai@1.0.0

`
exports[`test/lib/commands/ls.js TAP ls with filter arg nested dep > should output tree contaning only occurrences of filtered package and its ancestors 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-filter-arg-nested-dep
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- foo@1.0.0
\`-- dog@1.0.0
`
exports[`test/lib/commands/ls.js TAP ls with missing filter arg > should output tree containing no dependencies info 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-missing-filter-arg
+test-npm-ls@1.0.0 {CWD}/prefix
\`-- (empty)
`
exports[`test/lib/commands/ls.js TAP ls with multiple filter args > should output tree contaning only occurrences of multiple filtered packages and their ancestors 1`] = `
-test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-multiple-filter-args
+test-npm-ls@1.0.0 {CWD}/prefix
+-- chai@1.0.0
\`-- foo@1.0.0
\`-- dog@1.0.0
@@ -681,7 +681,7 @@ test-npm-ls@1.0.0 {CWD}/tap-testdir-ls-ls-with-multiple-filter-args
`
exports[`test/lib/commands/ls.js TAP ls with no args dedupe entries > should print tree output containing deduped ref 1`] = `
-dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries
+dedupe-entries@1.0.0 {CWD}/prefix
+-- @npmcli/a@1.0.0
| \`-- @npmcli/b@1.1.2 deduped
+-- @npmcli/b@1.1.2
@@ -691,7 +691,7 @@ dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries
`
exports[`test/lib/commands/ls.js TAP ls with no args dedupe entries and not displaying all > should print tree output containing deduped ref 1`] = `
-dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries-and-not-displaying-all
+dedupe-entries@1.0.0 {CWD}/prefix
+-- @npmcli/a@1.0.0
+-- @npmcli/b@1.1.2
\`-- @npmcli/c@1.0.0
@@ -699,14 +699,14 @@ dedupe-entries@1.0.0 {CWD}/tap-testdir-ls-ls-with-no-args-dedupe-entries-and-not
`
exports[`test/lib/commands/ls.js TAP ls workspace and missing optional dep > should omit missing optional dep 1`] = `
-root@ {CWD}/tap-testdir-ls-ls-workspace-and-missing-optional-dep
+root@ {CWD}/prefix
+-- baz@1.0.0 -> ./baz
\`-- foo@1.0.0
`
exports[`test/lib/commands/ls.js TAP show multiple invalid reasons > ls result 1`] = `
-test-npm-ls@1.0.0 {cwd}/tap-testdir-ls-show-multiple-invalid-reasons
+test-npm-ls@1.0.0 {CWD}/prefix
+-- cat@1.0.0 invalid: "^2.0.0" from the root project
| \`-- dog@1.0.0 deduped invalid: "^1.2.3" from the root project, "^2.0.0" from node_modules/cat
+-- chai@1.0.0 extraneous
diff --git a/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs
index ef6baa9666..a72338b0ba 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/outdated.js.test.cjs
@@ -6,237 +6,216 @@
*/
'use strict'
exports[`test/lib/commands/outdated.js TAP aliases > should display aliased outdated dep output 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat:dog@latest 1.0.0 2.0.0 2.0.0 node_modules/cat tap-testdir-outdated-aliases
+cat:dog@latest 1.0.0 2.0.0 2.0.0 node_modules/cat prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --all > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
-chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps
-theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
+chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
+theta MISSING 1.0.1 1.0.1 - prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --json --long > must match snapshot 1`] = `
-
{
"cat": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat",
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/cat",
"type": "dependencies"
},
"chai": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai",
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/chai",
"type": "peerDependencies"
},
"dog": {
"current": "1.0.1",
"wanted": "1.0.1",
"latest": "2.0.0",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog",
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/dog",
"type": "dependencies"
},
"theta": {
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
+ "dependent": "prefix",
"type": "dependencies"
}
}
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --json > must match snapshot 1`] = `
-
{
"cat": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat"
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/cat"
},
"chai": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai"
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/chai"
},
"dog": {
"current": "1.0.1",
"wanted": "1.0.1",
"latest": "2.0.0",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog"
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/dog"
},
"theta": {
"wanted": "1.0.1",
"latest": "1.0.1",
- "dependent": "tap-testdir-outdated-should-display-outdated-deps"
+ "dependent": "prefix"
}
}
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --long > must match snapshot 1`] = `
-
-Package Current Wanted Latest Location Depended by Package Type Homepage
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps dependencies
-chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps peerDependencies
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps dependencies
-theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps dependencies
+Package Current Wanted Latest Location Depended by Package Type Homepage
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix dependencies
+chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix peerDependencies
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix dependencies
+theta MISSING 1.0.1 1.0.1 - prefix dependencies
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=dev --omit=peer > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps
-theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
+theta MISSING 1.0.1 1.0.1 - prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=dev > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
-chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps
-theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
+chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
+theta MISSING 1.0.1 1.0.1 - prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --omit=prod > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
-chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
+chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --parseable --long > must match snapshot 1`] = `
-
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:tap-testdir-outdated-should-display-outdated-deps:dependencies:
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:tap-testdir-outdated-should-display-outdated-deps:peerDependencies:
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-should-display-outdated-deps:dependencies:
-:theta@1.0.1:MISSING:theta@1.0.1:tap-testdir-outdated-should-display-outdated-deps:dependencies:
+{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:prefix:dependencies:
+{CWD}/prefix/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:prefix:peerDependencies:
+{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix:dependencies:
+:theta@1.0.1:MISSING:theta@1.0.1:prefix:dependencies:
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated --parseable > must match snapshot 1`] = `
-
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:tap-testdir-outdated-should-display-outdated-deps
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:tap-testdir-outdated-should-display-outdated-deps
-{CWD}/test/lib/commands/tap-testdir-outdated-should-display-outdated-deps/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-should-display-outdated-deps
-:theta@1.0.1:MISSING:theta@1.0.1:tap-testdir-outdated-should-display-outdated-deps
+{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:prefix
+{CWD}/prefix/node_modules/chai:chai@1.0.1:chai@1.0.0:chai@1.0.1:prefix
+{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix
+:theta@1.0.1:MISSING:theta@1.0.1:prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
-chai 1.0.0 1.0.1 1.0.1 node_modules/chai tap-testdir-outdated-should-display-outdated-deps
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-should-display-outdated-deps
-theta MISSING 1.0.1 1.0.1 - tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
+chai 1.0.0 1.0.1 1.0.1 node_modules/chai prefix
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
+theta MISSING 1.0.1 1.0.1 - prefix
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated global > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat global
`
exports[`test/lib/commands/outdated.js TAP should display outdated deps outdated specific dep > must match snapshot 1`] = `
-
Package Current Wanted Latest Location Depended by
-cat 1.0.0 1.0.1 1.0.1 node_modules/cat tap-testdir-outdated-should-display-outdated-deps
+cat 1.0.0 1.0.1 1.0.1 node_modules/cat prefix
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display all dependencies 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display all dependencies > output 1`] = `
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0
chai 1.0.0 1.0.1 1.0.1 node_modules/chai foo
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-workspaces
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
theta MISSING 1.0.1 1.0.1 - c@1.0.0
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display json results filtered by ws 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display json results filtered by ws > output 1`] = `
{
"cat": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
"dependent": "a",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat"
+ "location": "{CWD}/prefix/node_modules/cat"
}
}
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display missing deps when filtering by ws 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display missing deps when filtering by ws > output 1`] = `
Package Current Wanted Latest Location Depended by
theta MISSING 1.0.1 1.0.1 - c@1.0.0
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display nested deps when filtering by ws and using --all 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display nested deps when filtering by ws and using --all > output 1`] = `
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0
chai 1.0.0 1.0.1 1.0.1 node_modules/chai foo
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display no results if ws has no deps to display 1`] = `
+exports[`test/lib/commands/outdated.js TAP workspaces should display no results if ws has no deps to display > output 1`] = `
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display only root outdated when ws disabled 1`] = `
+exports[`test/lib/commands/outdated.js TAP workspaces should display only root outdated when ws disabled > output 1`] = `
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display parseable results filtered by ws 1`] = `
-
-{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a
+exports[`test/lib/commands/outdated.js TAP workspaces should display parseable results filtered by ws > output 1`] = `
+{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display results filtered by ws 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display results filtered by ws > output 1`] = `
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps human output 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps human output > output 1`] = `
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-workspaces
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
theta MISSING 1.0.1 1.0.1 - c@1.0.0
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps json output 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps json output > output 1`] = `
{
"cat": {
"current": "1.0.0",
"wanted": "1.0.1",
"latest": "1.0.1",
"dependent": "a",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat"
+ "location": "{CWD}/prefix/node_modules/cat"
},
"dog": {
"current": "1.0.1",
"wanted": "1.0.1",
"latest": "2.0.0",
- "dependent": "tap-testdir-outdated-workspaces",
- "location": "{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/dog"
+ "dependent": "prefix",
+ "location": "{CWD}/prefix/node_modules/dog"
},
"theta": {
"wanted": "1.0.1",
@@ -246,17 +225,15 @@ exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdat
}
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should display ws outdated deps parseable output 1`] = `
-
-{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a
-{CWD}/test/lib/commands/tap-testdir-outdated-workspaces/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:tap-testdir-outdated-workspaces
+exports[`test/lib/commands/outdated.js TAP workspaces should display ws outdated deps parseable output > output 1`] = `
+{CWD}/prefix/node_modules/cat:cat@1.0.1:cat@1.0.0:cat@1.0.1:a
+{CWD}/prefix/node_modules/dog:dog@1.0.1:dog@1.0.1:dog@2.0.0:prefix
:theta@1.0.1:MISSING:theta@1.0.1:c
`
-exports[`test/lib/commands/outdated.js TAP workspaces > should highlight ws in dependend by section 1`] = `
-
+exports[`test/lib/commands/outdated.js TAP workspaces should highlight ws in dependend by section > output 1`] = `
Package Current Wanted Latest Location Depended by
cat 1.0.0 1.0.1 1.0.1 node_modules/cat a@1.0.0
-dog 1.0.1 1.0.1 2.0.0 node_modules/dog tap-testdir-outdated-workspaces
+dog 1.0.1 1.0.1 2.0.0 node_modules/dog prefix
theta MISSING 1.0.1 1.0.1 - c@1.0.0
`
diff --git a/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs
index 2103ccdd32..4959f7cdd2 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/profile.js.test.cjs
@@ -8,8 +8,7 @@
exports[`test/lib/commands/profile.js TAP enable-2fa from token and set otp, retries on pending and verifies with qrcode > should output 2fa enablement success msgs 1`] = `
Scan into your authenticator app:
qrcode
- Or enter code:
-1234
+ Or enter code: 1234
2FA successfully enabled. Below are your recovery codes, please print these out.
You will need these to recover access to your account if you lose your authentication device.
123456
diff --git a/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs
index 9ad6e2e380..a6dbfcf7c6 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/query.js.test.cjs
@@ -13,8 +13,8 @@ exports[`test/lib/commands/query.js TAP global > should return global package 1`
"_id": "lorem@2.0.0",
"pkgid": "lorem@2.0.0",
"location": "node_modules/lorem",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-global/global/node_modules/lorem",
+ "path": "{CWD}/global/node_modules/lorem",
+ "realpath": "{CWD}/global/node_modules/lorem",
"resolved": null,
"from": [
""
@@ -42,8 +42,8 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w
},
"pkgid": "project@",
"location": "",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix",
+ "path": "{CWD}/prefix",
+ "realpath": "{CWD}/prefix",
"resolved": null,
"from": [],
"to": [
@@ -63,8 +63,8 @@ exports[`test/lib/commands/query.js TAP include-workspace-root > should return w
"_id": "c@1.0.0",
"pkgid": "c@1.0.0",
"location": "c",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-include-workspace-root/prefix/c",
+ "path": "{CWD}/prefix/c",
+ "realpath": "{CWD}/prefix/c",
"resolved": null,
"from": [],
"to": [],
@@ -85,8 +85,8 @@ exports[`test/lib/commands/query.js TAP linked node > should return linked node
"_id": "a@1.0.0",
"pkgid": "a@1.0.0",
"location": "a",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-linked-node/prefix/a",
+ "path": "{CWD}/prefix/a",
+ "realpath": "{CWD}/prefix/a",
"resolved": null,
"from": [],
"to": [],
@@ -109,8 +109,8 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin
},
"pkgid": "project@",
"location": "",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix",
+ "path": "{CWD}/prefix",
+ "realpath": "{CWD}/prefix",
"resolved": null,
"from": [],
"to": [
@@ -126,8 +126,8 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin
{
"pkgid": "a@",
"location": "node_modules/a",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/a",
+ "path": "{CWD}/prefix/node_modules/a",
+ "realpath": "{CWD}/prefix/node_modules/a",
"resolved": null,
"from": [
""
@@ -142,8 +142,8 @@ exports[`test/lib/commands/query.js TAP recursive tree > should return everythin
{
"pkgid": "b@",
"location": "node_modules/b",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-recursive-tree/prefix/node_modules/b",
+ "path": "{CWD}/prefix/node_modules/b",
+ "realpath": "{CWD}/prefix/node_modules/b",
"resolved": null,
"from": [
""
@@ -171,8 +171,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
},
"pkgid": "project@",
"location": "",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix",
+ "path": "{CWD}/prefix",
+ "realpath": "{CWD}/prefix",
"resolved": null,
"from": [],
"to": [
@@ -188,8 +188,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
{
"pkgid": "a@",
"location": "node_modules/a",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/a",
+ "path": "{CWD}/prefix/node_modules/a",
+ "realpath": "{CWD}/prefix/node_modules/a",
"resolved": null,
"from": [
""
@@ -204,8 +204,8 @@ exports[`test/lib/commands/query.js TAP simple query > should return root object
{
"pkgid": "b@",
"location": "node_modules/b",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-simple-query/prefix/node_modules/b",
+ "path": "{CWD}/prefix/node_modules/b",
+ "realpath": "{CWD}/prefix/node_modules/b",
"resolved": null,
"from": [
""
@@ -228,8 +228,8 @@ exports[`test/lib/commands/query.js TAP workspace query > should return workspac
"_id": "c@1.0.0",
"pkgid": "c@1.0.0",
"location": "c",
- "path": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c",
- "realpath": "{CWD}/test/lib/commands/tap-testdir-query-workspace-query/prefix/c",
+ "path": "{CWD}/prefix/c",
+ "realpath": "{CWD}/prefix/c",
"resolved": null,
"from": [],
"to": [],
diff --git a/deps/npm/tap-snapshots/test/lib/commands/stars.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/stars.js.test.cjs
index fbf074f718..d55d7b414d 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/stars.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/stars.js.test.cjs
@@ -6,7 +6,6 @@
*/
'use strict'
exports[`test/lib/commands/stars.js TAP no args > should output a list of starred packages 1`] = `
-
@npmcli/arborist
@npmcli/map-workspaces
libnpmfund
diff --git a/deps/npm/tap-snapshots/test/lib/commands/team.js.test.cjs b/deps/npm/tap-snapshots/test/lib/commands/team.js.test.cjs
index 6a93234f54..f72fcb2f1f 100644
--- a/deps/npm/tap-snapshots/test/lib/commands/team.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/commands/team.js.test.cjs
@@ -37,18 +37,18 @@ ruyadorno
`
exports[`test/lib/commands/team.js TAP team ls <scope:team> default output > should list users for a given scope:team 1`] = `
-
@npmcli:developers has 4 users:
-darcyclarke isaacs nlf ruyadorno
+darcyclarke
+isaacs
+nlf
+ruyadorno
`
exports[`test/lib/commands/team.js TAP team ls <scope:team> no users > should list no users for a given scope 1`] = `
-
@npmcli:developers has 0 users
`
exports[`test/lib/commands/team.js TAP team ls <scope:team> single user > should list single user for a given scope 1`] = `
-
@npmcli:developers has 1 user:
foo
`
@@ -60,18 +60,17 @@ npmcli:product
`
exports[`test/lib/commands/team.js TAP team ls <scope> default output > should list teams for a given scope 1`] = `
-
@npmcli has 3 teams:
-@npmcli:designers @npmcli:developers @npmcli:product
+@npmcli:designers
+@npmcli:developers
+@npmcli:product
`
exports[`test/lib/commands/team.js TAP team ls <scope> no teams > should list no teams for a given scope 1`] = `
-
@npmcli has 0 teams
`
exports[`test/lib/commands/team.js TAP team ls <scope> single team > should list single team for a given scope 1`] = `
-
@npmcli has 1 team:
@npmcli:developers
`
diff --git a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
index c18dd305b0..578bbd7981 100644
--- a/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/docs.js.test.cjs
@@ -604,8 +604,8 @@ safer to use a registry-provided authentication bearer token stored in the
current level
* Type: null, "restricted", or "public"
-If do not want your scoped package to be publicly viewable (and installable)
-set \`--access=restricted\`.
+If you do not want your scoped package to be publicly viewable (and
+installable) set \`--access=restricted\`.
Unscoped packages can not be set to \`restricted\`.
@@ -654,7 +654,8 @@ exit code.
* Default: "web"
* Type: "legacy" or "web"
-What authentication strategy to use with \`login\`.
+What authentication strategy to use with \`login\`. Note that if an \`otp\`
+config is given, this value will always be set to \`legacy\`.
#### \`before\`
@@ -1702,7 +1703,7 @@ be resolved using the nearest non-peer dependency specification, even if
doing so will result in some packages receiving a peer dependency outside
the range set in their package's \`peerDependencies\` object.
-When such and override is performed, a warning is printed, explaining the
+When such an override is performed, a warning is printed, explaining the
conflict and the packages involved. If \`--strict-peer-deps\` is set, then
this warning is treated as a failure.
@@ -1983,7 +1984,7 @@ Alias for \`--include=dev\`.
\`--install-strategy=shallow\`
Only install direct dependencies in the top level \`node_modules\`, but hoist
-on deeper dependendencies. Sets \`--install-strategy=shallow\`.
+on deeper dependencies. Sets \`--install-strategy=shallow\`.
#### \`init.author.email\`
@@ -2380,6 +2381,7 @@ Array [
"tag",
"tag-version-prefix",
"umask",
+ "unicode",
"user-agent",
"workspace",
"workspaces",
@@ -2409,7 +2411,6 @@ Array [
"prefix",
"timing",
"tmp",
- "unicode",
"update-notifier",
"usage",
"userconfig",
@@ -2491,6 +2492,8 @@ npm access grant <read-only|read-write> <scope:team> [<package>]
npm access revoke <scope:team> [<package>]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`json\`
#### \`otp\`
#### \`registry\`
@@ -2515,6 +2518,8 @@ npm adduser
alias: add-user
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`scope\`
#### \`auth-type\`
@@ -2603,6 +2608,8 @@ npm cache ls [<name>@<version>]
npm cache verify
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`cache\`
`
@@ -2665,6 +2672,8 @@ Run "npm help completion" for more info
npm completion
\`\`\`
+Note: This command is unaware of workspaces.
+
NO PARAMS
`
@@ -2698,6 +2707,8 @@ npm config fix
alias: c
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`json\`
#### \`global\`
#### \`editor\`
@@ -2761,6 +2772,8 @@ Run "npm help deprecate" for more info
npm deprecate <package-spec> <message>
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`otp\`
`
@@ -2872,6 +2885,8 @@ Run "npm help doctor" for more info
npm doctor [ping] [registry] [versions] [environment] [permissions] [cache]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
`
@@ -2890,6 +2905,8 @@ Run "npm help edit" for more info
npm edit <pkg>[/<subpkg>...]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`editor\`
`
@@ -2965,6 +2982,8 @@ Run "npm help explore" for more info
npm explore <pkg> [ -- <command>]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`shell\`
`
@@ -3040,6 +3059,8 @@ Run "npm help get" for more info
npm get [<key> ...] (See \`npm config\`)
\`\`\`
+Note: This command is unaware of workspaces.
+
NO PARAMS
`
@@ -3062,6 +3083,8 @@ npm help <term> [<terms..>]
alias: hlep
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`viewer\`
`
@@ -3080,6 +3103,8 @@ Run "npm help help-search" for more info
npm help-search <text>
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`long\`
`
@@ -3104,6 +3129,8 @@ npm hook rm <id>
npm hook update <id> <url> <secret>
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`otp\`
`
@@ -3112,7 +3139,7 @@ exports[`test/lib/docs.js TAP usage init > must match snapshot 1`] = `
Create a package.json file
Usage:
-npm init <package-spec> (same as \`npx <package-spec>)
+npm init <package-spec> (same as \`npx <package-spec>\`)
npm init <@scope> (same as \`npx <@scope>/create\`)
Options:
@@ -3125,7 +3152,7 @@ aliases: create, innit
Run "npm help init" for more info
\`\`\`bash
-npm init <package-spec> (same as \`npx <package-spec>)
+npm init <package-spec> (same as \`npx <package-spec>\`)
npm init <@scope> (same as \`npx <@scope>/create\`)
aliases: create, innit
@@ -3380,6 +3407,8 @@ Run "npm help login" for more info
npm login
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`scope\`
#### \`auth-type\`
@@ -3400,6 +3429,8 @@ Run "npm help logout" for more info
npm logout
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`scope\`
`
@@ -3448,6 +3479,8 @@ exports[`test/lib/docs.js TAP usage npm > must match snapshot 1`] = `
npm
\`\`\`
+Note: This command is unaware of workspaces.
+
NO PARAMS
`
@@ -3485,6 +3518,8 @@ npm org ls orgname [<username>]
alias: ogr
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`otp\`
#### \`json\`
@@ -3586,6 +3621,8 @@ Run "npm help ping" for more info
npm ping
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
`
@@ -3635,6 +3672,8 @@ Run "npm help prefix" for more info
npm prefix [-g]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`global\`
`
@@ -3659,6 +3698,8 @@ npm profile get [<key>]
npm profile set <key> <value>
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`json\`
#### \`parseable\`
@@ -3832,6 +3873,8 @@ Run "npm help root" for more info
npm root
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`global\`
`
@@ -3886,6 +3929,8 @@ npm search [search terms ...]
aliases: find, s, se
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`long\`
#### \`json\`
#### \`color\`
@@ -3911,6 +3956,8 @@ Run "npm help set" for more info
npm set <key>=<value> [<key>=<value> ...] (See \`npm config\`)
\`\`\`
+Note: This command is unaware of workspaces.
+
NO PARAMS
`
@@ -3926,6 +3973,8 @@ Run "npm help shrinkwrap" for more info
npm shrinkwrap
\`\`\`
+Note: This command is unaware of workspaces.
+
NO PARAMS
`
@@ -3944,6 +3993,8 @@ Run "npm help star" for more info
npm star [<package-spec>...]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`unicode\`
#### \`otp\`
@@ -3964,6 +4015,8 @@ Run "npm help stars" for more info
npm stars [<user>]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
`
@@ -4028,6 +4081,8 @@ npm team rm <scope:team> <user> [--otp <otpcode>]
npm team ls <scope>|<scope:team>
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`otp\`
#### \`parseable\`
@@ -4077,6 +4132,8 @@ npm token revoke <id|token>
npm token create [--read-only] [--cidr=list]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`read-only\`
#### \`cidr\`
#### \`registry\`
@@ -4149,6 +4206,8 @@ Run "npm help unstar" for more info
npm unstar [<package-spec>...]
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
#### \`unicode\`
#### \`otp\`
@@ -4274,5 +4333,7 @@ Run "npm help whoami" for more info
npm whoami
\`\`\`
+Note: This command is unaware of workspaces.
+
#### \`registry\`
`
diff --git a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
index 7b689ff972..5fe20969fc 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs
@@ -390,7 +390,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-false-cacheDest-true-/cache/dest",
+ "dest": "{CWD}/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -424,7 +424,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-false-/cache/path",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -456,8 +456,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-true-/cache/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-false-cachePath-true-cacheDest-true-/cache/path",
+ "dest": "{CWD}/cache/dest",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -505,15 +505,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -530,7 +530,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-true-/cache"
+ sudo chown -R 867:5309 "{CWD}/cache"
),
],
],
@@ -545,18 +545,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
- ],
- Array [
- "dummy stack trace",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -573,7 +570,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-false-/cache"
+ sudo chown -R 867:5309 "{CWD}/cache"
),
],
],
@@ -588,18 +585,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
- ],
- Array [
- "dummy stack trace",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -616,7 +610,7 @@ Object {
previous versions of npm which has since been addressed.
To permanently fix this problem, please run:
- sudo chown -R 867:5309 "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-true-/cache"
+ sudo chown -R 867:5309 "{CWD}/cache"
),
],
],
@@ -631,18 +625,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-false-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
- ],
- Array [
- "dummy stack trace",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -703,7 +694,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-false-cacheDest-true-/cache/dest",
+ "dest": "{CWD}/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -738,7 +729,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-false-/cache/path",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -771,8 +762,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-true-/cache/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-false-cachePath-true-cacheDest-true-/cache/path",
+ "dest": "{CWD}/cache/dest",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -821,15 +812,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -856,7 +847,7 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-true-/cache/dest",
+ "dest": "{CWD}/cache/dest",
"path": "/not/cache/dir/path",
},
],
@@ -872,15 +863,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-false-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -908,7 +899,7 @@ Object {
Error: whoopsie {
"code": "EACCES",
"dest": "/not/cache/dir/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-false-/cache/path",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -923,15 +914,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-false-/cache/_logs/{DATE}-debug-0.log",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -958,8 +949,8 @@ Object {
"",
Error: whoopsie {
"code": "EACCES",
- "dest": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/dest",
- "path": "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/path",
+ "dest": "{CWD}/cache/dest",
+ "path": "{CWD}/cache/path",
},
],
],
@@ -974,15 +965,15 @@ Array [
],
Array [
"argv",
- "",
+ "/"--fetch-retries/" /"0/" /"--cache/" /"{CWD}/cache/"",
],
Array [
"logfile",
- "logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-",
+ "logs-max:10 dir:{CWD}/cache/_logs/{DATE}-",
],
Array [
"logfile",
- "{CWD}/test/lib/utils/tap-testdir-error-message-eacces-eperm--windows-true-loaded-true-cachePath-true-cacheDest-true-/cache/_logs/{DATE}-debug-0.log",
+ "{CWD}/cache/_logs/{DATE}-debug-0.log",
],
]
`
@@ -1280,7 +1271,7 @@ Object {
String(
Not compatible with your version of node/npm: some@package
Required: undefined
- Actual: {"npm":"123.456.789-npm","node":"99.99.99"}
+ Actual: {"npm":"123.456.789-npm","node":"123.456.789-node"}
),
],
],
diff --git a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
index eed705be38..4c163e7df5 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/exit-handler.js.test.cjs
@@ -12,18 +12,18 @@ exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and
15 timing npm:load:mkdirpcache Completed in {TIME}ms
16 timing npm:load:mkdirplogs Completed in {TIME}ms
17 verbose title npm
-18 verbose argv
+18 verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "notice"
19 timing npm:load:setTitle Completed in {TIME}ms
21 timing npm:load:display Completed in {TIME}ms
-22 verbose logfile logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-
-23 verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+22 verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-
+23 verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log
24 timing npm:load:logFile Completed in {TIME}ms
25 timing npm:load:timers Completed in {TIME}ms
26 timing npm:load:configScope Completed in {TIME}ms
27 timing npm:load Completed in {TIME}ms
28 silly logfile done cleaning log files
29 verbose stack Error: Unknown error
-30 verbose cwd {CWD}
+30 verbose cwd {CWD}/prefix
31 verbose Foo 1.0.0
32 verbose node v1.0.0
33 verbose npm v1.0.0
@@ -31,10 +31,10 @@ exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and
35 error ERR SUMMARY Unknown error
36 error ERR DETAIL Unknown error
37 verbose exit 1
-39 timing npm Completed in {TIME}ms
-40 verbose code 1
-41 error A complete log of this run can be found in:
-41 error {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+38 timing npm Completed in {TIME}ms
+39 verbose code 1
+40 error A complete log of this run can be found in:
+40 error {CWD}/cache/_logs/{DATE}-debug-0.log
`
exports[`test/lib/utils/exit-handler.js TAP handles unknown error with logs and debug file > logs 1`] = `
@@ -44,18 +44,18 @@ timing npm:load:configload Completed in {TIME}ms
timing npm:load:mkdirpcache Completed in {TIME}ms
timing npm:load:mkdirplogs Completed in {TIME}ms
verbose title npm
-verbose argv
+verbose argv "--fetch-retries" "0" "--cache" "{CWD}/cache" "--loglevel" "notice"
timing npm:load:setTitle Completed in {TIME}ms
timing npm:load:display Completed in {TIME}ms
-verbose logfile logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-
-verbose logfile {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+verbose logfile logs-max:10 dir:{CWD}/cache/_logs/{DATE}-
+verbose logfile {CWD}/cache/_logs/{DATE}-debug-0.log
timing npm:load:logFile Completed in {TIME}ms
timing npm:load:timers Completed in {TIME}ms
timing npm:load:configScope Completed in {TIME}ms
timing npm:load Completed in {TIME}ms
silly logfile done cleaning log files
verbose stack Error: Unknown error
-verbose cwd {CWD}
+verbose cwd {CWD}/prefix
verbose Foo 1.0.0
verbose node v1.0.0
verbose npm v1.0.0
@@ -66,5 +66,5 @@ verbose exit 1
timing npm Completed in {TIME}ms
verbose code 1
error A complete log of this run can be found in:
- {CWD}/test/lib/utils/tap-testdir-exit-handler-handles-unknown-error-with-logs-and-debug-file/cache/_logs/{DATE}-debug-0.log
+ {CWD}/cache/_logs/{DATE}-debug-0.log
`
diff --git a/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs
index 912a4365f6..0a4af7cadf 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/log-file.js.test.cjs
@@ -6,7 +6,7 @@
*/
'use strict'
exports[`test/lib/utils/log-file.js TAP snapshot > must match snapshot 1`] = `
-0 verbose logfile logs-max:10 dir:{CWD}/test/lib/utils/tap-testdir-log-file-snapshot/{DATE}-
+0 verbose logfile logs-max:10 dir:{CWD}/{DATE}-
1 silly logfile done cleaning log files
2 error no prefix
3 error prefix with prefix
diff --git a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs
index 755b236425..3fb3fa2611 100644
--- a/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs
+++ b/deps/npm/tap-snapshots/test/lib/utils/reify-output.js.test.cjs
@@ -15,12 +15,12 @@ exports[`test/lib/utils/reify-output.js TAP added packages should be looked up w
up to date in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
up to date in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -30,14 +30,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
up to date, audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -52,21 +52,21 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
up to date, audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":false} 2`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":false} 2`] = `
up to date, audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -81,7 +81,7 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":true} 2`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":0,"audited":2,"json":true} 2`] = `
{
"added": 0,
"removed": 0,
@@ -99,12 +99,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -114,14 +114,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -136,14 +136,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -158,12 +158,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -173,14 +173,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -195,14 +195,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 0,
@@ -217,12 +217,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
removed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -232,14 +232,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
removed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -254,14 +254,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
removed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -276,12 +276,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
removed 1 package, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -291,14 +291,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
removed 1 package, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -313,14 +313,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
removed 1 package, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -335,12 +335,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
removed 1 package, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -350,14 +350,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
removed 1 package, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -372,14 +372,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
removed 1 package, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 1,
@@ -394,12 +394,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
removed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -409,14 +409,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
removed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -431,14 +431,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
removed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -453,12 +453,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
removed 2 packages, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -468,14 +468,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
removed 2 packages, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -490,14 +490,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
removed 2 packages, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -512,12 +512,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
removed 2 packages, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -527,14 +527,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
removed 2 packages, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -549,14 +549,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
removed 2 packages, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":0,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 0,
"removed": 2,
@@ -571,12 +571,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
added 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -586,14 +586,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
added 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -608,14 +608,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
added 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -630,12 +630,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
added 1 package, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -645,14 +645,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
added 1 package, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -667,14 +667,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
added 1 package, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -689,12 +689,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
added 1 package, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -704,14 +704,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
added 1 package, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -726,14 +726,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
added 1 package, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 0,
@@ -748,12 +748,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
added 1 package, and removed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -763,14 +763,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
added 1 package, removed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -785,14 +785,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
added 1 package, removed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -807,12 +807,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
added 1 package, removed 1 package, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -822,14 +822,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
added 1 package, removed 1 package, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -844,14 +844,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
added 1 package, removed 1 package, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -866,12 +866,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
added 1 package, removed 1 package, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -881,14 +881,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
added 1 package, removed 1 package, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -903,14 +903,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
added 1 package, removed 1 package, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 1,
@@ -925,12 +925,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
added 1 package, and removed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -940,14 +940,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
added 1 package, removed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -962,14 +962,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
added 1 package, removed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -984,12 +984,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
added 1 package, removed 2 packages, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -999,14 +999,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
added 1 package, removed 2 packages, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -1021,14 +1021,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
added 1 package, removed 2 packages, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -1043,12 +1043,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
added 1 package, removed 2 packages, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -1058,14 +1058,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
added 1 package, removed 2 packages, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -1080,14 +1080,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
added 1 package, removed 2 packages, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":1,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 1,
"removed": 2,
@@ -1102,12 +1102,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":0,"json":false} 1`] = `
added 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1117,14 +1117,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":1,"json":false} 1`] = `
added 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1139,14 +1139,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":2,"json":false} 1`] = `
added 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1161,12 +1161,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":0,"json":false} 1`] = `
added 2 packages, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1176,14 +1176,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":1,"json":false} 1`] = `
added 2 packages, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1198,14 +1198,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":2,"json":false} 1`] = `
added 2 packages, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1220,12 +1220,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":0,"json":false} 1`] = `
added 2 packages, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1235,14 +1235,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":1,"json":false} 1`] = `
added 2 packages, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1257,14 +1257,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":2,"json":false} 1`] = `
added 2 packages, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":0,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 0,
@@ -1279,12 +1279,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":0,"json":false} 1`] = `
added 2 packages, and removed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1294,14 +1294,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":1,"json":false} 1`] = `
added 2 packages, removed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1316,14 +1316,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":2,"json":false} 1`] = `
added 2 packages, removed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1338,12 +1338,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":0,"json":false} 1`] = `
added 2 packages, removed 1 package, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1353,14 +1353,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":1,"json":false} 1`] = `
added 2 packages, removed 1 package, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1375,14 +1375,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":2,"json":false} 1`] = `
added 2 packages, removed 1 package, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1397,12 +1397,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":0,"json":false} 1`] = `
added 2 packages, removed 1 package, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1412,14 +1412,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":1,"json":false} 1`] = `
added 2 packages, removed 1 package, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1434,14 +1434,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":2,"json":false} 1`] = `
added 2 packages, removed 1 package, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":1,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 1,
@@ -1456,12 +1456,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":0,"json":false} 1`] = `
added 2 packages, and removed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1471,14 +1471,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":1,"json":false} 1`] = `
added 2 packages, removed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1493,14 +1493,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":2,"json":false} 1`] = `
added 2 packages, removed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":0,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1515,12 +1515,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":0,"json":false} 1`] = `
added 2 packages, removed 2 packages, and changed 1 package in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1530,14 +1530,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":1,"json":false} 1`] = `
added 2 packages, removed 2 packages, changed 1 package, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1552,14 +1552,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":2,"json":false} 1`] = `
added 2 packages, removed 2 packages, changed 1 package, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":1,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1574,12 +1574,12 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":0,"json":false} 1`] = `
added 2 packages, removed 2 packages, and changed 2 packages in {TIME}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":0,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1589,14 +1589,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":1,"json":false} 1`] = `
added 2 packages, removed 2 packages, changed 2 packages, and audited 1 package in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":1,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
@@ -1611,14 +1611,14 @@ exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":
}
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":2,"json":false} 1`] = `
added 2 packages, removed 2 packages, changed 2 packages, and audited 2 packages in {TIME}
-found 0 vulnerabilities
+found 0 vulnerabilities
`
-exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
+exports[`test/lib/utils/reify-output.js TAP packages changed message > {"added":2,"removed":2,"changed":2,"audited":2,"json":true} 1`] = `
{
"added": 2,
"removed": 2,
diff --git a/deps/npm/test/bin/npm-cli.js b/deps/npm/test/bin/npm-cli.js
index 7b4b619e2b..134208c816 100644
--- a/deps/npm/test/bin/npm-cli.js
+++ b/deps/npm/test/bin/npm-cli.js
@@ -1,7 +1,9 @@
const t = require('tap')
+const tmock = require('../fixtures/tmock')
+
t.test('loading the bin calls the implementation', t => {
- t.mock('../../bin/npm-cli.js', {
- '../../lib/cli.js': proc => {
+ tmock(t, '{BIN}/npm-cli.js', {
+ '{LIB}/cli.js': proc => {
t.equal(proc, process, 'called implementation with process object')
t.end()
},
diff --git a/deps/npm/test/bin/npx-cli.js b/deps/npm/test/bin/npx-cli.js
index b526f2dfbe..5670f24f07 100644
--- a/deps/npm/test/bin/npx-cli.js
+++ b/deps/npm/test/bin/npx-cli.js
@@ -1,45 +1,46 @@
const t = require('tap')
-const npx = require.resolve('../../bin/npx-cli.js')
-const cli = require.resolve('../../lib/cli.js')
-const npm = require.resolve('../../bin/npm-cli.js')
+const mockGlobals = require('../fixtures/mock-globals')
+const tmock = require('../fixtures/tmock')
-const logs = []
-console.error = (...msg) => logs.push(msg)
+const npm = require.resolve('../../bin/npm-cli.js')
+const npx = require.resolve('../../bin/npx-cli.js')
-t.afterEach(() => (logs.length = 0))
+const mockNpx = (t, argv) => {
+ const logs = []
+ mockGlobals(t, {
+ 'process.argv': argv,
+ 'console.error': (...msg) => logs.push(msg),
+ })
+ tmock(t, '{BIN}/npx-cli.js', { '{LIB}/cli.js': () => {} })
+ return {
+ logs,
+ argv: process.argv,
+ }
+}
-t.test('npx foo -> npm exec -- foo', t => {
- process.argv = ['node', npx, 'foo']
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, ['node', npm, 'exec', '--', 'foo'])
- t.end()
+t.test('npx foo -> npm exec -- foo', async t => {
+ const { argv } = mockNpx(t, ['node', npx, 'foo'])
+ t.strictSame(argv, ['node', npm, 'exec', '--', 'foo'])
})
-t.test('npx -- foo -> npm exec -- foo', t => {
- process.argv = ['node', npx, '--', 'foo']
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, ['node', npm, 'exec', '--', 'foo'])
- t.end()
+t.test('npx -- foo -> npm exec -- foo', async t => {
+ const { argv } = mockNpx(t, ['node', npx, '--', 'foo'])
+ t.strictSame(argv, ['node', npm, 'exec', '--', 'foo'])
})
-t.test('npx -x y foo -z -> npm exec -x y -- foo -z', t => {
- process.argv = ['node', npx, '-x', 'y', 'foo', '-z']
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, ['node', npm, 'exec', '-x', 'y', '--', 'foo', '-z'])
- t.end()
+t.test('npx -x y foo -z -> npm exec -x y -- foo -z', async t => {
+ const { argv } = mockNpx(t, ['node', npx, '-x', 'y', 'foo', '-z'])
+ t.strictSame(argv, ['node', npm, 'exec', '-x', 'y', '--', 'foo', '-z'])
})
-t.test('npx --x=y --no-install foo -z -> npm exec --x=y -- foo -z', t => {
- process.argv = ['node', npx, '--x=y', '--no-install', 'foo', '-z']
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, ['node', npm, 'exec', '--x=y', '--yes=false', '--', 'foo', '-z'])
- t.end()
+t.test('npx --x=y --no-install foo -z -> npm exec --x=y -- foo -z', async t => {
+ const { argv } = mockNpx(t, ['node', npx, '--x=y', '--no-install', 'foo', '-z'])
+ t.strictSame(argv, ['node', npm, 'exec', '--x=y', '--yes=false', '--', 'foo', '-z'])
})
-t.test('transform renamed options into proper values', t => {
- process.argv = ['node', npx, '-y', '--shell=bash', '-p', 'foo', '-c', 'asdf']
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, [
+t.test('transform renamed options into proper values', async t => {
+ const { argv } = mockNpx(t, ['node', npx, '-y', '--shell=bash', '-p', 'foo', '-c', 'asdf'])
+ t.strictSame(argv, [
'node',
npm,
'exec',
@@ -50,12 +51,11 @@ t.test('transform renamed options into proper values', t => {
'--call',
'asdf',
])
- t.end()
})
// warn if deprecated switches/options are used
-t.test('use a bunch of deprecated switches and options', t => {
- process.argv = [
+t.test('use a bunch of deprecated switches and options', async t => {
+ const { argv, logs } = mockNpx(t, [
'node',
npx,
'--npm',
@@ -71,7 +71,7 @@ t.test('use a bunch of deprecated switches and options', t => {
'--ignore-existing',
'-q',
'foobar',
- ]
+ ])
const expect = [
'node',
@@ -86,8 +86,7 @@ t.test('use a bunch of deprecated switches and options', t => {
'--',
'foobar',
]
- t.mock(npx, { [cli]: () => {} })
- t.strictSame(process.argv, expect)
+ t.strictSame(argv, expect)
t.strictSame(logs, [
['npx: the --npm argument has been removed.'],
['npx: the --node-arg argument has been removed.'],
@@ -97,5 +96,4 @@ t.test('use a bunch of deprecated switches and options', t => {
['npx: the --ignore-existing argument has been removed.'],
['See `npm help exec` for more information'],
])
- t.end()
})
diff --git a/deps/npm/test/fixtures/clean-snapshot.js b/deps/npm/test/fixtures/clean-snapshot.js
index b0ea28cee4..83ddc00f4b 100644
--- a/deps/npm/test/fixtures/clean-snapshot.js
+++ b/deps/npm/test/fixtures/clean-snapshot.js
@@ -1,19 +1,43 @@
+const { relative, dirname } = require('path')
+
+// normalize line endings (for ini)
+const cleanNewlines = (s) => s.replace(/\r\n/g, '\n')
+
// XXX: this also cleans quoted " in json snapshots
// ideally this could be avoided but its easier to just
// run this command inside cleanSnapshot
-const normalizePath = (str) => str
- .replace(/\r\n/g, '\n') // normalize line endings (for ini)
+const normalizePath = (str) => cleanNewlines(str)
.replace(/[A-z]:\\/g, '\\') // turn windows roots to posix ones
.replace(/\\+/g, '/') // replace \ with /
+const pathRegex = (p) => new RegExp(normalizePath(p), 'gi')
+
+// create a cwd replacer in the module scope, since some tests
+// overwrite process.cwd()
+const CWD = pathRegex(process.cwd())
+const TESTDIR = pathRegex(relative(process.cwd(), dirname(require.main.filename)))
+
const cleanCwd = (path) => normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
+ // repalce CWD, TESTDIR, and TAPDIR separately
+ .replace(CWD, '{CWD}')
+ .replace(TESTDIR, '{TESTDIR}')
+ .replace(/tap-testdir-[\w-.]+/gi, '{TAPDIR}')
+ // if everything ended up in line, reduce it all to CWD
+ .replace(/\{CWD\}\/\{TESTDIR\}\/\{TAPDIR\}/g, '{CWD}')
+ // replace for platform differences in global nodemodules
+ .replace(/lib\/node_modules/g, 'node_modules')
+ .replace(/global\/lib/g, 'global')
const cleanDate = (str) =>
str.replace(/\d{4}-\d{2}-\d{2}T\d{2}[_:]\d{2}[_:]\d{2}[_:.]\d{3}Z/g, '{DATE}')
+const cleanTime = str => str.replace(/in [0-9]+m?s\s*$/gm, 'in {TIME}')
+
module.exports = {
normalizePath,
+ pathRegex,
cleanCwd,
cleanDate,
+ cleanTime,
+ cleanNewlines,
}
diff --git a/deps/npm/test/fixtures/merge-conflict.json b/deps/npm/test/fixtures/merge-conflict.json
new file mode 100644
index 0000000000..2591c62efb
--- /dev/null
+++ b/deps/npm/test/fixtures/merge-conflict.json
@@ -0,0 +1,36 @@
+{
+ "array": [
+<<<<<<< HEAD
+ 100,
+ {
+ "foo": "baz"
+ },
+||||||| merged common ancestors
+ 1,
+=======
+ 111,
+ 1,
+ 2,
+ 3,
+ {
+ "foo": "bar"
+ },
+>>>>>>> a
+ 1
+ ],
+ "a": {
+ "b": {
+<<<<<<< HEAD
+ "c": {
+ "x": "bbbb"
+ }
+||||||| merged common ancestors
+ "c": {
+ "x": "aaaa"
+ }
+=======
+ "c": "xxxx"
+>>>>>>> a
+ }
+ }
+}
diff --git a/deps/npm/test/fixtures/mock-globals.js b/deps/npm/test/fixtures/mock-globals.js
index 29da2a48b0..aec8a83963 100644
--- a/deps/npm/test/fixtures/mock-globals.js
+++ b/deps/npm/test/fixtures/mock-globals.js
@@ -4,23 +4,49 @@
// Hopefully it can be removed for a feature in tap in the future
const sep = '.'
+const escapeSep = '"'
const has = (o, k) => Object.prototype.hasOwnProperty.call(o, k)
const opd = (o, k) => Object.getOwnPropertyDescriptor(o, k)
const po = (o) => Object.getPrototypeOf(o)
const pojo = (o) => Object.prototype.toString.call(o) === '[object Object]'
const last = (arr) => arr[arr.length - 1]
-const splitLast = (str) => str.split(new RegExp(`\\${sep}(?=[^${sep}]+$)`))
const dupes = (arr) => arr.filter((k, i) => arr.indexOf(k) !== i)
const dupesStartsWith = (arr) => arr.filter((k1) => arr.some((k2) => k2.startsWith(k1 + sep)))
+const splitLastSep = (str) => {
+ let escaped = false
+ for (let i = str.length - 1; i >= 0; i--) {
+ const c = str[i]
+ const cp = str[i + 1]
+ const cn = str[i - 1]
+ if (!escaped && c === escapeSep && (cp == null || cp === sep)) {
+ escaped = true
+ continue
+ }
+ if (escaped && c === escapeSep && cn === sep) {
+ escaped = false
+ continue
+ }
+ if (!escaped && c === sep) {
+ return [
+ str.slice(0, i),
+ str.slice(i + 1).replace(new RegExp(`^${escapeSep}(.*)${escapeSep}$`), '$1'),
+ ]
+ }
+ }
+ return [str]
+}
+
// A weird getter that can look up keys on nested objects but also
// match keys with dots in their names, eg { 'process.env': { TERM: 'a' } }
// can be looked up with the key 'process.env.TERM'
const get = (obj, key, childKey = '') => {
if (has(obj, key)) {
return childKey ? get(obj[key], childKey) : obj[key]
- } else if (key.includes(sep)) {
- const [parentKey, prefix] = splitLast(key)
+ }
+ const split = splitLastSep(key)
+ if (split.length === 2) {
+ const [parentKey, prefix] = split
return get(
obj,
parentKey,
@@ -81,7 +107,7 @@ class DescriptorStack {
#isDelete = (o) => o && o.DELETE === true
constructor (key) {
- const keys = splitLast(key)
+ const keys = splitLastSep(key)
this.#global = keys.length === 1 ? global : get(global, keys[0])
this.#valueKey = specialCaseKeys(key) || last(keys)
// If the global object doesnt return a descriptor for the key
diff --git a/deps/npm/test/fixtures/mock-npm.js b/deps/npm/test/fixtures/mock-npm.js
index 8a744cd559..2cada13548 100644
--- a/deps/npm/test/fixtures/mock-npm.js
+++ b/deps/npm/test/fixtures/mock-npm.js
@@ -1,26 +1,81 @@
const os = require('os')
const fs = require('fs').promises
const path = require('path')
+const tap = require('tap')
+const errorMessage = require('../../lib/utils/error-message')
const mockLogs = require('./mock-logs')
const mockGlobals = require('./mock-globals')
-const log = require('../../lib/utils/log-shim')
-const envConfigKeys = Object.keys(require('../../lib/utils/config/definitions.js'))
+const tmock = require('./tmock')
+const defExitCode = process.exitCode
+
+const changeDir = (dir) => {
+ if (dir) {
+ const cwd = process.cwd()
+ process.chdir(dir)
+ return () => process.chdir(cwd)
+ }
+ return () => {}
+}
+
+const setGlobalNodeModules = (globalDir) => {
+ const updateSymlinks = (obj, visit) => {
+ for (const [key, value] of Object.entries(obj)) {
+ if (/Fixture<symlink>/.test(value.toString())) {
+ obj[key] = tap.fixture('symlink', path.join('..', value.content))
+ } else if (typeof value === 'object') {
+ obj[key] = updateSymlinks(value, visit)
+ }
+ }
+ return obj
+ }
+
+ if (globalDir.lib) {
+ throw new Error('`globalPrefixDir` should not have a top-level `lib/` directory, only a ' +
+ 'top-level `node_modules/` dir that gets set in the correct location based on platform. ' +
+ `Received the following top level entries: ${Object.keys(globalDir).join(', ')}.`
+ )
+ }
+
+ if (process.platform !== 'win32' && globalDir.node_modules) {
+ const { node_modules: nm, ...rest } = globalDir
+ return {
+ ...rest,
+ lib: { node_modules: updateSymlinks(nm) },
+ }
+ }
-const RealMockNpm = (t, otherMocks = {}) => {
+ return globalDir
+}
+
+const getMockNpm = async (t, { mocks, init, load, npm: npmOpts }) => {
const mock = {
- ...mockLogs(otherMocks),
+ ...mockLogs(mocks),
outputs: [],
outputErrors: [],
joinedOutput: () => mock.outputs.map(o => o.join(' ')).join('\n'),
}
- const Npm = t.mock('../../lib/npm.js', {
- '../../lib/utils/update-notifier.js': async () => {},
- ...otherMocks,
+ const Npm = tmock(t, '{LIB}/npm.js', {
+ '{LIB}/utils/update-notifier.js': async () => {},
+ ...mocks,
...mock.logMocks,
})
- mock.Npm = class MockNpm extends Npm {
+ class MockNpm extends Npm {
+ async exec (...args) {
+ const [res, err] = await super.exec(...args).then((r) => [r]).catch(e => [null, e])
+ // This mimics how the exit handler flushes output for commands that have
+ // buffered output. It also uses the same json error processing from the
+ // error message fn. This is necessary for commands with buffered output
+ // to read the output after exec is called. This is not *exactly* how it
+ // works in practice, but it is close enough for now.
+ this.flushOutput(err ? errorMessage(err, this).json : null)
+ if (err) {
+ throw err
+ }
+ return res
+ }
+
// lib/npm.js tests needs this to actually test the function!
originalOutput (...args) {
super.output(...args)
@@ -39,77 +94,88 @@ const RealMockNpm = (t, otherMocks = {}) => {
}
}
- return mock
-}
-
-const setLoglevel = (t, loglevel, reset = true) => {
- if (t && reset) {
- const _level = log.level
- t.teardown(() => log.level = _level)
+ mock.Npm = MockNpm
+ if (init) {
+ mock.npm = new MockNpm(npmOpts)
+ if (load) {
+ await mock.npm.load()
+ }
}
- if (loglevel) {
- // Set log level on the npmlog singleton and shared across everything
- log.level = loglevel
- }
+ return mock
}
-// Resolve some options to a function call with supplied args
-const result = (fn, ...args) => typeof fn === 'function' ? fn(...args) : fn
+const mockNpms = new Map()
-const LoadMockNpm = async (t, {
+const setupMockNpm = async (t, {
init = true,
load = init,
+ // preload a command
+ command = null, // string name of the command
+ exec = null, // optionally exec the command before returning
+ // test dirs
prefixDir = {},
homeDir = {},
cacheDir = {},
- globalPrefixDir = { lib: {} },
- config = {},
- mocks = {},
+ globalPrefixDir = { node_modules: {} },
otherDirs = {},
- globals = null,
+ chdir = ({ prefix }) => prefix,
+ // setup config, env vars, mocks, npm opts
+ config: _config = {},
+ mocks = {},
+ globals = {},
+ npm: npmOpts = {},
+ argv: rawArgv = [],
} = {}) => {
- // Mock some globals with their original values so they get torn down
- // back to the original at the end of the test since they are manipulated
- // by npm itself
- const npmConfigEnv = {}
- for (const key in process.env) {
- if (key.startsWith('npm_config_')) {
- npmConfigEnv[key] = undefined
+ // easy to accidentally forget to pass in tap
+ if (!(t instanceof tap.Test)) {
+ throw new Error('first argument must be a tap instance')
+ }
+
+ // mockNpm is designed to only be run once per test chain so we assign it to
+ // the test in the cache and error if it is attempted to run again
+ let tapInstance = t
+ while (tapInstance) {
+ if (mockNpms.has(tapInstance)) {
+ throw new Error('mockNpm can only be called once in each t.test chain')
}
+ tapInstance = tapInstance.parent
}
+ mockNpms.set(t, true)
+
+ if (!init && load) {
+ throw new Error('cant `load` without `init`')
+ }
+
+ // These are globals manipulated by npm itself that we need to reset to their
+ // original values between tests
+ const npmEnvs = Object.keys(process.env).filter(k => k.startsWith('npm_'))
mockGlobals(t, {
process: {
title: process.title,
execPath: process.execPath,
env: {
- npm_command: process.env.npm_command,
+ NODE_ENV: process.env.NODE_ENV,
COLOR: process.env.COLOR,
- ...npmConfigEnv,
+ // further, these are npm controlled envs that we need to zero out before
+ // before the test. setting them to undefined ensures they are not set and
+ // also returned to their original value after the test
+ ...npmEnvs.reduce((acc, k) => {
+ acc[k] = undefined
+ return acc
+ }, {}),
},
},
})
- const { Npm, ...rest } = RealMockNpm(t, mocks)
-
- // We want to fail fast when writing tests. Default this to 0 unless it was
- // explicitly set in a test.
- config = { 'fetch-retries': 0, ...config }
-
- if (!init && load) {
- throw new Error('cant `load` without `init`')
- }
-
- // Set log level as early as possible since
- setLoglevel(t, config.loglevel)
-
const dir = t.testdir({
home: homeDir,
prefix: prefixDir,
cache: cacheDir,
- global: globalPrefixDir,
+ global: setGlobalNodeModules(globalPrefixDir),
other: otherDirs,
})
+
const dirs = {
testdir: dir,
prefix: path.join(dir, 'prefix'),
@@ -119,52 +185,93 @@ const LoadMockNpm = async (t, {
other: path.join(dir, 'other'),
}
- // Set cache to testdir via env var so it is available when load is run
- // XXX: remove this for a solution where cache argv is passed in
+ // Option objects can also be functions that are called with all the dir paths
+ // so they can be used to set configs that need to be based on paths
+ const withDirs = (v) => typeof v === 'function' ? v(dirs) : v
+
+ const teardownDir = changeDir(withDirs(chdir))
+
+ const defaultConfigs = {
+ // We want to fail fast when writing tests. Default this to 0 unless it was
+ // explicitly set in a test.
+ 'fetch-retries': 0,
+ cache: dirs.cache,
+ }
+
+ const { argv, env, config } = Object.entries({ ...defaultConfigs, ...withDirs(_config) })
+ .reduce((acc, [key, value]) => {
+ // nerfdart configs passed in need to be set via env var instead of argv
+ // and quoted with `"` so mock globals will ignore that it contains dots
+ if (key.startsWith('//')) {
+ acc.env[`process.env."npm_config_${key}"`] = value
+ } else {
+ const values = [].concat(value)
+ acc.argv.push(...values.flatMap(v => [`--${key}`, v.toString()]))
+ }
+ acc.config[key] = value
+ return acc
+ }, { argv: [...rawArgv], env: {}, config: {} })
+
mockGlobals(t, {
'process.env.HOME': dirs.home,
- 'process.env.npm_config_cache': dirs.cache,
- ...(globals ? result(globals, { ...dirs }) : {}),
- // Some configs don't work because they can't be set via npm.config.set until
- // config is loaded. But some config items are needed before that. So this is
- // an explicit set of configs that must be loaded as env vars.
- // XXX(npm9): make this possible by passing in argv directly to npm/config
- ...Object.entries(config)
- .filter(([k]) => envConfigKeys.includes(k))
- .reduce((acc, [k, v]) => {
- acc[`process.env.npm_config_${k.replace(/-/g, '_')}`] =
- result(v, { ...dirs }).toString()
- return acc
- }, {}),
+ // global prefix cannot be (easily) set via argv so this is the easiest way
+ // to set it that also closely mimics the behavior a user would see since it
+ // will already be set while `npm.load()` is being run
+ // Note that this only sets the global prefix and the prefix is set via chdir
+ 'process.env.PREFIX': dirs.globalPrefix,
+ ...withDirs(globals),
+ ...env,
})
- const npm = init ? new Npm() : null
+ const { npm, ...mockNpm } = await getMockNpm(t, {
+ init,
+ load,
+ mocks: withDirs(mocks),
+ npm: { argv, excludeNpmCwd: true, ...withDirs(npmOpts) },
+ })
+
+ if (config.omit?.includes('prod')) {
+ // XXX(HACK): --omit=prod is not a valid config according to the definitions but
+ // it was being hacked in via flatOptions for older tests so this is to
+ // preserve that behavior and reduce churn in the snapshots. this should be
+ // removed or fixed in the future
+ npm.flatOptions.omit.push('prod')
+ }
+
t.teardown(() => {
- npm && npm.unload()
+ if (npm) {
+ npm.unload()
+ }
+ // only set exitCode back if we're passing tests
+ if (t.passing()) {
+ process.exitCode = defExitCode
+ }
+ teardownDir()
})
- if (load) {
- await npm.load()
- for (const [k, v] of Object.entries(result(config, { npm, ...dirs }))) {
- if (typeof v === 'object' && v.value && v.where) {
- npm.config.set(k, v.value, v.where)
- } else {
- npm.config.set(k, v)
- }
+ const mockCommand = {}
+ if (command) {
+ const cmd = await npm.cmd(command)
+ const usage = await cmd.usage
+ mockCommand.cmd = cmd
+ mockCommand[command] = {
+ usage,
+ exec: (args) => npm.exec(command, args),
+ completion: (args) => cmd.completion(args),
+ }
+ if (exec) {
+ await mockCommand[command].exec(exec)
+ // assign string output to the command now that we have it
+ // for easier testing
+ mockCommand[command].output = mockNpm.joinedOutput()
}
- // Set global loglevel *again* since it possibly got reset during load
- // XXX: remove with npmlog
- setLoglevel(t, config.loglevel, false)
- npm.prefix = dirs.prefix
- npm.cache = dirs.cache
- npm.globalPrefix = dirs.globalPrefix
}
return {
- ...rest,
- ...dirs,
- Npm,
npm,
+ ...mockNpm,
+ ...dirs,
+ ...mockCommand,
debugFile: async () => {
const readFiles = npm.logFiles.map(f => fs.readFile(f))
const logFiles = await Promise.all(readFiles)
@@ -180,80 +287,6 @@ const LoadMockNpm = async (t, {
}
}
-const realConfig = require('../../lib/utils/config')
-
-// Basic npm fixture that you can give a config object that acts like
-// npm.config You still need a separate flatOptions. Tests should migrate to
-// using the real npm mock above
-class MockNpm {
- constructor (base = {}, t) {
- this._mockOutputs = []
- this.isMockNpm = true
- this.base = base
-
- const config = base.config || {}
-
- for (const attr in base) {
- if (attr !== 'config') {
- this[attr] = base[attr]
- }
- }
-
- this.flatOptions = base.flatOptions || {}
- this.config = {
- // for now just set `find` to what config.find should return
- // this works cause `find` is not an existing config entry
- find: (k) => ({ ...realConfig.defaults, ...config })[k],
- // for now isDefault is going to just return false if a value was defined
- isDefault: (k) => !Object.prototype.hasOwnProperty.call(config, k),
- get: (k) => ({ ...realConfig.defaults, ...config })[k],
- set: (k, v) => {
- config[k] = v
- // mock how real npm derives silent
- if (k === 'loglevel') {
- this.flatOptions.silent = v === 'silent'
- this.silent = v === 'silent'
- }
- },
- list: [{ ...realConfig.defaults, ...config }],
- validate: () => {},
- }
-
- if (t && config.loglevel) {
- setLoglevel(t, config.loglevel)
- }
-
- if (config.loglevel) {
- this.config.set('loglevel', config.loglevel)
- }
- }
-
- get global () {
- return this.config.get('global') || this.config.get('location') === 'global'
- }
-
- output (...msg) {
- if (this.base.output) {
- return this.base.output(msg)
- }
- this._mockOutputs.push(msg)
- }
-
- // with the older fake mock npm there is no
- // difference between output and outputBuffer
- // since it just collects the output and never
- // calls the exit handler, so we just mock the
- // method the same as output.
- outputBuffer (...msg) {
- this.output(...msg)
- }
-}
-
-const FakeMockNpm = (base = {}, t) => {
- return new MockNpm(base, t)
-}
-
-module.exports = {
- fake: FakeMockNpm,
- load: LoadMockNpm,
-}
+module.exports = setupMockNpm
+module.exports.load = setupMockNpm
+module.exports.setGlobalNodeModules = setGlobalNodeModules
diff --git a/deps/npm/test/fixtures/sandbox.js b/deps/npm/test/fixtures/sandbox.js
index c7bb8218dc..460609628c 100644
--- a/deps/npm/test/fixtures/sandbox.js
+++ b/deps/npm/test/fixtures/sandbox.js
@@ -2,9 +2,7 @@ const { createHook, executionAsyncId } = require('async_hooks')
const { EventEmitter } = require('events')
const { homedir, tmpdir } = require('os')
const { dirname, join } = require('path')
-const { promisify } = require('util')
-const { mkdir } = require('fs/promises')
-const rimraf = promisify(require('rimraf'))
+const { mkdir, rm } = require('fs/promises')
const mockLogs = require('./mock-logs')
const pkg = require('../../package.json')
@@ -201,7 +199,7 @@ class Sandbox extends EventEmitter {
if (this[_npm]) {
this[_npm].unload()
}
- return rimraf(this[_dirs].temp).catch(() => null)
+ return rm(this[_dirs].temp, { recursive: true, force: true }).catch(() => null)
}
// proxy get handler
diff --git a/deps/npm/test/fixtures/tmock.js b/deps/npm/test/fixtures/tmock.js
new file mode 100644
index 0000000000..321e8bc07c
--- /dev/null
+++ b/deps/npm/test/fixtures/tmock.js
@@ -0,0 +1,27 @@
+const path = require('path')
+
+const ROOT = path.resolve(__dirname, '../..')
+const BIN = path.join(ROOT, 'bin')
+const LIB = path.join(ROOT, 'lib')
+
+// since mock npm changes directories it can be hard to figure out the
+// correct path to mock something with tap since the directory will change
+// before/after npm is loaded. This helper replaces {BIN} and {LIB} with
+// the absolute path to those directories
+const replace = (s) => {
+ if (/^[./{]/.test(s)) {
+ return s
+ .replace(/^\{BIN\}/, BIN)
+ .replace(/^\{LIB\}/, LIB)
+ .replace(/^\{ROOT\}/, ROOT)
+ } else {
+ return require.resolve(s)
+ }
+}
+
+const tmock = (t, p, mocks = {}) => {
+ const entries = Object.entries(mocks).map(([k, v]) => [replace(k), v])
+ return t.mock(replace(p), Object.fromEntries(entries))
+}
+
+module.exports = tmock
diff --git a/deps/npm/test/index.js b/deps/npm/test/index.js
index 747d75b5fd..44fb0989df 100644
--- a/deps/npm/test/index.js
+++ b/deps/npm/test/index.js
@@ -1,34 +1,20 @@
const t = require('tap')
+const spawn = require('@npmcli/promise-spawn')
const index = require.resolve('../index.js')
const packageIndex = require.resolve('../')
+const { load: loadMockNpm } = require('./fixtures/mock-npm')
t.equal(index, packageIndex, 'index is main package require() export')
t.throws(() => require(index), {
message: 'The programmatic API was removed in npm v8.0.0',
})
-t.test('loading as main module will load the cli', t => {
- const cwd = t.testdir()
- const { spawn } = require('child_process')
+t.test('loading as main module will load the cli', async t => {
+ const { npm, cache } = await loadMockNpm(t)
const LS = require('../lib/commands/ls.js')
- const ls = new LS({
- config: {
- validate: () => {},
- get: (key) => {
- if (key === 'location') {
- return 'project'
- }
- },
- isDefault: () => {},
- },
- })
- const p = spawn(process.execPath, [index, 'ls', '-h', '--cache', cwd])
- const out = []
- p.stdout.on('data', c => out.push(c))
- p.on('close', (code, signal) => {
- t.equal(code, 0)
- t.equal(signal, null)
- t.match(Buffer.concat(out).toString(), ls.usage)
- t.end()
- })
+ const ls = new LS(npm)
+ const p = await spawn(process.execPath, [index, 'ls', '-h', '--cache', cache])
+ t.equal(p.code, 0)
+ t.equal(p.signal, null)
+ t.match(p.stdout, ls.usage)
})
diff --git a/deps/npm/test/lib/arborist-cmd.js b/deps/npm/test/lib/arborist-cmd.js
index f3c1d2573d..36c697cd9e 100644
--- a/deps/npm/test/lib/arborist-cmd.js
+++ b/deps/npm/test/lib/arborist-cmd.js
@@ -1,115 +1,140 @@
const { resolve } = require('path')
const t = require('tap')
-const ArboristCmd = require('../../lib/arborist-cmd.js')
+const { load: loadMockNpm } = require('../fixtures/mock-npm')
+const tmock = require('../fixtures/tmock')
-const configMock = {
- validate: () => {},
- get: (key) => {
- if (key === 'location') {
- return 'project'
- }
- },
- isDefault: () => {},
-}
+const mockArboristCmd = async (t, exec, workspace, { mocks = {}, ...opts } = {}) => {
+ const ArboristCmd = tmock(t, '{LIB}/arborist-cmd.js', mocks)
-t.test('arborist-cmd', async t => {
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'simple-workspaces-list',
- version: '1.1.1',
- workspaces: [
- 'a',
- 'b',
- 'group/*',
- ],
- }),
- node_modules: {
- abbrev: {
- 'package.json': JSON.stringify({ name: 'abbrev', version: '1.1.1' }),
+ const config = (typeof workspace === 'function')
+ ? (dirs) => ({ workspace: workspace(dirs) })
+ : { workspace }
+
+ const mock = await loadMockNpm(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'simple-workspaces-list',
+ version: '1.1.1',
+ workspaces: [
+ 'a',
+ 'b',
+ 'group/*',
+ ],
+ }),
+ node_modules: {
+ abbrev: {
+ 'package.json': JSON.stringify({ name: 'abbrev', version: '1.1.1' }),
+ },
+ a: t.fixture('symlink', '../a'),
+ b: t.fixture('symlink', '../b'),
},
- a: t.fixture('symlink', '../a'),
- b: t.fixture('symlink', '../b'),
- },
- a: {
- 'package.json': JSON.stringify({ name: 'a', version: '1.0.0' }),
- },
- b: {
- 'package.json': JSON.stringify({ name: 'b', version: '1.0.0' }),
- },
- group: {
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- dependencies: {
- abbrev: '^1.1.1',
- },
- }),
+ a: {
+ 'package.json': JSON.stringify({ name: 'a', version: '1.0.0' }),
+ },
+ b: {
+ 'package.json': JSON.stringify({ name: 'b', version: '1.0.0' }),
},
- d: {
- 'package.json': JSON.stringify({ name: 'd', version: '1.0.0' }),
+ group: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: '^1.1.1',
+ },
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({ name: 'd', version: '1.0.0' }),
+ },
},
},
+ ...opts,
})
- class TestCmd extends ArboristCmd {}
-
- const cmd = new TestCmd({ localPrefix: path, config: configMock })
-
- // check filtering for a single workspace name
- cmd.exec = async function (args) {
- t.same(this.workspaceNames, ['a'], 'should set array with single ws name')
- t.same(args, ['foo'], 'should get received args')
+ let execArg
+ class TestCmd extends ArboristCmd {
+ async exec (arg) {
+ execArg = arg
+ }
}
- await cmd.execWorkspaces(['foo'], ['a'])
- // check filtering single workspace by path
- cmd.exec = async function (args) {
- t.same(this.workspaceNames, ['a'],
- 'should set array with single ws name from path')
+ const cmd = new TestCmd(mock.npm)
+ if (exec) {
+ await cmd.execWorkspaces(exec)
}
- await cmd.execWorkspaces([], ['./a'])
- // check filtering single workspace by full path
- cmd.exec = function (args) {
- t.same(this.workspaceNames, ['a'],
- 'should set array with single ws name from full path')
- }
- await cmd.execWorkspaces([], [resolve(path, './a')])
+ return { ...mock, cmd, getArg: () => execArg }
+}
- // filtering multiple workspaces by name
- cmd.exec = async function (args) {
- t.same(this.workspaceNames, ['a', 'c'],
- 'should set array with multiple listed ws names')
- }
- await cmd.execWorkspaces([], ['a', 'c'])
+t.test('arborist-cmd', async t => {
+ await t.test('single name', async t => {
+ const { cmd, getArg } = await mockArboristCmd(t, ['foo'], 'a')
- // filtering multiple workspaces by path names
- cmd.exec = async function (args) {
- t.same(this.workspaceNames, ['a', 'c'],
- 'should set array with multiple ws names from paths')
- }
- await cmd.execWorkspaces([], ['./a', 'group/c'])
+ t.same(cmd.workspaceNames, ['a'], 'should set array with single ws name')
+ t.same(getArg(), ['foo'], 'should get received args')
+ })
- // filtering multiple workspaces by parent path name
- cmd.exec = async function (args) {
- t.same(this.workspaceNames, ['c', 'd'],
- 'should set array with multiple ws names from a parent folder name')
- }
- await cmd.execWorkspaces([], ['./group'])
+ await t.test('single path', async t => {
+ const { cmd } = await mockArboristCmd(t, [], './a')
+
+ t.same(cmd.workspaceNames, ['a'], 'should set array with single ws name')
+ })
+
+ await t.test('single full path', async t => {
+ const { cmd } = await mockArboristCmd(t, [], ({ prefix }) => resolve(prefix, 'a'))
+
+ t.same(cmd.workspaceNames, ['a'], 'should set array with single ws name')
+ })
+
+ await t.test('multiple names', async t => {
+ const { cmd } = await mockArboristCmd(t, [], ['a', 'c'])
+
+ t.same(cmd.workspaceNames, ['a', 'c'], 'should set array with single ws name')
+ })
+
+ await t.test('multiple paths', async t => {
+ const { cmd } = await mockArboristCmd(t, [], ['./a', 'group/c'])
+
+ t.same(cmd.workspaceNames, ['a', 'c'], 'should set array with single ws name')
+ })
+
+ await t.test('parent path', async t => {
+ const { cmd } = await mockArboristCmd(t, [], './group')
+
+ t.same(cmd.workspaceNames, ['c', 'd'], 'should set array with single ws name')
+ })
+
+ await t.test('parent path', async t => {
+ const { cmd } = await mockArboristCmd(t, [], './group')
+
+ t.same(cmd.workspaceNames, ['c', 'd'], 'should set array with single ws name')
+ })
+
+ await t.test('prefix inside cwd', async t => {
+ const { npm, cmd, prefix } = await mockArboristCmd(t, null, ['a', 'c'], {
+ chdir: (dirs) => dirs.testdir,
+ })
+
+ npm.localPrefix = prefix
+ await cmd.execWorkspaces([])
+
+ t.same(cmd.workspaceNames, ['a', 'c'], 'should set array with single ws name')
+ })
})
t.test('handle getWorkspaces raising an error', async t => {
- const ArboristCmd = t.mock('../../lib/arborist-cmd.js', {
- '../../lib/workspaces/get-workspaces.js': async () => {
- throw new Error('oopsie')
+ const { cmd } = await mockArboristCmd(t, null, 'a', {
+ mocks: {
+ '{LIB}/workspaces/get-workspaces.js': async () => {
+ throw new Error('oopsie')
+ },
},
})
- class TestCmd extends ArboristCmd {}
- const cmd = new TestCmd({ localPrefix: t.testdir(), config: configMock })
await t.rejects(
- cmd.execWorkspaces(['foo'], ['a']),
+ cmd.execWorkspaces(['foo']),
{ message: 'oopsie' }
)
})
diff --git a/deps/npm/test/lib/cli.js b/deps/npm/test/lib/cli.js
index 42a22a20b3..28640a2260 100644
--- a/deps/npm/test/lib/cli.js
+++ b/deps/npm/test/lib/cli.js
@@ -1,6 +1,6 @@
const t = require('tap')
-
const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
+const tmock = require('../fixtures/tmock')
const cliMock = async (t, opts) => {
let exitHandlerArgs = null
@@ -12,9 +12,9 @@ const cliMock = async (t, opts) => {
exitHandlerMock.setNpm = _npm => npm = _npm
const { Npm, outputs, logMocks, logs } = await loadMockNpm(t, { ...opts, init: false })
- const cli = t.mock('../../lib/cli.js', {
- '../../lib/npm.js': Npm,
- '../../lib/utils/exit-handler.js': exitHandlerMock,
+ const cli = tmock(t, '{LIB}/cli.js', {
+ '{LIB}/npm.js': Npm,
+ '{LIB}/utils/exit-handler.js': exitHandlerMock,
...logMocks,
})
@@ -29,10 +29,6 @@ const cliMock = async (t, opts) => {
}
}
-t.afterEach(() => {
- process.exitCode = undefined
-})
-
t.test('print the version, and treat npm_g as npm -g', async t => {
const { logsBy, logs, cli, Npm, outputs, exitHandlerCalled } = await cliMock(t, {
globals: { 'process.argv': ['node', 'npm_g', '-v'] },
@@ -42,24 +38,18 @@ t.test('print the version, and treat npm_g as npm -g', async t => {
t.strictSame(process.argv, ['node', 'npm', '-g', '-v'], 'system process.argv was rewritten')
t.strictSame(logsBy('cli'), [['node npm']])
t.strictSame(logsBy('title'), [['npm']])
- t.strictSame(logsBy('argv'), [['"--global" "--version"']])
+ t.match(logsBy('argv'), [['"--global" "--version"']])
t.strictSame(logs.info, [
['using', 'npm@%s', Npm.version],
['using', 'node@%s', process.version],
])
+ t.equal(outputs.length, 1)
t.strictSame(outputs, [[Npm.version]])
t.strictSame(exitHandlerCalled(), [])
})
t.test('calling with --versions calls npm version with no args', async t => {
const { logsBy, cli, outputs, exitHandlerCalled } = await cliMock(t, {
- mocks: {
- '../../lib/commands/version.js': class Version {
- async exec (args) {
- t.strictSame(args, [])
- }
- },
- },
globals: {
'process.argv': ['node', 'npm', 'install', 'or', 'whatever', '--versions'],
},
@@ -69,18 +59,14 @@ t.test('calling with --versions calls npm version with no args', async t => {
t.equal(process.title, 'npm install or whatever')
t.strictSame(logsBy('cli'), [['node npm']])
t.strictSame(logsBy('title'), [['npm install or whatever']])
- t.strictSame(logsBy('argv'), [['"install" "or" "whatever" "--versions"']])
- t.strictSame(outputs, [])
+ t.match(logsBy('argv'), [['"install" "or" "whatever" "--versions"']])
+ t.equal(outputs.length, 1)
+ t.match(outputs[0][0], { npm: String, node: String, v8: String })
t.strictSame(exitHandlerCalled(), [])
})
t.test('logged argv is sanitized', async t => {
const { logsBy, cli } = await cliMock(t, {
- mocks: {
- '../../lib/commands/version.js': class Version {
- async exec () {}
- },
- },
globals: {
'process.argv': [
'node',
@@ -96,16 +82,11 @@ t.test('logged argv is sanitized', async t => {
t.equal(process.title, 'npm version')
t.strictSame(logsBy('cli'), [['node npm']])
t.strictSame(logsBy('title'), [['npm version']])
- t.strictSame(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/password"']])
+ t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org/password"']])
})
t.test('logged argv is sanitized with equals', async t => {
const { logsBy, cli } = await cliMock(t, {
- mocks: {
- '../../lib/commands/version.js': class Version {
- async exec () {}
- },
- },
globals: {
'process.argv': [
'node',
@@ -117,7 +98,7 @@ t.test('logged argv is sanitized with equals', async t => {
})
await cli(process)
- t.strictSame(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org"']])
+ t.match(logsBy('argv'), [['"version" "--registry" "https://u:***@npmjs.org"']])
})
t.test('print usage if no params provided', async t => {
@@ -153,7 +134,7 @@ t.test('load error calls error handler', async t => {
const err = new Error('test load error')
const { cli, exitHandlerCalled } = await cliMock(t, {
mocks: {
- '../../lib/utils/config/index.js': {
+ '{LIB}/utils/config/index.js': {
definitions: null,
flatten: null,
shorthands: null,
diff --git a/deps/npm/test/lib/commands/audit.js b/deps/npm/test/lib/commands/audit.js
index 02b00f7f9a..bba74407cb 100644
--- a/deps/npm/test/lib/commands/audit.js
+++ b/deps/npm/test/lib/commands/audit.js
@@ -86,7 +86,6 @@ t.test('normal audit', async t => {
await npm.exec('audit', [])
t.ok(process.exitCode, 'would have exited uncleanly')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -135,7 +134,6 @@ t.test('fallback audit ', async t => {
})
await npm.exec('audit', [])
t.ok(process.exitCode, 'would have exited uncleanly')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -165,7 +163,6 @@ t.test('json audit', async t => {
await npm.exec('audit', [])
t.ok(process.exitCode, 'would have exited uncleanly')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -762,7 +759,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -796,7 +792,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -903,7 +898,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /audited 3 packages/)
t.match(joinedOutput(), /2 packages have verified registry signatures/)
t.match(joinedOutput(), /1 package has an invalid registry signature/)
@@ -921,7 +915,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -937,7 +930,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /invalid registry signature/)
t.match(joinedOutput(), /kms-demo@1.0.0/)
t.matchSnapshot(joinedOutput())
@@ -955,7 +947,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /audited 2 packages/)
t.match(joinedOutput(), /verified registry signature/)
t.match(joinedOutput(), /missing registry signature/)
@@ -974,7 +965,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /audited 2 packages/)
t.match(joinedOutput(), /invalid/)
t.match(joinedOutput(), /missing/)
@@ -993,7 +983,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -1009,7 +998,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -1069,7 +1057,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(
joinedOutput(),
/registry is providing signing keys/
@@ -1088,7 +1075,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(
joinedOutput(),
/kms-demo/
@@ -1110,7 +1096,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), JSON.stringify({ invalid: [], missing: [] }, null, 2))
t.matchSnapshot(joinedOutput())
})
@@ -1129,7 +1114,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -1148,7 +1132,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.matchSnapshot(joinedOutput())
})
@@ -1166,7 +1149,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -1176,7 +1158,8 @@ t.test('audit signatures', async t => {
const { npm } = await loadMockNpm(t, {
prefixDir: installWithThirdPartyRegistry,
config: {
- '@npmcli:registry': registryUrl,
+ scope: '@npmcli',
+ registry: registryUrl,
},
})
const registry = new MockRegistry({ tap: t, registry: registryUrl })
@@ -1205,7 +1188,8 @@ t.test('audit signatures', async t => {
const { npm } = await loadMockNpm(t, {
prefixDir: installWithThirdPartyRegistry,
config: {
- '@npmcli:registry': registryUrl,
+ scope: '@npmcli',
+ registry: registryUrl,
},
})
const registry = new MockRegistry({ tap: t, registry: registryUrl })
@@ -1234,7 +1218,8 @@ t.test('audit signatures', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: installWithThirdPartyRegistry,
config: {
- '@npmcli:registry': registryUrl,
+ scope: '@npmcli',
+ registry: registryUrl,
},
})
const registry = new MockRegistry({ tap: t, registry: registryUrl })
@@ -1273,7 +1258,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -1283,7 +1267,8 @@ t.test('audit signatures', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: installWithThirdPartyRegistry,
config: {
- '@npmcli:registry': registryUrl,
+ scope: '@npmcli',
+ registry: registryUrl,
},
})
const registry = new MockRegistry({ tap: t, registry: registryUrl })
@@ -1321,7 +1306,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /https:\/\/verdaccio-clone.org/)
t.matchSnapshot(joinedOutput())
})
@@ -1331,7 +1315,8 @@ t.test('audit signatures', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: installWithThirdPartyRegistry,
config: {
- '@npmcli:registry': registryUrl,
+ scope: '@npmcli',
+ registry: registryUrl,
},
})
const registry = new MockRegistry({ tap: t, registry: registryUrl })
@@ -1363,7 +1348,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(joinedOutput(), /1 package has a missing registry signature/)
t.matchSnapshot(joinedOutput())
})
@@ -1371,9 +1355,9 @@ t.test('audit signatures', async t => {
t.test('multiple registries with keys and signatures', async t => {
const registryUrl = 'https://verdaccio-clone.org'
const { npm, joinedOutput } = await loadMockNpm(t, {
- prefixDir: installWithMultipleRegistries,
- config: {
- '@npmcli:registry': registryUrl,
+ prefixDir: {
+ ...installWithMultipleRegistries,
+ '.npmrc': `@npmcli:registry=${registryUrl}\n`,
},
})
const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') })
@@ -1418,7 +1402,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 2 packages/)
t.matchSnapshot(joinedOutput())
})
@@ -1465,7 +1448,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 1 package/)
t.matchSnapshot(joinedOutput())
})
@@ -1586,7 +1568,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 1, 'should exit with error')
- process.exitCode = 0
t.match(
joinedOutput(),
// eslint-disable-next-line no-control-regex
@@ -1645,7 +1626,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 3 packages/)
t.matchSnapshot(joinedOutput())
})
@@ -1653,7 +1633,7 @@ t.test('audit signatures', async t => {
t.test('verifies registry deps when filtering by workspace name', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceInstall,
- config: { workspace: ['./packages/a'] },
+ config: { workspace: './packages/a' },
})
const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') })
const asyncManifest = registry.manifest({
@@ -1699,7 +1679,6 @@ t.test('audit signatures', async t => {
await npm.exec('audit', ['signatures'])
t.equal(process.exitCode, 0, 'should exit successfully')
- process.exitCode = 0
t.match(joinedOutput(), /audited 2 packages/)
t.matchSnapshot(joinedOutput())
})
diff --git a/deps/npm/test/lib/commands/bugs.js b/deps/npm/test/lib/commands/bugs.js
index 91d144b6bd..bf45b9eee8 100644
--- a/deps/npm/test/lib/commands/bugs.js
+++ b/deps/npm/test/lib/commands/bugs.js
@@ -1,79 +1,71 @@
const t = require('tap')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
const pacote = {
- manifest: async (spec, options) => {
+ manifest: async (spec) => {
return spec === 'nobugs' ? {
name: 'nobugs',
version: '1.2.3',
- }
- : spec === 'bugsurl' ? {
- name: 'bugsurl',
- version: '1.2.3',
- bugs: 'https://bugzilla.localhost/bugsurl',
- }
- : spec === 'bugsobj' ? {
- name: 'bugsobj',
- version: '1.2.3',
- bugs: { url: 'https://bugzilla.localhost/bugsobj' },
- }
- : spec === 'bugsobj-nourl' ? {
- name: 'bugsobj-nourl',
- version: '1.2.3',
- bugs: { no: 'url here' },
- }
- : spec === 'repourl' ? {
- name: 'repourl',
- version: '1.2.3',
- repository: 'https://github.com/foo/repourl',
- }
- : spec === 'repoobj' ? {
- name: 'repoobj',
- version: '1.2.3',
- repository: { url: 'https://github.com/foo/repoobj' },
- }
- : spec === 'mailtest' ? {
- name: 'mailtest',
- version: '3.7.4',
- bugs: { email: 'hello@example.com' },
- }
- : spec === 'secondmailtest' ? {
- name: 'secondmailtest',
- version: '0.1.1',
- bugs: { email: 'ABC432abc@a.b.example.net' },
- }
- : spec === '.' ? {
- name: 'thispkg',
- version: '1.2.3',
- bugs: 'https://example.com',
- }
- : null
+ } : spec === 'bugsurl' ? {
+ name: 'bugsurl',
+ version: '1.2.3',
+ bugs: 'https://bugzilla.localhost/bugsurl',
+ } : spec === 'bugsobj' ? {
+ name: 'bugsobj',
+ version: '1.2.3',
+ bugs: { url: 'https://bugzilla.localhost/bugsobj' },
+ } : spec === 'bugsobj-nourl' ? {
+ name: 'bugsobj-nourl',
+ version: '1.2.3',
+ bugs: { no: 'url here' },
+ } : spec === 'repourl' ? {
+ name: 'repourl',
+ version: '1.2.3',
+ repository: 'https://github.com/foo/repourl',
+ } : spec === 'repoobj' ? {
+ name: 'repoobj',
+ version: '1.2.3',
+ repository: { url: 'https://github.com/foo/repoobj' },
+ } : spec === 'mailtest' ? {
+ name: 'mailtest',
+ version: '3.7.4',
+ bugs: { email: 'hello@example.com' },
+ } : spec === 'secondmailtest' ? {
+ name: 'secondmailtest',
+ version: '0.1.1',
+ bugs: { email: 'ABC432abc@a.b.example.net' },
+ } : spec === '.' ? {
+ name: 'thispkg',
+ version: '1.2.3',
+ bugs: 'https://example.com',
+ } : null
},
}
-// keep a tally of which urls got opened
-let opened = {}
-const openUrl = async (npm, url, errMsg) => {
- opened[url] = opened[url] || 0
- opened[url]++
-}
-
-const Bugs = t.mock('../../../lib/commands/bugs.js', {
- pacote,
- '../../../lib/utils/open-url.js': openUrl,
+t.test('usage', async (t) => {
+ const { npm } = await loadMockNpm(t)
+ const bugs = await npm.cmd('bugs')
+ t.match(bugs.usage, 'bugs', 'usage has command name in it')
})
-const bugs = new Bugs({ flatOptions: {}, config: { validate: () => {} } })
+t.test('open bugs urls & emails', async t => {
+ // keep a tally of which urls got opened
+ let opened = {}
-t.test('usage', (t) => {
- t.match(bugs.usage, 'bugs', 'usage has command name in it')
- t.end()
-})
+ const openUrl = async (_, url) => {
+ opened[url] = opened[url] || 0
+ opened[url]++
+ }
-t.afterEach(() => {
- opened = {}
-})
-t.test('open bugs urls & emails', t => {
- const expect = {
+ const { npm } = await loadMockNpm(t, {
+ mocks: {
+ pacote,
+ '{LIB}/utils/open-url.js': openUrl,
+ },
+ })
+
+ const expected = {
+ '.': 'https://example.com',
nobugs: 'https://www.npmjs.com/package/nobugs',
'bugsobj-nourl': 'https://www.npmjs.com/package/bugsobj-nourl',
bugsurl: 'https://bugzilla.localhost/bugsurl',
@@ -82,19 +74,19 @@ t.test('open bugs urls & emails', t => {
repoobj: 'https://github.com/foo/repoobj/issues',
mailtest: 'mailto:hello@example.com',
secondmailtest: 'mailto:ABC432abc@a.b.example.net',
- '.': 'https://example.com',
}
- const keys = Object.keys(expect)
- t.plan(keys.length)
- keys.forEach(pkg => {
- t.test(pkg, async t => {
- await bugs.exec([pkg])
- t.equal(opened[expect[pkg]], 1, 'opened expected url', { opened })
+
+ for (const [pkg, expect] of Object.entries(expected)) {
+ await t.test(pkg, async t => {
+ await npm.exec('bugs', [pkg])
+ t.equal(opened[expect], 1, 'opened expected url', { opened })
})
- })
-})
+ }
-t.test('open default package if none specified', async t => {
- await bugs.exec([])
- t.equal(opened['https://example.com'], 1, 'opened expected url', { opened })
+ opened = {}
+
+ await t.test('open default package if none specified', async t => {
+ await npm.exec('bugs', [])
+ t.equal(opened['https://example.com'], 1, 'opened expected url', { opened })
+ })
})
diff --git a/deps/npm/test/lib/commands/config.js b/deps/npm/test/lib/commands/config.js
index 35872e722e..f2bdcc7231 100644
--- a/deps/npm/test/lib/commands/config.js
+++ b/deps/npm/test/lib/commands/config.js
@@ -26,16 +26,10 @@ t.test('config ignores workspaces', async t => {
await t.rejects(
sandbox.run('config', ['--workspaces']),
{
- code: 'EUSAGE',
+ code: 'ENOWORKSPACES',
},
'rejects with usage'
)
-
- t.match(
- sandbox.logs.warn,
- [['config', 'This command does not support workspaces.']],
- 'logged the warning'
- )
})
t.test('config list', async t => {
diff --git a/deps/npm/test/lib/commands/diff.js b/deps/npm/test/lib/commands/diff.js
index 0ca9c3b8d0..d9ff9e5dad 100644
--- a/deps/npm/test/lib/commands/diff.js
+++ b/deps/npm/test/lib/commands/diff.js
@@ -1,1164 +1,1041 @@
const t = require('tap')
-const { resolve, join } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const { join, extname } = require('path')
+const MockRegistry = require('@npmcli/mock-registry')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
+
+const jsonifyTestdir = (obj) => {
+ for (const [key, value] of Object.entries(obj || {})) {
+ if (extname(key) === '.json') {
+ obj[key] = JSON.stringify(value, null, 2) + '\n'
+ } else if (typeof value === 'object') {
+ obj[key] = jsonifyTestdir(value)
+ } else {
+ obj[key] = value.trim() + '\n'
+ }
+ }
+ return obj
+}
-const noop = () => null
-let libnpmdiff = noop
+// generic helper to call diff with a specified dir contents and registry calls
+const mockDiff = async (t, {
+ exec,
+ diff = [],
+ tarballs = {},
+ times = {},
+ ...opts
+} = {}) => {
+ const tarballFixtures = Object.entries(tarballs).reduce((acc, [spec, fixture]) => {
+ const [name, version] = spec.split('@')
+ acc[name] = acc[name] || {}
+ acc[name][version] = fixture
+ if (!acc[name][version]['package.json']) {
+ acc[name][version]['package.json'] = { name, version }
+ } else {
+ acc[name][version]['package.json'].name = name
+ acc[name][version]['package.json'].version = version
+ }
+ return acc
+ }, {})
+
+ const { prefixDir, globalPrefixDir, otherDirs, config, ...rest } = opts
+ const { npm, ...res } = await loadMockNpm(t, {
+ prefixDir: jsonifyTestdir(prefixDir),
+ otherDirs: jsonifyTestdir({ tarballs: tarballFixtures, ...otherDirs }),
+ globalPrefixDir: jsonifyTestdir(globalPrefixDir),
+ config: {
+ ...config,
+ diff: [].concat(diff),
+ },
+ ...rest,
+ })
-const config = {
- global: false,
- tag: 'latest',
- diff: [],
-}
-const flatOptions = {
- global: false,
- diffUnified: null,
- diffIgnoreAllSpace: false,
- diffNoPrefix: false,
- diffSrcPrefix: '',
- diffDstPrefix: '',
- diffText: false,
- savePrefix: '^',
-}
-const fooPath = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo', version: '1.0.0' }),
-})
-const npm = mockNpm({
- prefix: fooPath,
- config,
- flatOptions,
- output: noop,
-})
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ strict: true,
+ debug: true,
+ })
+
+ const manifests = Object.entries(tarballFixtures).reduce((acc, [name, versions]) => {
+ acc[name] = registry.manifest({
+ name,
+ packuments: Object.keys(versions).map((version) => ({ version })),
+ })
+ return acc
+ }, {})
+
+ for (const [name, manifest] of Object.entries(manifests)) {
+ await registry.package({ manifest, times: times[name] ?? 1 })
+ for (const [version, tarballManifest] of Object.entries(manifest.versions)) {
+ await registry.tarball({
+ manifest: tarballManifest,
+ tarball: join(res.other, 'tarballs', name, version),
+ })
+ }
+ }
-const mocks = {
- 'proc-log': { info: noop, verbose: noop },
- libnpmdiff: (...args) => libnpmdiff(...args),
- 'npm-registry-fetch': async () => ({}),
+ if (exec) {
+ await npm.exec('diff', exec)
+ res.output = res.joinedOutput()
+ }
+
+ return { npm, registry, ...res }
}
-t.afterEach(() => {
- config.global = false
- config.tag = 'latest'
- config.diff = []
- flatOptions.global = false
- flatOptions.diffUnified = null
- flatOptions.diffIgnoreAllSpace = false
- flatOptions.diffNoPrefix = false
- flatOptions.diffSrcPrefix = ''
- flatOptions.diffDstPrefix = ''
- flatOptions.diffText = false
- flatOptions.savePrefix = '^'
- npm.globalDir = fooPath
- npm.prefix = fooPath
- libnpmdiff = noop
- diff.prefix = undefined
- diff.top = undefined
-})
+// a more specific helper to call diff against a local package and a registry package
+// and assert the diff output contains the matching strings
+const assertFoo = async (t, arg) => {
+ let diff = []
+ let exec = []
+
+ if (typeof arg === 'string' || Array.isArray(arg)) {
+ diff = arg
+ } else if (arg && typeof arg === 'object') {
+ diff = arg.diff
+ exec = arg.exec
+ }
+
+ const { output } = await mockDiff(t, {
+ diff,
+ prefixDir: {
+ 'package.json': { name: 'foo', version: '1.0.0' },
+ 'index.js': 'const version = "1.0.0"',
+ 'a.js': 'const a = "a@1.0.0"',
+ 'b.js': 'const b = "b@1.0.0"',
+ },
+ tarballs: {
+ 'foo@0.1.0': {
+ 'index.js': 'const version = "0.1.0"',
+ 'a.js': 'const a = "a@0.1.0"',
+ 'b.js': 'const b = "b@0.1.0"',
+ },
+ },
+ exec,
+ })
-const Diff = t.mock('../../../lib/commands/diff.js', mocks)
-const diff = new Diff(npm)
+ const hasFile = (f) => !exec.length || exec.some(e => e.endsWith(f))
-t.test('no args', t => {
- t.test('in a project dir', async t => {
- t.plan(3)
+ if (hasFile('package.json')) {
+ t.match(output, /-\s*"version": "0\.1\.0"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
+ }
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@latest', 'should have default spec comparison')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(opts, npm.flatOptions, 'should forward flat options')
- }
+ if (hasFile('index.js')) {
+ t.match(output, /-\s*const version = "0\.1\.0"/)
+ t.match(output, /\+\s*const version = "1\.0\.0"/)
+ }
+
+ if (hasFile('a.js')) {
+ t.match(output, /-\s*const a = "a@0\.1\.0"/)
+ t.match(output, /\+\s*const a = "a@1\.0\.0"/)
+ }
+
+ if (hasFile('b.js')) {
+ t.match(output, /-\s*const b = "b@0\.1\.0"/)
+ t.match(output, /\+\s*const b = "b@1\.0\.0"/)
+ }
- npm.prefix = fooPath
- await diff.exec([])
+ return output
+}
+
+const rejectDiff = async (t, msg, opts) => {
+ const { npm } = await mockDiff(t, opts)
+ await t.rejects(npm.exec('diff', []), msg)
+}
+
+t.test('no args', async t => {
+ t.test('in a project dir', async t => {
+ const output = await assertFoo(t)
+ t.matchSnapshot(output)
})
t.test('no args, missing package.json name in cwd', async t => {
- const path = t.testdir({})
- npm.prefix = path
- await t.rejects(
- diff.exec([]),
- /Needs multiple arguments to compare or run from a project dir./,
- 'should throw EDIFF error msg'
- )
+ await rejectDiff(t, /Needs multiple arguments to compare or run from a project dir./)
})
t.test('no args, bad package.json in cwd', async t => {
- const path = t.testdir({
- 'package.json': '{invalid"json',
+ await rejectDiff(t, /Needs multiple arguments to compare or run from a project dir./, {
+ prefixDir: { 'package.json': '{invalid"json' },
})
- npm.prefix = path
-
- await t.rejects(
- diff.exec([]),
- /Needs multiple arguments to compare or run from a project dir./,
- 'should throw EDIFF error msg'
- )
})
-
- t.end()
})
-t.test('single arg', t => {
+t.test('single arg', async t => {
t.test('spec using cwd package name', async t => {
- t.plan(3)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@1.0.0', 'should forward single spec')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(opts, npm.flatOptions, 'should forward flat options')
- }
-
- config.diff = ['foo@1.0.0']
- npm.prefix = fooPath
- await diff.exec([])
+ await assertFoo(t, 'foo@0.1.0')
})
t.test('unknown spec, no package.json', async t => {
- const path = t.testdir({})
-
- config.diff = ['foo@1.0.0']
- npm.prefix = path
- await t.rejects(
- diff.exec([]),
- /Needs multiple arguments to compare or run from a project dir./,
- 'should throw usage error'
- )
+ await rejectDiff(t, /Needs multiple arguments to compare or run from a project dir./, {
+ diff: ['foo@1.0.0'],
+ })
})
t.test('spec using semver range', async t => {
- t.plan(3)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@~1.0.0', 'should forward single spec')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(opts, npm.flatOptions, 'should forward flat options')
- }
-
- config.diff = ['foo@~1.0.0']
- await diff.exec([])
+ await assertFoo(t, 'foo@~0.1.0')
})
t.test('version', async t => {
- t.plan(3)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@2.1.4', 'should convert to expected first spec')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(opts, npm.flatOptions, 'should forward flat options')
- }
-
- config.diff = ['2.1.4']
- await diff.exec([])
+ await assertFoo(t, '0.1.0')
})
t.test('version, no package.json', async t => {
- const path = t.testdir({})
- npm.prefix = path
- config.diff = ['2.1.4']
- await t.rejects(
- diff.exec([]),
- /Needs multiple arguments to compare or run from a project dir./,
- 'should throw an error message explaining usage'
- )
+ await rejectDiff(t, /Needs multiple arguments to compare or run from a project dir./, {
+ diff: ['0.1.0'],
+ })
})
t.test('version, filtering by files', async t => {
- t.plan(3)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@2.1.4', 'should use expected spec')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(
- opts,
- {
- ...npm.flatOptions,
- diffFiles: ['./foo.js', './bar.js'],
- },
- 'should forward flatOptions and diffFiles'
- )
- }
-
- config.diff = ['2.1.4']
- await diff.exec(['./foo.js', './bar.js'])
+ const output = await assertFoo(t, { diff: '0.1.0', exec: ['./a.js', './b.js'] })
+ t.matchSnapshot(output)
})
t.test('spec is not a dep', async t => {
- t.plan(2)
-
- const path = t.testdir({
- node_modules: {},
- 'package.json': JSON.stringify({
- name: 'my-project',
- }),
+ const { output } = await mockDiff(t, {
+ diff: 'bar@1.0.0',
+ prefixDir: {
+ node_modules: {},
+ 'package.json': { name: 'my-project', version: '1.0.0' },
+ },
+ tarballs: {
+ 'bar@1.0.0': {},
+ },
+ exec: [],
})
- 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')
- }
-
- config.diff = ['bar@1.0.0']
- npm.prefix = path
-
- await diff.exec([])
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "my-project"/)
})
t.test('unknown package name', async t => {
- t.plan(3)
-
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ const { npm, registry } = await mockDiff(t, {
+ diff: 'bar',
+ prefixDir: {
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
})
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'simple-output@*', 'should forward single spec')
- t.equal(b, `file:${path}`, 'should compare to cwd')
- t.match(opts, npm.flatOptions, 'should forward flat options')
- }
-
- config.diff = ['simple-output']
- npm.prefix = path
- await diff.exec([])
+ registry.getPackage('bar', { times: 2, code: 404 })
+ t.rejects(npm.exec('diff', []), /404 Not Found.*bar/)
})
t.test('unknown package name, no package.json', async t => {
- const path = t.testdir({})
-
- config.diff = ['bar']
- npm.prefix = path
- await t.rejects(
- diff.exec([]),
- /Needs multiple arguments to compare or run from a project dir./,
- 'should throw usage error'
- )
+ const { npm } = await mockDiff(t, {
+ diff: 'bar',
+ })
+ t.rejects(npm.exec('diff', []),
+ /Needs multiple arguments to compare or run from a project dir./)
})
t.test('transform single direct dep name into spec comparison', async 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',
+ const { output } = await mockDiff(t, {
+ diff: 'bar',
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- }),
- })
-
- config.diff = ['bar']
- npm.prefix = path
-
- const Diff = t.mock('../../../lib/commands/diff.js', {
- ...mocks,
- pacote: {
- packument: spec => {
- t.equal(spec.name, 'bar', 'should have expected spec name')
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
},
- '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')
+ tarballs: {
+ 'bar@1.8.0': {},
},
+ times: { bar: 2 },
+ exec: [],
})
- const diff = new Diff(npm)
- await diff.exec([])
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "1\.8\.0"/)
})
t.test('global space, transform single direct dep name', async t => {
- t.plan(4)
-
- const path = t.testdir({
- globalDir: {
- lib: {
- node_modules: {
- lorem: {
- 'package.json': JSON.stringify({
- name: 'lorem',
- version: '2.0.0',
- }),
+ const { output } = await mockDiff(t, {
+ diff: 'lorem',
+ config: {
+ global: true,
+ },
+ globalPrefixDir: {
+ node_modules: {
+ lorem: {
+ 'package.json': {
+ name: 'lorem',
+ version: '2.0.0',
},
},
},
},
- project: {
+ prefixDir: {
node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ lorem: {
+ 'package.json': {
+ name: 'lorem',
+ version: '3.0.0',
+ },
},
},
- 'package.json': JSON.stringify({
+ 'package.json': {
name: 'my-project',
dependencies: {
- bar: '^1.0.0',
+ lorem: '^3.0.0',
},
- }),
- },
- })
-
- config.global = true
- flatOptions.global = true
- config.diff = ['lorem']
- npm.prefix = resolve(path, 'project')
- npm.globalDir = resolve(path, 'globalDir/lib/node_modules')
-
- const Diff = t.mock('../../../lib/commands/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' }
+ tarballs: {
+ 'lorem@1.0.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')
+ times: {
+ lorem: 2,
},
+ exec: [],
})
- const diff = new Diff(npm)
- await diff.exec([])
+ t.match(output, 'lorem')
+ t.match(output, /-\s*"version": "2\.0\.0"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
})
t.test('transform single spec into spec comparison', async t => {
- t.plan(2)
-
- const path = t.testdir({
- node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { output } = await mockDiff(t, {
+ diff: 'bar@2.0.0',
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar@2.0.0': {},
+ },
+ times: {
+ lorem: 2,
+ },
+ exec: [],
})
- 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')
- }
-
- config.diff = ['bar@2.0.0']
- npm.prefix = path
-
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('transform single spec from transitive deps', async 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',
+ const { output } = await mockDiff(t, {
+ diff: 'lorem',
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ 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',
+ },
+ lorem: {
+ 'package.json': {
+ name: 'lorem',
+ version: '2.0.0',
+ },
+ },
},
- }),
- })
-
- const Diff = t.mock('../../../lib/commands/diff.js', {
- ...mocks,
- pacote: {
- packument: spec => {
- t.equal(spec.name, 'lorem', 'should have expected spec name')
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
},
- 'npm-pick-manifest': (packument, target) => {
- t.equal(target, '^2.0.0', 'should target first semver-range spec found')
- return { version: '2.2.2' }
+ tarballs: {
+ 'lorem@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')
+ times: {
+ lorem: 2,
},
+ exec: [],
})
- const diff = new Diff(npm)
-
- config.diff = ['lorem']
- npm.prefix = path
- await diff.exec([])
+ t.match(output, 'lorem')
+ t.match(output, /-\s*"version": "2\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.2\.2"/)
})
t.test('missing actual tree', async t => {
- t.plan(2)
-
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'my-project',
- }),
- })
-
- const Diff = t.mock('../../../lib/commands/diff.js', {
- ...mocks,
- '@npmcli/arborist': class {
- constructor () {
- throw new Error('ERR')
- }
+ const { output } = await mockDiff(t, {
+ diff: 'lorem',
+ prefixDir: {
+ 'package.json': {
+ name: 'lorem',
+ version: '2.0.0',
+ },
+ },
+ mocks: {
+ '@npmcli/arborist': class {
+ constructor () {
+ throw new Error('ERR')
+ }
+ },
},
- libnpmdiff: async ([a, b], opts) => {
- t.equal(a, 'lorem@*', 'should target any version of pkg name')
- t.equal(b, `file:${path}`, 'should target current cwd')
+ tarballs: {
+ 'lorem@2.2.2': {},
},
+ exec: [],
})
- const diff = new Diff(npm)
- config.diff = ['lorem']
- npm.prefix = path
-
- await diff.exec([])
+ t.match(output, 'lorem')
+ t.match(output, /-\s*"version": "2\.2\.2"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('unknown package name', async t => {
- t.plan(2)
+ const { output } = await mockDiff(t, {
+ diff: 'bar',
+ prefixDir: {
+ 'package.json': { version: '1.0.0' },
+ },
- const path = t.testdir({
- 'package.json': JSON.stringify({ version: '1.0.0' }),
+ tarballs: {
+ 'bar@2.2.2': {},
+ },
+ exec: [],
})
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@*', 'should target any version of pkg name')
- t.equal(b, `file:${path}`, 'should compare to cwd')
- }
-
- config.diff = ['bar']
- npm.prefix = path
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "2\.2\.2"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
})
t.test('use project name in project dir', async t => {
- t.plan(2)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@*', 'should target any version of pkg name')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- }
+ const { output } = await mockDiff(t, {
+ diff: 'foo',
+ prefixDir: {
+ 'package.json': { name: 'foo', version: '1.0.0' },
+ },
+ tarballs: {
+ 'foo@2.2.2': {},
+ },
+ exec: [],
+ })
- config.diff = ['foo']
- await diff.exec([])
+ t.match(output, 'foo')
+ t.match(output, /-\s*"version": "2\.2\.2"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
})
t.test('dir spec type', async t => {
- t.plan(2)
-
- const otherPath = resolve('/path/to/other-dir')
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, `file:${otherPath}`, 'should target dir')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- }
+ const { output } = await mockDiff(t, {
+ diff: '../other/other-pkg',
+ prefixDir: {
+ 'package.json': { name: 'foo', version: '1.0.0' },
+ },
+ otherDirs: {
+ 'other-pkg': {
+ 'package.json': { name: 'foo', version: '2.0.0' },
+ },
+ },
+ exec: [],
+ })
- config.diff = [otherPath]
- await diff.exec([])
+ t.match(output, 'foo')
+ t.match(output, /-\s*"version": "2\.0\.0"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
})
t.test('unsupported spec type', async t => {
- config.diff = ['git+https://github.com/user/foo']
+ const p = mockDiff(t, {
+ diff: 'git+https://github.com/user/foo',
+ exec: [],
+ })
+
await t.rejects(
- diff.exec([]),
+ p,
/Spec type git not supported./,
'should throw spec type not supported error.'
)
})
-
- t.end()
})
-t.test('first arg is a qualified spec', t => {
+t.test('first arg is a qualified spec', async t => {
t.test('second arg is ALSO a qualified spec', async 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')
- }
+ const { output } = await mockDiff(t, {
+ diff: ['bar@1.0.0', 'bar@^2.0.0'],
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar@2.2.2': {},
+ },
+ times: {
+ bar: 2,
+ },
+ exec: [],
+ })
- config.diff = ['bar@1.0.0', 'bar@^2.0.0']
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.2\.2"/)
})
t.test('second arg is a known dependency name', async t => {
- t.plan(2)
-
- const path = t.testdir({
- node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar@2.0.0': {},
+ },
+ diff: ['bar@2.0.0', 'bar'],
+ exec: [],
})
- 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.prefix = path
- config.diff = ['bar@2.0.0', 'bar']
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "2\.0\.0"/)
+ t.match(output, /\+\s*"version": "1\.0\.0"/)
})
t.test('second arg is a valid semver version', async t => {
- t.plan(2)
-
- config.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')
- }
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar@2.0.0': {},
+ },
+ times: {
+ bar: 2,
+ },
+ diff: ['bar@1.0.0', '2.0.0'],
+ exec: [],
+ })
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is an unknown dependency name', async t => {
- t.plan(2)
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar-fork@2.0.0': {},
+ },
+ diff: ['bar@1.0.0', 'bar-fork'],
+ exec: [],
+ })
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@1.0.0', 'should set expected first spec')
- t.equal(b, 'bar-fork@*', 'should target any version if not a dep')
- }
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "bar-fork"/)
- config.diff = ['bar@1.0.0', 'bar-fork']
- await diff.exec([])
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
-
- t.end()
})
t.test('first arg is a known dependency name', async 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',
- }),
+ t.test('second arg is a qualified spec', async t => {
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar@2.0.0': {},
+ },
+ diff: ['bar', 'bar@2.0.0'],
+ exec: [],
})
- 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.prefix = path
- config.diff = ['bar', 'bar@2.0.0']
- diff.exec([], err => {
- if (err) {
- throw err
- }
- })
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
- 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',
- }),
+ t.test('second arg is ALSO a known dependency', async t => {
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
+ 'bar-fork': {
+ 'package.json': {
+ name: 'bar-fork',
+ version: '1.0.0',
+ },
+ },
},
- 'bar-fork': {
- 'package.json': JSON.stringify({
- name: 'bar-fork',
- version: '1.0.0',
- }),
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
},
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
- },
- }),
+ diff: ['bar', 'bar-fork'],
+ exec: [],
})
- 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.prefix = path
- config.diff = ['bar', 'bar-fork']
- diff.exec([], err => {
- if (err) {
- throw err
- }
- })
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "bar-fork"/)
})
- 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',
- }),
+ t.test('second arg is a valid semver version', async t => {
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar@2.0.0': {},
+ },
+ diff: ['bar', '2.0.0'],
+ exec: [],
})
- 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.prefix = path
- config.diff = ['bar', '2.0.0']
- diff.exec([], err => {
- if (err) {
- throw err
- }
- })
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is an unknown dependency name', async t => {
- t.plan(2)
-
- const path = t.testdir({
- node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '1.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar-fork@1.0.0': {},
+ },
+ diff: ['bar', 'bar-fork'],
+ exec: [],
})
- 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@*', 'should set expected second spec')
- }
-
- npm.prefix = path
- config.diff = ['bar', 'bar-fork']
- await diff.exec([])
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "bar-fork"/)
})
-
- t.end()
})
-t.test('first arg is a valid semver range', t => {
+t.test('first arg is a valid semver range', async t => {
t.test('second arg is a qualified spec', async t => {
- t.plan(2)
-
- config.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')
- }
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar@2.0.0': {},
+ },
+ diff: ['1.0.0', 'bar@2.0.0'],
+ times: { bar: 2 },
+ exec: [],
+ })
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is a known dependency', async t => {
- t.plan(2)
-
- const path = t.testdir({
- node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '2.0.0',
- }),
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '2.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar@1.0.0': {},
+ },
+ diff: ['1.0.0', 'bar'],
+ exec: [],
})
- 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.prefix = path
- config.diff = ['1.0.0', 'bar']
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is ALSO a semver version', async t => {
- t.plan(2)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@1.0.0', 'should use name from project dir')
- t.equal(b, 'foo@2.0.0', 'should use name from project dir')
- }
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ 'package.json': {
+ name: 'bar',
+ },
+ },
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar@2.0.0': {},
+ },
+ diff: ['1.0.0', '2.0.0'],
+ times: { bar: 2 },
+ exec: [],
+ })
- config.diff = ['1.0.0', '2.0.0']
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is ALSO a semver version BUT cwd not a project dir', async t => {
- const path = t.testdir({})
- config.diff = ['1.0.0', '2.0.0']
- npm.prefix = path
+ const p = mockDiff(t, {
+ diff: ['1.0.0', '2.0.0'],
+ exec: [],
+ })
await t.rejects(
- diff.exec([]),
+ p,
/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.test('second arg is an unknown dependency name', async t => {
- t.plan(2)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@1.0.0', 'should use name from second arg')
- t.equal(b, 'bar@*', 'should compare against any version')
- }
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ prefixDir: {
+ 'package.json': {
+ name: 'bar',
+ },
+ },
+ },
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar@2.0.0': {},
+ },
+ diff: ['1.0.0', 'bar'],
+ times: { bar: 2 },
+ exec: [],
+ })
- config.diff = ['1.0.0', 'bar']
- await diff.exec([])
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
t.test('second arg is a qualified spec, missing actual tree', async t => {
- t.plan(2)
-
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'my-project',
- }),
- })
-
- const Diff = t.mock('../../../lib/commands/diff.js', {
- ...mocks,
- '@npmcli/arborist': class {
- constructor () {
- throw new Error('ERR')
- }
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ 'package.json': {
+ name: 'lorem',
+ version: '2.0.0',
+ },
},
- 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')
+ mocks: {
+ '@npmcli/arborist': class {
+ constructor () {
+ throw new Error('ERR')
+ }
+ },
+ },
+ tarballs: {
+ 'lorem@1.0.0': {},
+ 'lorem@2.0.0': {},
},
+ times: { lorem: 2 },
+ diff: ['1.0.0', 'lorem@2.0.0'],
+ exec: [],
})
- const diff = new Diff(npm)
-
- config.diff = ['1.0.0', 'lorem@2.0.0']
- npm.prefix = path
- await diff.exec([])
+ t.match(output, 'lorem')
+ t.match(output, /-\s*"version": "1\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
})
-
- t.end()
})
-t.test('first arg is an unknown dependency name', t => {
- t.test('second arg is a qualified spec', t => {
- t.plan(4)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@*', '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')
- t.match(opts, { where: fooPath }, 'should forward pacote options')
- }
-
- config.diff = ['bar', 'bar@2.0.0']
- diff.exec([], err => {
- if (err) {
- throw err
- }
+t.test('first arg is an unknown dependency name', async t => {
+ t.test('second arg is a qualified spec', async t => {
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@2.0.0': {},
+ 'bar@3.0.0': {},
+ },
+ times: { bar: 2 },
+ diff: ['bar', 'bar@2.0.0'],
+ exec: [],
})
- })
- t.test('second arg is a known dependency', t => {
- t.plan(2)
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "3\.0\.0"/)
+ t.match(output, /\+\s*"version": "2\.0\.0"/)
+ })
- const path = t.testdir({
- node_modules: {
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '2.0.0',
- }),
+ t.test('second arg is a known dependency', async t => {
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ node_modules: {
+ bar: {
+ 'package.json': {
+ name: 'bar',
+ version: '2.0.0',
+ },
+ },
},
- },
- 'package.json': JSON.stringify({
- name: 'my-project',
- dependencies: {
- bar: '^1.0.0',
+ 'package.json': {
+ name: 'my-project',
+ dependencies: {
+ bar: '^1.0.0',
+ },
},
- }),
+ },
+ tarballs: {
+ 'bar-fork@2.0.0': {},
+ },
+ diff: ['bar-fork', 'bar'],
+ exec: [],
})
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar-fork@*', 'should use any version')
- t.equal(
- b,
- `bar@file:${resolve(path, 'node_modules/bar')}`,
- 'should target local node_modules pkg'
- )
- }
-
- npm.prefix = path
- config.diff = ['bar-fork', 'bar']
- diff.exec([], err => {
- if (err) {
- throw err
- }
- })
+ t.match(output, /-\s*"name": "bar-fork"/)
+ t.match(output, /\+\s*"name": "bar"/)
})
- t.test('second arg is a valid semver version', t => {
- t.plan(2)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@*', 'should use any version')
- t.equal(b, 'bar@^1.0.0', 'should use name from first arg')
- }
-
- config.diff = ['bar', '^1.0.0']
- diff.exec([], 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@*', 'should use any version')
- t.equal(b, 'bar-fork@*', 'should use any version')
- }
-
- config.diff = ['bar', 'bar-fork']
- diff.exec([], err => {
- if (err) {
- throw err
- }
+ t.test('second arg is a valid semver version', async t => {
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@1.5.0': {},
+ 'bar@2.0.0': {},
+ },
+ times: { bar: 2 },
+ diff: ['bar', '^1.0.0'],
+ exec: [],
})
- })
-
- t.test('cwd not a project dir', t => {
- t.plan(2)
- const path = t.testdir({})
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'bar@*', 'should use any version')
- t.equal(b, 'bar-fork@*', 'should use any version')
- }
-
- config.diff = ['bar', 'bar-fork']
- npm.prefix = path
-
- diff.exec([], err => {
- if (err) {
- throw err
- }
- })
+ t.match(output, 'bar')
+ t.match(output, /-\s*"version": "2\.0\.0"/)
+ t.match(output, /\+\s*"version": "1\.5\.0"/)
})
- t.end()
-})
-
-t.test('various options', t => {
- t.test('using --name-only option', async t => {
- t.plan(1)
-
- flatOptions.diffNameOnly = true
-
- libnpmdiff = async ([a, b], opts) => {
- t.match(
- opts,
- {
- ...npm.flatOptions,
- diffNameOnly: true,
+ t.test('second arg is ALSO an unknown dependency name', async t => {
+ const { output } = await mockDiff(t, {
+ prefixDir: {
+ 'package.json': {
+ name: 'my-project',
},
- 'should forward nameOnly=true option'
- )
- }
+ },
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar-fork@1.0.0': {},
+ },
+ diff: ['bar', 'bar-fork'],
+ exec: [],
+ })
- await diff.exec([])
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "bar-fork"/)
})
- t.test('set files after both versions', async t => {
- t.plan(3)
-
- config.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'
- )
- }
+ t.test('cwd not a project dir', async t => {
+ const { output } = await mockDiff(t, {
+ tarballs: {
+ 'bar@1.0.0': {},
+ 'bar-fork@1.0.0': {},
+ },
+ diff: ['bar', 'bar-fork'],
+ exec: [],
+ })
- await diff.exec(['./foo.js', './bar.js'])
+ t.match(output, /-\s*"name": "bar"/)
+ t.match(output, /\+\s*"name": "bar-fork"/)
})
+})
- t.test('set files no diff args', async t => {
- t.plan(3)
-
- libnpmdiff = async ([a, b], opts) => {
- t.equal(a, 'foo@latest', 'should have default spec')
- t.equal(b, `file:${fooPath}`, 'should compare to cwd')
- t.match(
- opts,
- {
- ...npm.flatOptions,
- diffFiles: ['./foo.js', './bar.js'],
- },
- 'should forward all remaining items as filenames'
- )
- }
+t.test('various options', async t => {
+ const mockOptions = async (t, config) => {
+ const file = (v) => new Array(50).fill(0).map((_, i) => `${i}${i === 20 ? v : ''}`).join('\n')
+ const mock = await mockDiff(t, {
+ diff: ['bar@2.0.0', 'bar@3.0.0'],
+ config,
+ exec: [],
+ tarballs: {
+ 'bar@2.0.0': { 'index.js': file('2.0.0') },
+ 'bar@3.0.0': { 'index.js': file('3.0.0') },
+ },
+ times: { bar: 2 },
+ })
+
+ return mock
+ }
- await diff.exec(['./foo.js', './bar.js'])
+ t.test('using --name-only option', async t => {
+ const { output } = await mockOptions(t, {
+ 'diff-name-only': true,
+ })
+ t.matchSnapshot(output)
})
t.test('using diff option', async t => {
- t.plan(1)
-
- flatOptions.diffContext = 5
- flatOptions.diffIgnoreWhitespace = true
- flatOptions.diffNoPrefix = false
- flatOptions.diffSrcPrefix = 'foo/'
- flatOptions.diffDstPrefix = 'bar/'
- 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'
- )
- }
+ const { output } = await mockOptions(t, {
+ 'diff-context': 5,
+ 'diff-ignore-whitespace': true,
+ 'diff-no-prefix': false,
+ 'diff-drc-prefix': 'foo/',
+ 'diff-fst-prefix': 'bar/',
+ 'diff-text': true,
- await diff.exec([])
+ })
+ t.matchSnapshot(output)
})
-
- t.end()
})
t.test('too many args', async t => {
- config.diff = ['a', 'b', 'c']
+ const { npm } = await mockDiff(t, {
+ diff: ['a', 'b', 'c'],
+ })
+
await t.rejects(
- diff.exec([]),
+ npm.exec('diff', []),
/Can't use more than two --diff arguments./,
'should throw usage error'
)
})
-t.test('workspaces', t => {
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'workspaces-test',
- version: '1.2.3-test',
- workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
- }),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.2.3-a',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.2.3-b',
- }),
- },
- 'workspace-c': JSON.stringify({
+t.test('workspaces', async t => {
+ const mockWorkspaces = (t, workspaces = true, opts) => mockDiff(t, {
+ prefixDir: {
'package.json': {
- name: 'workspace-n',
- version: '1.2.3-n',
+ name: 'workspaces-test',
+ version: '1.2.3',
+ workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
},
- }),
+ 'workspace-a': {
+ 'package.json': {
+ name: 'workspace-a',
+ version: '1.2.3-a',
+ },
+ },
+ 'workspace-b': {
+ 'package.json': {
+ name: 'workspace-b',
+ version: '1.2.3-b',
+ },
+ },
+ 'workspace-c': {
+ 'package.json': {
+ name: 'workspace-c',
+ version: '1.2.3-c',
+ },
+ },
+ },
+ exec: [],
+ config: workspaces === true ? { workspaces } : { workspace: workspaces },
+ ...opts,
})
t.test('all workspaces', async t => {
- const diffCalls = []
- libnpmdiff = async ([a, b]) => {
- diffCalls.push([a, b])
- }
- npm.prefix = path
- npm.localPrefix = path
- await diff.execWorkspaces([], [])
- t.same(
- diffCalls,
- [
- ['workspace-a@latest', join(`file:${path}`, 'workspace-a')],
- ['workspace-b@latest', join(`file:${path}`, 'workspace-b')],
- ],
- 'should call libnpmdiff with workspaces params'
- )
+ const { output } = await mockWorkspaces(t, true, {
+ tarballs: {
+ 'workspace-a@2.0.0-a': {},
+ 'workspace-b@2.0.0-b': {},
+ 'workspace-c@2.0.0-c': {},
+ },
+ })
+
+ t.match(output, '"name": "workspace-a"')
+ t.match(output, /-\s*"version": "2\.0\.0-a"/)
+ t.match(output, /\+\s*"version": "1\.2\.3-a"/)
+
+ t.match(output, '"name": "workspace-b"')
+ t.match(output, /-\s*"version": "2\.0\.0-b"/)
+ t.match(output, /\+\s*"version": "1\.2\.3-b"/)
+
+ t.match(output, '"name": "workspace-c"')
+ t.match(output, /-\s*"version": "2\.0\.0-c"/)
+ t.match(output, /\+\s*"version": "1\.2\.3-c"/)
})
t.test('one workspace', async t => {
- const diffCalls = []
- libnpmdiff = async ([a, b]) => {
- diffCalls.push([a, b])
- }
- npm.prefix = path
- npm.localPrefix = path
- await diff.execWorkspaces([], ['workspace-a'])
- t.same(
- diffCalls,
- [['workspace-a@latest', join(`file:${path}`, 'workspace-a')]],
- 'should call libnpmdiff with workspaces params'
- )
+ const { output } = await mockWorkspaces(t, 'workspace-a', {
+ tarballs: {
+ 'workspace-a@2.0.0-a': {},
+ },
+ })
+
+ t.match(output, '"name": "workspace-a"')
+ t.match(output, /-\s*"version": "2\.0\.0-a"/)
+ t.match(output, /\+\s*"version": "1\.2\.3-a"/)
+
+ t.notMatch(output, '"name": "workspace-b"')
+ t.notMatch(output, '"name": "workspace-c"')
})
t.test('invalid workspace', async t => {
- libnpmdiff = () => {
- t.fail('should not call libnpmdiff')
- }
- npm.prefix = path
- npm.localPrefix = path
- await t.rejects(diff.execWorkspaces([], ['workspace-x']), /No workspaces found/)
- await t.rejects(diff.execWorkspaces([], ['workspace-x']), /workspace-x/)
+ const p = mockWorkspaces(t, 'workspace-x')
+ await t.rejects(p, /No workspaces found/)
+ await t.rejects(p, /workspace-x/)
})
- t.end()
})
diff --git a/deps/npm/test/lib/commands/dist-tag.js b/deps/npm/test/lib/commands/dist-tag.js
index 464f5bc939..4cc241f745 100644
--- a/deps/npm/test/lib/commands/dist-tag.js
+++ b/deps/npm/test/lib/commands/dist-tag.js
@@ -1,15 +1,36 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const realFetch = require('npm-registry-fetch')
+const mockNpm = require('../../fixtures/mock-npm')
-let result = ''
-let log = ''
-
-t.afterEach(() => {
- result = ''
- log = ''
-})
+const fixtures = {
+ workspace: {
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
+ }),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-c': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-c',
+ version: '1.0.0',
+ }),
+ },
+ },
+}
-const routeMap = {
+const tags = {
'/-/package/@scoped%2fpkg/dist-tags': {
latest: '1.0.0',
a: '0.0.1',
@@ -40,67 +61,70 @@ const routeMap = {
},
}
-// XXX overriding this does not appear to do anything, adding t.plan to things
-// that use it fails the test
-let npmRegistryFetchMock = (url, opts) => {
- if (url === '/-/package/foo/dist-tags') {
- throw new Error('no package found')
- }
+const mockDist = async (t, { ...npmOpts } = {}) => {
+ const getTag = async (url) => ({ ...tags })[url]
- return routeMap[url]
-}
+ let fetchOpts
+ const nrf = async (url, opts) => {
+ fetchOpts = opts
-npmRegistryFetchMock.json = async (url, opts) => {
- return routeMap[url]
-}
+ if (url === '/-/package/foo/dist-tags') {
+ throw new Error('no package found')
+ }
-const logger = (...msgs) => {
- for (const msg of [...msgs]) {
- log += msg + ' '
+ return getTag(url)
}
- log += '\n'
-}
+ const mock = await mockNpm(t, {
+ ...npmOpts,
+ mocks: {
+ 'npm-registry-fetch': Object.assign(nrf, realFetch, { json: getTag }),
+ },
+ })
-const DistTag = t.mock('../../../lib/commands/dist-tag.js', {
- 'proc-log': {
- error: logger,
- info: logger,
- verbose: logger,
- warn: logger,
- },
- get 'npm-registry-fetch' () {
- return npmRegistryFetchMock
- },
-})
+ const usage = await mock.npm.cmd('dist-tag').then(c => c.usage)
-const config = {}
-const npm = mockNpm({
- config,
- output: msg => {
- result = result ? [result, msg].join('\n') : msg
- },
-})
-const distTag = new DistTag(npm)
+ return {
+ ...mock,
+ distTag: {
+ exec: (args) => mock.npm.exec('dist-tag', args),
+ usage,
+ completion: (remain) => mock.npm.cmd('dist-tag').then(c => c.completion({
+ conf: { argv: { remain } },
+ })),
+ },
+ fetchOpts: () => fetchOpts,
+ result: () => mock.joinedOutput(),
+ logs: () => {
+ const distLogs = mock.logs.filter(l => l[1].startsWith('dist-tag'))
+ return distLogs.map(([, ...parts]) => {
+ return parts.map(p => p.toString()).join(' ').trim()
+ }).join('\n').trim()
+ },
+ }
+}
t.test('ls in current package', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: '@scoped/pkg',
- }),
+ const { distTag, result } = await mockDist(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: '@scoped/pkg',
+ }),
+ },
})
await distTag.exec(['ls'])
t.matchSnapshot(
- result,
+ result(),
'should list available tags for current package'
)
})
t.test('ls global', async t => {
- t.teardown(() => {
- config.global = false
+ const { distTag } = await mockDist(t, {
+ config: {
+ global: true,
+ },
})
- config.global = true
await t.rejects(
distTag.exec(['ls']),
distTag.usage,
@@ -109,20 +133,22 @@ t.test('ls global', async t => {
})
t.test('no args in current package', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: '@scoped/pkg',
- }),
+ const { distTag, result } = await mockDist(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: '@scoped/pkg',
+ }),
+ },
})
await distTag.exec([])
t.matchSnapshot(
- result,
+ result(),
'should default to listing available tags for current package'
)
})
t.test('borked cmd usage', async t => {
- npm.prefix = t.testdir({})
+ const { distTag } = await mockDist(t)
await t.rejects(
distTag.exec(['borked', '@scoped/pkg']),
distTag.usage,
@@ -131,31 +157,33 @@ t.test('borked cmd usage', async t => {
})
t.test('ls on named package', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, result } = await mockDist(t)
await distTag.exec(['ls', '@scoped/another'])
t.matchSnapshot(
- result,
+ result(),
'should list tags for the specified package'
)
})
t.test('ls on missing package', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, logs } = await mockDist(t)
await t.rejects(
distTag.exec(['ls', 'foo']),
distTag.usage
)
t.matchSnapshot(
- log,
+ logs(),
'should log no dist-tag found msg'
)
})
t.test('ls on missing name in current package', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- version: '1.0.0',
- }),
+ const { distTag } = await mockDist(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ version: '1.0.0',
+ }),
+ },
})
await t.rejects(
distTag.exec(['ls']),
@@ -165,107 +193,78 @@ t.test('ls on missing name in current package', async t => {
})
t.test('only named package arg', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, result } = await mockDist(t)
await distTag.exec(['@scoped/another'])
t.matchSnapshot(
- result,
+ result(),
'should default to listing tags for the specified package'
)
})
-t.test('workspaces', t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
- }),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
- },
- 'workspace-c': {
- 'package.json': JSON.stringify({
- name: 'workspace-c',
- version: '1.0.0',
- }),
- },
- })
+t.test('workspaces', async t => {
+ const mockWorkspaces = async (t, exec = [], workspaces = true, prefixDir = {}) => {
+ const mock = await mockDist(t, {
+ prefixDir: {
+ ...fixtures.workspace,
+ ...prefixDir,
+ },
+ config: workspaces === true ? { workspaces } : { workspace: workspaces },
+ })
+
+ await mock.distTag.exec(exec)
+
+ return mock
+ }
t.test('no args', async t => {
- await distTag.execWorkspaces([], [])
- t.matchSnapshot(result, 'printed the expected output')
+ const { result } = await mockWorkspaces(t)
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('no args, one workspace', async t => {
- await distTag.execWorkspaces([], ['workspace-a'])
- t.matchSnapshot(result, 'printed the expected output')
+ const { result } = await mockWorkspaces(t, [], 'workspace-a')
+ t.matchSnapshot(result(), 'printed the expected output')
})
- t.test('one arg -- .', async t => {
- await distTag.execWorkspaces(['.'], [])
- t.matchSnapshot(result, 'printed the expected output')
+ t.test('one arg -- cwd', async t => {
+ const { result } = await mockWorkspaces(t, ['.'])
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('one arg -- .@1, ignores version spec', async t => {
- await distTag.execWorkspaces(['.@'], [])
- t.matchSnapshot(result, 'printed the expected output')
+ const { result } = await mockWorkspaces(t, ['.@'])
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('one arg -- list', async t => {
- await distTag.execWorkspaces(['list'], [])
- t.matchSnapshot(result, 'printed the expected output')
+ const { result } = await mockWorkspaces(t, ['list'])
+ t.matchSnapshot(result(), 'printed the expected output')
})
- t.test('two args -- list, .', async t => {
- await distTag.execWorkspaces(['list', '.'], [])
- t.matchSnapshot(result, 'printed the expected output')
+ t.test('two args -- list, cwd', async t => {
+ const { result } = await mockWorkspaces(t, ['list', '.'])
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('two args -- list, .@1, ignores version spec', async t => {
- await distTag.execWorkspaces(['list', '.@'], [])
- t.matchSnapshot(result, 'printed the expected output')
+ const { result } = await mockWorkspaces(t, ['list', '.@'])
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('two args -- list, @scoped/pkg, logs a warning and ignores workspaces', async t => {
- await distTag.execWorkspaces(['list', '@scoped/pkg'], [])
- t.match(log, 'Ignoring workspaces for specified package', 'logs a warning')
- t.matchSnapshot(result, 'printed the expected output')
+ const { result, logs } = await mockWorkspaces(t, ['list', '@scoped/pkg'])
+ t.match(logs(), 'Ignoring workspaces for specified package', 'logs a warning')
+ t.matchSnapshot(result(), 'printed the expected output')
})
t.test('no args, one failing workspace sets exitCode to 1', async t => {
- npm.localPrefix = t.testdir({
+ const { result, logs } = await mockWorkspaces(t, [], true, {
'package.json': JSON.stringify({
name: 'root',
version: '1.0.0',
workspaces: ['workspace-a', 'workspace-b', 'workspace-c', 'workspace-d'],
}),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
- },
- 'workspace-c': {
- 'package.json': JSON.stringify({
- name: 'workspace-c',
- version: '1.0.0',
- }),
- },
+
'workspace-d': {
'package.json': JSON.stringify({
name: 'workspace-d',
@@ -274,52 +273,41 @@ t.test('workspaces', t => {
},
})
- await distTag.execWorkspaces([], [])
- t.equal(process.exitCode, 1, 'set the error status')
- process.exitCode = 0
- t.match(log, 'dist-tag ls Couldn\'t get dist-tag data for workspace-d@*', 'logs the error')
- t.matchSnapshot(result, 'printed the expected output')
+ t.match(logs(), 'dist-tag ls Couldn\'t get dist-tag data for workspace-d@*', 'logs the error')
+ t.matchSnapshot(result(), 'printed the expected output')
})
-
- t.end()
})
t.test('add new tag', async t => {
- const _nrf = npmRegistryFetchMock
- t.teardown(() => {
- npmRegistryFetchMock = _nrf
- })
-
- npmRegistryFetchMock = async (url, opts) => {
- t.equal(opts.method, 'PUT', 'should trigger request to add new tag')
- t.equal(opts.body, '7.7.7', 'should point to expected version')
- }
- npm.prefix = t.testdir({})
+ const { distTag, result, fetchOpts } = await mockDist(t)
await distTag.exec(['add', '@scoped/another@7.7.7', 'c'])
+ const opts = fetchOpts()
+ t.equal(opts.method, 'PUT', 'should trigger request to add new tag')
+ t.equal(opts.body, '"7.7.7"', 'should point to expected version')
t.matchSnapshot(
- result,
+ result(),
'should return success msg'
)
})
t.test('add using valid semver range as name', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, logs } = await mockDist(t)
await t.rejects(
distTag.exec(['add', '@scoped/another@7.7.7', '1.0.0']),
/Tag name must not be a valid SemVer range: 1.0.0/,
'should exit with semver range error'
)
t.matchSnapshot(
- log,
+ logs(),
'should return success msg'
)
})
t.test('add missing args', async t => {
- npm.prefix = t.testdir({})
- config.tag = ''
- t.teardown(() => {
- delete config.tag
+ const { distTag } = await mockDist(t, {
+ config: {
+ tag: '',
+ },
})
await t.rejects(
distTag.exec(['add', '@scoped/another@7.7.7']),
@@ -329,7 +317,7 @@ t.test('add missing args', async t => {
})
t.test('add missing pkg name', async t => {
- npm.prefix = t.testdir({})
+ const { distTag } = await mockDist(t)
await t.rejects(
distTag.exec(['add', null]),
distTag.usage,
@@ -338,41 +326,35 @@ t.test('add missing pkg name', async t => {
})
t.test('set existing version', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, logs } = await mockDist(t)
await distTag.exec(['set', '@scoped/another@0.6.0', 'b'])
t.matchSnapshot(
- log,
+ logs(),
'should log warn msg'
)
})
t.test('remove existing tag', async t => {
- const _nrf = npmRegistryFetchMock
- t.teardown(() => {
- npmRegistryFetchMock = _nrf
- })
-
- npmRegistryFetchMock = async (url, opts) => {
- t.equal(opts.method, 'DELETE', 'should trigger request to remove tag')
- }
- npm.prefix = t.testdir({})
+ const { distTag, result, logs, fetchOpts } = await mockDist(t)
await distTag.exec(['rm', '@scoped/another', 'c'])
- t.matchSnapshot(log, 'should log remove info')
- t.matchSnapshot(result, 'should return success msg')
+ const opts = fetchOpts()
+ t.equal(opts.method, 'DELETE', 'should trigger request to remove tag')
+ t.matchSnapshot(logs(), 'should log remove info')
+ t.matchSnapshot(result(), 'should return success msg')
})
t.test('remove non-existing tag', async t => {
- npm.prefix = t.testdir({})
+ const { distTag, logs } = await mockDist(t)
await t.rejects(
distTag.exec(['rm', '@scoped/another', 'nonexistent']),
/nonexistent is not a dist-tag on @scoped\/another/,
'should exit with error'
)
- t.matchSnapshot(log, 'should log error msg')
+ t.matchSnapshot(logs(), 'should log error msg')
})
t.test('remove missing pkg name', async t => {
- npm.prefix = t.testdir({})
+ const { distTag } = await mockDist(t)
await t.rejects(
distTag.exec(['rm', null]),
distTag.usage,
@@ -381,14 +363,12 @@ t.test('remove missing pkg name', async t => {
})
t.test('completion', async t => {
- const { completion } = distTag
- t.plan(2)
+ const { distTag } = await mockDist(t)
- const match = completion({ conf: { argv: { remain: ['npm', 'dist-tag'] } } })
+ const match = distTag.completion(['npm', 'dist-tag'])
t.resolveMatch(match, ['add', 'rm', 'ls'],
'should list npm dist-tag commands for completion')
- const noMatch = completion({ conf: { argv: { remain: ['npm', 'dist-tag', 'foobar'] } } })
+ const noMatch = distTag.completion(['npm', 'dist-tag', 'foobar'])
t.resolveMatch(noMatch, [])
- t.end()
})
diff --git a/deps/npm/test/lib/commands/docs.js b/deps/npm/test/lib/commands/docs.js
index b2a65786bf..e11df6b07b 100644
--- a/deps/npm/test/lib/commands/docs.js
+++ b/deps/npm/test/lib/commands/docs.js
@@ -1,46 +1,48 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm.js')
-const { join, sep } = require('path')
+const mockNpm = require('../../fixtures/mock-npm.js')
+const { sep } = require('path')
-const pkgDirs = t.testdir({
- 'package.json': JSON.stringify({
- name: 'thispkg',
- version: '1.2.3',
- homepage: 'https://example.com',
- }),
- nodocs: {
+const fixtures = {
+ pkg: {
'package.json': JSON.stringify({
- name: 'nodocs',
+ name: 'thispkg',
version: '1.2.3',
+ homepage: 'https://example.com',
}),
- },
- docsurl: {
- 'package.json': JSON.stringify({
- name: 'docsurl',
- version: '1.2.3',
- homepage: 'https://bugzilla.localhost/docsurl',
- }),
- },
- repourl: {
- 'package.json': JSON.stringify({
- name: 'repourl',
- version: '1.2.3',
- repository: 'https://github.com/foo/repourl',
- }),
- },
- repoobj: {
- 'package.json': JSON.stringify({
- name: 'repoobj',
- version: '1.2.3',
- repository: { url: 'https://github.com/foo/repoobj' },
- }),
- },
- repourlobj: {
- 'package.json': JSON.stringify({
- name: 'repourlobj',
- version: '1.2.3',
- repository: { url: { works: false } },
- }),
+ nodocs: {
+ 'package.json': JSON.stringify({
+ name: 'nodocs',
+ version: '1.2.3',
+ }),
+ },
+ docsurl: {
+ 'package.json': JSON.stringify({
+ name: 'docsurl',
+ version: '1.2.3',
+ homepage: 'https://bugzilla.localhost/docsurl',
+ }),
+ },
+ repourl: {
+ 'package.json': JSON.stringify({
+ name: 'repourl',
+ version: '1.2.3',
+ repository: 'https://github.com/foo/repourl',
+ }),
+ },
+ repoobj: {
+ 'package.json': JSON.stringify({
+ name: 'repoobj',
+ version: '1.2.3',
+ repository: { url: 'https://github.com/foo/repoobj' },
+ }),
+ },
+ repourlobj: {
+ 'package.json': JSON.stringify({
+ name: 'repourlobj',
+ version: '1.2.3',
+ repository: { url: { works: false } },
+ }),
+ },
},
workspaces: {
'package.json': JSON.stringify({
@@ -69,26 +71,31 @@ const pkgDirs = t.testdir({
},
}),
},
-})
-
-// keep a tally of which urls got opened
-let opened = {}
-const openUrl = async (npm, url, errMsg) => {
- opened[url] = opened[url] || 0
- opened[url]++
}
-const Docs = t.mock('../../../lib/commands/docs.js', {
- '../../../lib/utils/open-url.js': openUrl,
-})
-const flatOptions = {}
-const npm = mockNpm({ flatOptions })
-const docs = new Docs(npm)
+const setup = async (t, { prefixDir = fixtures.pkg, config } = {}) => {
+ // keep a tally of which urls got opened
+ const opened = {}
+ const openUrl = async (_, url) => {
+ opened[url] = opened[url] || 0
+ opened[url]++
+ }
-t.afterEach(() => opened = {})
+ const res = await mockNpm(t, {
+ prefixDir,
+ mocks: {
+ '{LIB}/utils/open-url.js': openUrl,
+ },
+ config,
+ })
+
+ return {
+ ...res,
+ opened,
+ }
+}
-t.test('open docs urls', t => {
- npm.localPrefix = pkgDirs
+t.test('open docs urls', async t => {
const expect = {
nodocs: 'https://www.npmjs.com/package/nodocs',
docsurl: 'https://bugzilla.localhost/docsurl',
@@ -97,51 +104,60 @@ t.test('open docs urls', t => {
repourlobj: 'https://www.npmjs.com/package/repourlobj',
'.': 'https://example.com',
}
- const keys = Object.keys(expect)
- t.plan(keys.length)
- keys.forEach(pkg => {
- t.test(pkg, async t => {
- await docs.exec([['.', pkg].join(sep)])
- const url = expect[pkg]
- t.match({
- [url]: 1,
- }, opened, `opened ${url}`, { opened })
+
+ for (const [key, url] of Object.entries(expect)) {
+ await t.test(`open ${key} url`, async t => {
+ const { npm, opened } = await setup(t)
+ await npm.exec('docs', [['.', key].join(sep)])
+ t.strictSame({ [url]: 1 }, opened, `opened ${url}`)
})
- })
+ }
})
t.test('open default package if none specified', async t => {
- await docs.exec([])
- t.equal(opened['https://example.com'], 1, 'opened expected url', { opened })
+ const { npm, opened } = await setup(t)
+
+ await npm.exec('docs', [])
+ t.strictSame({ 'https://example.com': 1 }, opened, 'opened expected url')
})
-t.test('workspaces', (t) => {
- npm.localPrefix = join(pkgDirs, 'workspaces')
- t.test('all workspaces', async t => {
- await docs.execWorkspaces([], [])
- t.match({
+t.test('workspaces', async (t) => {
+ await t.test('all workspaces', async t => {
+ const { npm, opened } = await setup(t, {
+ prefixDir: fixtures.workspaces,
+ config: { workspaces: true },
+ })
+ await npm.exec('docs', [])
+ t.strictSame({
'http://docs.workspace-a/': 1,
'https://github.com/npm/workspace-b#readme': 1,
}, opened, 'opened two valid docs urls')
})
- t.test('one workspace', async t => {
- await docs.execWorkspaces([], ['workspace-a'])
- t.match({
+ await t.test('one workspace', async t => {
+ const { npm, opened } = await setup(t, {
+ prefixDir: fixtures.workspaces,
+ config: { workspace: 'workspace-a' },
+ })
+ await npm.exec('docs', [])
+ t.strictSame({
'http://docs.workspace-a/': 1,
}, opened, 'opened one requested docs urls')
})
- t.test('invalid workspace', async t => {
+ await t.test('invalid workspace', async t => {
+ const { npm, opened } = await setup(t, {
+ prefixDir: fixtures.workspaces,
+ config: { workspace: 'workspace-x' },
+ })
await t.rejects(
- docs.execWorkspaces([], ['workspace-x']),
+ npm.exec('docs', []),
/No workspaces found/
)
await t.rejects(
- docs.execWorkspaces([], ['workspace-x']),
+ npm.exec('docs', []),
/workspace-x/
)
t.match({}, opened, 'opened no docs urls')
})
- t.end()
})
diff --git a/deps/npm/test/lib/commands/doctor.js b/deps/npm/test/lib/commands/doctor.js
index a4602183e6..d1a88299e6 100644
--- a/deps/npm/test/lib/commands/doctor.js
+++ b/deps/npm/test/lib/commands/doctor.js
@@ -46,10 +46,7 @@ const dirs = {
},
globalPrefixDir: {
bin: {},
- lib: {
- node_modules: {
- },
- },
+ node_modules: {},
},
}
@@ -57,26 +54,25 @@ const globals = ({ globalPrefix }) => {
return {
process: {
'env.PATH': `${globalPrefix}:${path.join(globalPrefix, 'bin')}`,
- platform: 'test-not-windows',
version: 'v1.0.0',
},
}
}
-// getuid and getgid do not exist in windows, so we shim them
-// to return 0, as that is the value that lstat will assign the
-// gid and uid properties for fs.Stats objects
-if (process.platform === 'win32') {
- mockGlobals(t, {
- process: {
- getuid: () => 0,
- getgid: () => 0,
- },
- })
-}
+mockGlobals(t, {
+ process: {
+ // set platform to not-windows before any tests because mockNpm
+ // sets the platform specific location of node_modules based on it
+ platform: 'test-not-windows',
+ // getuid and getgid do not exist in windows, so we shim them
+ // to return 0, as that is the value that lstat will assign the
+ // gid and uid properties for fs.Stats objects
+ ...(process.platform === 'win32' ? { getuid: () => 0, getgid: () => 0 } : {}),
+ },
+})
const mocks = {
- '../../package.json': { version: '1.0.0' },
+ '{ROOT}/package.json': { version: '1.0.0' },
which: async () => '/path/to/git',
cacache: {
verify: () => {
@@ -106,13 +102,15 @@ t.test('all clear in color', async t => {
mocks,
globals,
...dirs,
+ config: {
+ color: 'always',
+ },
})
tnock(t, npm.config.get('registry'))
.get('/-/ping?write=true').reply(200, '{}')
.get('/npm').reply(200, npmManifest(npm.version))
tnock(t, 'https://nodejs.org')
.get('/dist/index.json').reply(200, nodeVersions)
- npm.config.set('color', 'always')
await npm.exec('doctor', [])
t.matchSnapshot(joinedOutput(), 'everything is ok in color')
t.matchSnapshot({ info: logs.info, warn: logs.warn, error: logs.error }, 'logs')
@@ -178,13 +176,15 @@ t.test('ping 404 in color', async t => {
mocks,
globals,
...dirs,
+ config: {
+ color: 'always',
+ },
})
tnock(t, npm.config.get('registry'))
.get('/-/ping?write=true').reply(404, '{}')
.get('/npm').reply(200, npmManifest(npm.version))
tnock(t, 'https://nodejs.org')
.get('/dist/index.json').reply(200, nodeVersions)
- npm.config.set('color', 'always')
await t.rejects(npm.exec('doctor', []))
t.matchSnapshot(joinedOutput(), 'ping 404 in color')
t.matchSnapshot({ info: logs.info, warn: logs.warn, error: logs.error }, 'logs')
@@ -247,7 +247,6 @@ t.test('node out of date - lts', async t => {
...g,
process: {
...g.process,
- platform: 'test-not-windows',
version: 'v0.0.1',
},
}
@@ -358,6 +357,7 @@ t.test('missing global directories', async t => {
mocks,
globals,
prefixDir: dirs.prefixDir,
+ globalPrefixDir: {},
})
tnock(t, npm.config.get('registry'))
.get('/-/ping?write=true').reply(200, '{}')
diff --git a/deps/npm/test/lib/commands/edit.js b/deps/npm/test/lib/commands/edit.js
index dc71148929..02621f1aef 100644
--- a/deps/npm/test/lib/commands/edit.js
+++ b/deps/npm/test/lib/commands/edit.js
@@ -9,7 +9,7 @@ const npmConfig = {
config: {
'ignore-scripts': false,
editor: 'testeditor',
- scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
+ 'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
},
prefixDir: {
node_modules: {
@@ -38,7 +38,7 @@ t.test('npm edit', async t => {
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
spawk.spawn('testeditor', [semverPath])
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'testinstall']
: ['-c', 'testinstall']
@@ -54,7 +54,7 @@ t.test('rebuild failure', async t => {
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
spawk.spawn('testeditor', [semverPath])
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'testinstall']
: ['-c', 'testinstall']
@@ -89,7 +89,7 @@ t.test('npm edit editor has flags', async t => {
const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
spawk.spawn('testeditor', ['--flag', semverPath])
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'testinstall']
: ['-c', 'testinstall']
diff --git a/deps/npm/test/lib/commands/exec.js b/deps/npm/test/lib/commands/exec.js
index 1a03b1a2e6..2fd11f4037 100644
--- a/deps/npm/test/lib/commands/exec.js
+++ b/deps/npm/test/lib/commands/exec.js
@@ -38,9 +38,6 @@ t.test('registry package', async t => {
require('fs').writeFileSync('npm-exec-test-success', '')`,
},
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await registry.package({
@@ -75,9 +72,6 @@ t.test('--prefix', async t => {
require('fs').writeFileSync('npm-exec-test-success', '')`,
},
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
// This is what `--prefix` does
@@ -125,9 +119,6 @@ t.test('workspaces', async t => {
}),
},
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await registry.package({ manifest,
diff --git a/deps/npm/test/lib/commands/explain.js b/deps/npm/test/lib/commands/explain.js
index 71bb175220..3262dfdce8 100644
--- a/deps/npm/test/lib/commands/explain.js
+++ b/deps/npm/test/lib/commands/explain.js
@@ -1,37 +1,33 @@
const t = require('tap')
-const npm = {
- prefix: null,
- color: true,
- flatOptions: { workspacesEnabled: true },
- output: (...args) => {
- OUTPUT.push(args)
- },
- config: {
- validate: () => {},
- get: (key) => {
- if (key === 'location') {
- return 'project'
- }
- },
- isDefault: () => {},
- },
-}
const { resolve } = require('path')
+const mockNpm = require('../../fixtures/mock-npm.js')
-const OUTPUT = []
+const mockExplain = async (t, opts) => {
+ const mock = await mockNpm(t, {
+ mocks: {
+ // keep the snapshots pared down a bit, since this has its own tests.
+ '{LIB}/utils/explain-dep.js': {
+ explainNode: (expl, depth, color) => {
+ return `${expl.name}@${expl.version} depth=${depth} color=${color}`
+ },
+ },
+ },
+ ...opts,
+ })
-const Explain = t.mock('../../../lib/commands/explain.js', {
+ const usage = await mock.npm.cmd('explain').then(c => c.usage)
- // keep the snapshots pared down a bit, since this has its own tests.
- '../../../lib/utils/explain-dep.js': {
- explainNode: (expl, depth, color) => {
- return `${expl.name}@${expl.version} depth=${depth} color=${color}`
+ return {
+ ...mock,
+ explain: {
+ usage,
+ exec: (args) => mock.npm.exec('explain', args),
},
- },
-})
-const explain = new Explain(npm)
+ }
+}
t.test('no args throws usage', async t => {
+ const { explain } = await mockExplain(t)
await t.rejects(
explain.exec([]),
explain.usage
@@ -39,7 +35,7 @@ t.test('no args throws usage', async t => {
})
t.test('no match throws not found', async t => {
- npm.prefix = t.testdir()
+ const { explain } = await mockExplain(t)
await t.rejects(
explain.exec(['foo@1.2.3', 'node_modules/baz']),
'No dependencies found matching foo@1.2.3, node_modules/baz'
@@ -47,7 +43,7 @@ t.test('no match throws not found', async t => {
})
t.test('invalid package name throws not found', async t => {
- npm.prefix = t.testdir()
+ const { explain } = await mockExplain(t)
const badName = ' not a valid package name '
await t.rejects(
explain.exec([`${badName}@1.2.3`]),
@@ -55,96 +51,106 @@ t.test('invalid package name throws not found', async t => {
)
})
-t.test('explain some nodes', t => {
- t.afterEach(() => {
- OUTPUT.length = 0
- npm.flatOptions.json = false
- })
-
- npm.prefix = t.testdir({
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.2.3',
- dependencies: {
- bar: '*',
- },
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.2.3',
- }),
- },
- baz: {
- 'package.json': JSON.stringify({
- name: 'baz',
- version: '1.2.3',
- dependencies: {
- foo: '*',
- bar: '2',
- },
- }),
+t.test('explain some nodes', async t => {
+ const mockNodes = async (t, config = {}) => {
+ const mock = await mockExplain(t, {
+ prefixDir: {
node_modules: {
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.2.3',
+ dependencies: {
+ bar: '*',
+ },
+ }),
+ },
bar: {
'package.json': JSON.stringify({
name: 'bar',
- version: '2.3.4',
+ version: '1.2.3',
}),
},
- extra: {
+ baz: {
'package.json': JSON.stringify({
- name: 'extra',
- version: '99.9999.999999',
- description: 'extraneous package',
+ name: 'baz',
+ version: '1.2.3',
+ dependencies: {
+ foo: '*',
+ bar: '2',
+ },
}),
+ node_modules: {
+ bar: {
+ 'package.json': JSON.stringify({
+ name: 'bar',
+ version: '2.3.4',
+ }),
+ },
+ extra: {
+ 'package.json': JSON.stringify({
+ name: 'extra',
+ version: '99.9999.999999',
+ description: 'extraneous package',
+ }),
+ },
+ },
},
},
+ 'package.json': JSON.stringify({
+ dependencies: {
+ baz: '1',
+ },
+ }),
},
- },
- 'package.json': JSON.stringify({
- dependencies: {
- baz: '1',
+ config: {
+ color: 'always',
+ ...config,
},
- }),
- })
+ })
+
+ return mock
+ }
t.test('works with the location', async t => {
const path = 'node_modules/foo'
+ const { explain, joinedOutput } = await mockNodes(t)
await explain.exec([path])
- t.strictSame(OUTPUT, [['foo@1.2.3 depth=Infinity color=true']])
+ t.strictSame(joinedOutput(), 'foo@1.2.3 depth=Infinity color=true')
})
t.test('works with a full actual path', async t => {
+ const { npm, explain, joinedOutput } = await mockNodes(t)
const path = resolve(npm.prefix, 'node_modules/foo')
await explain.exec([path])
- t.strictSame(OUTPUT, [['foo@1.2.3 depth=Infinity color=true']])
+ t.strictSame(joinedOutput(), 'foo@1.2.3 depth=Infinity color=true')
})
t.test('finds all nodes by name', async t => {
+ const { explain, joinedOutput } = await mockNodes(t)
await explain.exec(['bar'])
- t.strictSame(OUTPUT, [[
+ t.strictSame(joinedOutput(),
'bar@1.2.3 depth=Infinity color=true\n\n' +
- 'bar@2.3.4 depth=Infinity color=true',
- ]])
+ 'bar@2.3.4 depth=Infinity color=true'
+ )
})
t.test('finds only nodes that match the spec', async t => {
+ const { explain, joinedOutput } = await mockNodes(t)
await explain.exec(['bar@1'])
- t.strictSame(OUTPUT, [['bar@1.2.3 depth=Infinity color=true']])
+ t.strictSame(joinedOutput(), 'bar@1.2.3 depth=Infinity color=true')
})
t.test('finds extraneous nodes', async t => {
+ const { explain, joinedOutput } = await mockNodes(t)
await explain.exec(['extra'])
- t.strictSame(OUTPUT, [['extra@99.9999.999999 depth=Infinity color=true']])
+ t.strictSame(joinedOutput(), 'extra@99.9999.999999 depth=Infinity color=true')
})
t.test('json output', async t => {
- npm.flatOptions.json = true
+ const { explain, joinedOutput } = await mockNodes(t, { json: true })
await explain.exec(['node_modules/foo'])
- t.match(JSON.parse(OUTPUT[0][0]), [{
+ t.match(JSON.parse(joinedOutput()), [{
name: 'foo',
version: '1.2.3',
dependents: Array,
@@ -152,182 +158,126 @@ t.test('explain some nodes', t => {
})
t.test('report if no nodes found', async t => {
+ const { explain } = await mockNodes(t)
await t.rejects(
explain.exec(['asdf/foo/bar', 'quux@1.x']),
'No dependencies found matching asdf/foo/bar, quux@1.x'
)
})
- t.end()
})
t.test('workspaces', async t => {
- npm.localPrefix = npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'workspaces-project',
- version: '1.0.0',
- workspaces: ['packages/*'],
- dependencies: {
- abbrev: '^1.0.0',
- },
- }),
- node_modules: {
- a: t.fixture('symlink', '../packages/a'),
- b: t.fixture('symlink', '../packages/b'),
- c: t.fixture('symlink', '../packages/c'),
- once: {
+ const mockWorkspaces = async (t, exec = [], workspaces = true) => {
+ const mock = await mockExplain(t, {
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'once',
+ name: 'workspaces-project',
version: '1.0.0',
+ workspaces: ['packages/*'],
dependencies: {
- wrappy: '2.0.0',
+ abbrev: '^1.0.0',
},
}),
- },
- abbrev: {
- 'package.json': JSON.stringify({
- name: 'abbrev',
- version: '1.0.0',
- }),
- },
- wrappy: {
- 'package.json': JSON.stringify({
- name: 'wrappy',
- version: '2.0.0',
- }),
- },
- },
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- once: '1.0.0',
+ node_modules: {
+ a: t.fixture('symlink', '../packages/a'),
+ b: t.fixture('symlink', '../packages/b'),
+ c: t.fixture('symlink', '../packages/c'),
+ once: {
+ 'package.json': JSON.stringify({
+ name: 'once',
+ version: '1.0.0',
+ dependencies: {
+ wrappy: '2.0.0',
+ },
+ }),
},
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- abbrev: '^1.0.0',
+ abbrev: {
+ 'package.json': JSON.stringify({
+ name: 'abbrev',
+ version: '1.0.0',
+ }),
},
- }),
+ wrappy: {
+ 'package.json': JSON.stringify({
+ name: 'wrappy',
+ version: '2.0.0',
+ }),
+ },
+ },
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ once: '1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: '^1.0.0',
+ },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
+ },
},
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
+ config: {
+ ...(typeof workspaces === 'boolean' ? { workspaces } : { workspace: workspaces }),
+ color: 'always',
},
- },
- })
+ })
- await explain.exec(['wrappy'])
- t.strictSame(
- OUTPUT,
- [['wrappy@2.0.0 depth=Infinity color=true']],
- 'should explain workspaces deps'
- )
- OUTPUT.length = 0
+ await mock.explain.exec(exec)
- await explain.execWorkspaces(['wrappy'], ['a'])
+ return mock.joinedOutput()
+ }
- t.strictSame(
- OUTPUT,
- [
- ['wrappy@2.0.0 depth=Infinity color=true'],
- ],
- 'should explain deps when filtering to a single ws'
- )
- OUTPUT.length = 0
+ t.test('should explain workspaces deps', async t => {
+ const OUTPUT = await mockWorkspaces(t, ['wrappy'])
+ t.strictSame(
+ OUTPUT,
+ 'wrappy@2.0.0 depth=Infinity color=true'
+ )
+ })
- await explain.execWorkspaces(['abbrev'], [])
- t.strictSame(
- OUTPUT,
- [
- ['abbrev@1.0.0 depth=Infinity color=true'],
- ],
- 'should explain deps of workspaces only'
- )
- OUTPUT.length = 0
+ t.test('should explain deps when filtering to a single ws', async t => {
+ const OUTPUT = await mockWorkspaces(t, ['wrappy'], ['a'])
+ t.strictSame(
+ OUTPUT,
+ 'wrappy@2.0.0 depth=Infinity color=true'
+ )
+ })
- await t.rejects(
- explain.execWorkspaces(['abbrev'], ['a']),
- 'No dependencies found matching abbrev',
- 'should throw usage if dep not found within filtered ws'
- )
-})
+ t.test('should explain deps of workspaces only', async t => {
+ const OUTPUT = await mockWorkspaces(t, ['abbrev'])
+ t.strictSame(
+ OUTPUT,
+ 'abbrev@1.0.0 depth=Infinity color=true'
+ )
+ })
-t.test('workspaces disabled', async t => {
- npm.localPrefix = npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'workspaces-project',
- version: '1.0.0',
- workspaces: ['packages/*'],
- dependencies: {
- abbrev: '^1.0.0',
- },
- }),
- node_modules: {
- a: t.fixture('symlink', '../packages/a'),
- b: t.fixture('symlink', '../packages/b'),
- c: t.fixture('symlink', '../packages/c'),
- once: {
- 'package.json': JSON.stringify({
- name: 'once',
- version: '1.0.0',
- dependencies: {
- wrappy: '2.0.0',
- },
- }),
- },
- abbrev: {
- 'package.json': JSON.stringify({
- name: 'abbrev',
- version: '1.0.0',
- }),
- },
- wrappy: {
- 'package.json': JSON.stringify({
- name: 'wrappy',
- version: '2.0.0',
- }),
- },
- },
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- once: '1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- abbrev: '^1.0.0',
- },
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
- },
- },
+ t.test('should throw usage if dep not found within filtered ws', async t => {
+ await t.rejects(
+ mockWorkspaces(t, ['abbrev'], ['a']),
+ 'No dependencies found matching abbrev'
+ )
})
- npm.flatOptions.workspacesEnabled = false
- await t.rejects(
- explain.exec(['once']),
- 'No dependencies found matching once',
- 'should throw usage if dep not found when excluding ws'
- )
+ t.test('workspaces disabled', async t => {
+ await t.rejects(
+ mockWorkspaces(t, ['once'], false),
+ 'No dependencies found matching once',
+ 'should throw usage if dep not found when excluding ws'
+ )
+ })
})
diff --git a/deps/npm/test/lib/commands/explore.js b/deps/npm/test/lib/commands/explore.js
index af6f4df908..786a34a8e2 100644
--- a/deps/npm/test/lib/commands/explore.js
+++ b/deps/npm/test/lib/commands/explore.js
@@ -1,300 +1,149 @@
const t = require('tap')
-
-let RPJ_ERROR = null
-let RPJ_CALLED = ''
-const mockRPJ = async path => {
- if (RPJ_ERROR) {
- try {
+const mockNpm = require('../../fixtures/mock-npm')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
+const mockExplore = async (t, exec, {
+ RPJ_ERROR = null,
+ RUN_SCRIPT_ERROR = null,
+ RUN_SCRIPT_EXIT_CODE = 0,
+ RUN_SCRIPT_SIGNAL = null,
+} = {}) => {
+ let RPJ_CALLED = ''
+ const mockRPJ = async path => {
+ if (RPJ_ERROR) {
throw RPJ_ERROR
- } finally {
- RPJ_ERROR = null
}
+ RPJ_CALLED = cleanCwd(path)
+ return { some: 'package' }
}
- RPJ_CALLED = path
- return { some: 'package' }
-}
-let RUN_SCRIPT_ERROR = null
-let RUN_SCRIPT_EXIT_CODE = 0
-let RUN_SCRIPT_SIGNAL = null
-let RUN_SCRIPT_EXEC = null
-const mockRunScript = ({ pkg, banner, path, event, stdio }) => {
- if (event !== '_explore') {
- throw new Error('got wrong event name')
- }
+ let RUN_SCRIPT_EXEC = null
+ const mockRunScript = ({ pkg, event }) => {
+ if (event !== '_explore') {
+ throw new Error('got wrong event name')
+ }
- RUN_SCRIPT_EXEC = pkg.scripts._explore
+ RUN_SCRIPT_EXEC = pkg.scripts._explore
- if (RUN_SCRIPT_ERROR) {
- try {
+ if (RUN_SCRIPT_ERROR) {
return Promise.reject(RUN_SCRIPT_ERROR)
- } finally {
- RUN_SCRIPT_ERROR = null
}
- }
- if (RUN_SCRIPT_EXIT_CODE || RUN_SCRIPT_SIGNAL) {
- return Promise.reject(Object.assign(new Error('command failed'), {
- code: RUN_SCRIPT_EXIT_CODE,
- signal: RUN_SCRIPT_SIGNAL,
- }))
- }
+ if (RUN_SCRIPT_EXIT_CODE || RUN_SCRIPT_SIGNAL) {
+ return Promise.reject(Object.assign(new Error('command failed'), {
+ code: RUN_SCRIPT_EXIT_CODE,
+ signal: RUN_SCRIPT_SIGNAL,
+ }))
+ }
- return Promise.resolve({ code: 0, signal: null })
-}
+ return Promise.resolve({ code: 0, signal: null })
+ }
-const output = []
-const logs = []
-const getExplore = (windows) => {
- const Explore = t.mock('../../../lib/commands/explore.js', {
- path: require('path')[windows ? 'win32' : 'posix'],
- 'read-package-json-fast': mockRPJ,
- '@npmcli/run-script': mockRunScript,
- 'proc-log': {
- error: (...msg) => logs.push(msg),
- warn: () => {},
- },
- npmlog: {
- disableProgress: () => {},
- enableProgress: () => {},
- },
- })
- const npm = {
- dir: windows ? 'c:\\npm\\dir' : '/npm/dir',
- flatOptions: {
- shell: 'shell-command',
- },
- output: out => {
- output.push(out)
+ const mock = await mockNpm(t, {
+ mocks: {
+ 'read-package-json-fast': mockRPJ,
+ '@npmcli/run-script': mockRunScript,
},
config: {
- validate: () => {},
+ shell: 'shell-command',
},
- }
- return new Explore(npm)
-}
-
-const windowsExplore = getExplore(true)
-const posixExplore = getExplore(false)
-
-t.test('basic interactive', t => {
- t.afterEach(() => output.length = 0)
-
- t.test('windows', async t => {
- await windowsExplore.exec(['pkg'])
-
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json',
- RUN_SCRIPT_EXEC: 'shell-command',
- })
- t.strictSame(output, [
- "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n",
- ])
})
- t.test('posix', async t => {
- await posixExplore.exec(['pkg'])
+ await mock.npm.exec('explore', exec)
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'shell-command',
- })
- t.strictSame(output, [
- "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n",
- ])
- })
-
- t.end()
-})
+ return {
+ ...mock,
+ RPJ_CALLED,
+ RUN_SCRIPT_EXEC,
+ output: cleanCwd(mock.joinedOutput()).trim(),
+ }
+}
-t.test('interactive tracks exit code', t => {
- const { exitCode } = process
- t.beforeEach(() => {
- process.exitCode = exitCode
- RUN_SCRIPT_EXIT_CODE = 99
- })
- t.afterEach(() => {
- RUN_SCRIPT_EXIT_CODE = 0
- output.length = 0
- process.exitCode = exitCode
- })
+t.test('basic interactive', async t => {
+ const {
+ output,
+ RPJ_CALLED,
+ RUN_SCRIPT_EXEC,
+ } = await mockExplore(t, ['pkg'])
- t.test('windows', async t => {
- await windowsExplore.exec(['pkg'])
+ t.match(RPJ_CALLED, /\/pkg\/package.json$/)
+ t.strictSame(RUN_SCRIPT_EXEC, 'shell-command')
+ t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/)
+})
- t.strictSame({
+t.test('interactive tracks exit code', async t => {
+ t.test('code', async t => {
+ const {
+ output,
RPJ_CALLED,
RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json',
- RUN_SCRIPT_EXEC: 'shell-command',
- })
- t.strictSame(output, [
- "\nExploring c:\\npm\\dir\\pkg\nType 'exit' or ^D when finished\n",
- ])
- t.equal(process.exitCode, 99)
- })
+ } = await mockExplore(t, ['pkg'], { RUN_SCRIPT_EXIT_CODE: 99 })
- t.test('posix', async t => {
- await posixExplore.exec(['pkg'])
+ t.match(RPJ_CALLED, /\/pkg\/package.json$/)
+ t.strictSame(RUN_SCRIPT_EXEC, 'shell-command')
+ t.match(output, /Exploring \{CWD\}\/[\w-_/]+\nType 'exit' or \^D when finished/)
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'shell-command',
- })
- t.strictSame(output, [
- "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n",
- ])
t.equal(process.exitCode, 99)
})
- t.test('posix spawn fail', async t => {
- RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
+ t.test('spawn fail', async t => {
+ const RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
code: 33,
})
await t.rejects(
- posixExplore.exec(['pkg']),
+ mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
{ message: 'glorb', code: 33 }
)
- t.strictSame(output, [
- "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n",
- ])
t.equal(process.exitCode, 33)
})
- t.test('posix spawn fail, 0 exit code', async t => {
- RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
+ t.test('spawn fail, 0 exit code', async t => {
+ const RUN_SCRIPT_ERROR = Object.assign(new Error('glorb'), {
code: 0,
})
await t.rejects(
- posixExplore.exec(['pkg']),
+ mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
{ message: 'glorb', code: 0 }
)
- t.strictSame(output, [
- "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n",
- ])
t.equal(process.exitCode, 1)
})
- t.test('posix spawn fail, no exit code', async t => {
- RUN_SCRIPT_ERROR = Object.assign(new Error('command failed'), {
+ t.test('spawn fail, no exit code', async t => {
+ const RUN_SCRIPT_ERROR = Object.assign(new Error('command failed'), {
code: 'EPROBLEM',
})
await t.rejects(
- posixExplore.exec(['pkg']),
+ mockExplore(t, ['pkg'], { RUN_SCRIPT_ERROR }),
{ message: 'command failed', code: 'EPROBLEM' }
)
- t.strictSame(output, [
- "\nExploring /npm/dir/pkg\nType 'exit' or ^D when finished\n",
- ])
t.equal(process.exitCode, 1)
})
-
- t.end()
})
-t.test('basic non-interactive', t => {
- t.afterEach(() => output.length = 0)
-
- t.test('windows', async t => {
- await windowsExplore.exec(['pkg', 'ls'])
-
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
- t.strictSame(output, [])
- })
-
- t.test('posix', async t => {
- await posixExplore.exec(['pkg', 'ls'])
+t.test('basic non-interactive', async t => {
+ const {
+ output,
+ RPJ_CALLED,
+ RUN_SCRIPT_EXEC,
+ } = await mockExplore(t, ['pkg', 'ls'])
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
- t.strictSame(output, [])
- t.end()
- })
+ t.match(RPJ_CALLED, /\/pkg\/package.json$/)
+ t.strictSame(RUN_SCRIPT_EXEC, 'ls')
- t.end()
+ t.strictSame(output, '')
})
-t.test('signal fails non-interactive', t => {
- const { exitCode } = process
- t.afterEach(() => {
- output.length = 0
- logs.length = 0
- })
-
- t.beforeEach(() => {
- RUN_SCRIPT_SIGNAL = 'SIGPROBLEM'
- RUN_SCRIPT_EXIT_CODE = null
- process.exitCode = exitCode
- })
- t.afterEach(() => process.exitCode = exitCode)
-
- t.test('windows', async t => {
- await t.rejects(
- windowsExplore.exec(['pkg', 'ls']),
- {
- message: 'command failed',
- signal: 'SIGPROBLEM',
- }
- )
-
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: 'c:\\npm\\dir\\pkg\\package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
- t.strictSame(output, [])
- })
-
- t.test('posix', async t => {
- await t.rejects(
- posixExplore.exec(['pkg', 'ls']),
- {
- message: 'command failed',
- signal: 'SIGPROBLEM',
- }
- )
-
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
- t.strictSame(output, [])
- t.end()
- })
-
- t.end()
+t.test('signal fails non-interactive', async t => {
+ await t.rejects(
+ mockExplore(t, ['pkg', 'ls'], { RUN_SCRIPT_SIGNAL: 'SIGPROBLEM' }),
+ {
+ message: 'command failed',
+ signal: 'SIGPROBLEM',
+ }
+ )
})
-t.test('usage if no pkg provided', t => {
- t.teardown(() => {
- output.length = 0
- })
+t.test('usage if no pkg provided', async t => {
const noPkg = [
[],
['foo/../..'],
@@ -303,41 +152,22 @@ t.test('usage if no pkg provided', t => {
['..'],
['../..'],
]
- t.plan(noPkg.length)
+
for (const args of noPkg) {
t.test(JSON.stringify(args), async t => {
await t.rejects(
- posixExplore.exec(args),
+ mockExplore(t, args),
'Usage:'
)
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
})
}
})
t.test('pkg not installed', async t => {
- t.teardown(() => {
- logs.length = 0
- })
- RPJ_ERROR = new Error('plurple')
+ const RPJ_ERROR = new Error('plurple')
await t.rejects(
- posixExplore.exec(['pkg', 'ls']),
+ mockExplore(t, ['pkg', 'ls'], { RPJ_ERROR }),
{ message: 'plurple' }
)
- t.strictSame({
- RPJ_CALLED,
- RUN_SCRIPT_EXEC,
- }, {
- RPJ_CALLED: '/npm/dir/pkg/package.json',
- RUN_SCRIPT_EXEC: 'ls',
- })
- t.strictSame(output, [])
- t.match(logs, [['explore', `It doesn't look like pkg is installed.`]])
})
diff --git a/deps/npm/test/lib/commands/fund.js b/deps/npm/test/lib/commands/fund.js
index b82ed93fe5..277190e7a1 100644
--- a/deps/npm/test/lib/commands/fund.js
+++ b/deps/npm/test/lib/commands/fund.js
@@ -1,7 +1,8 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const mockNpm = require('../../fixtures/mock-npm')
const version = '1.0.0'
+
const funding = {
type: 'individual',
url: 'http://example.com/donate',
@@ -172,78 +173,64 @@ const conflictingFundingPackages = {
},
}
-let result = ''
-let printUrl = ''
-const config = {
- color: false,
- json: false,
- global: false,
- unicode: false,
- which: null,
-}
-const openUrl = async (npm, url, msg) => {
- if (url === 'http://npmjs.org') {
- throw new Error('ERROR')
- }
+const setup = async (t, { openUrl, ...opts } = {}) => {
+ const openedUrls = []
+
+ const res = await mockNpm(t, {
+ ...opts,
+ mocks: {
+ '@npmcli/promise-spawn': { open: openUrl || (async url => openedUrls.push(url)) },
+ pacote: {
+ manifest: arg =>
+ arg.name === 'ntl'
+ ? Promise.resolve({ funding: 'http://example.com/pacote' })
+ : Promise.reject(new Error('ERROR')),
+ },
+ ...opts.mocks,
+ },
+ })
- if (config.json) {
- printUrl = JSON.stringify({
- title: msg,
- url: url,
- })
- } else {
- printUrl = `${msg}:\n ${url}`
+ return {
+ ...res,
+ openedUrls: () => openedUrls,
+ fund: (...args) => res.npm.exec('fund', args),
}
}
-const Fund = t.mock('../../../lib/commands/fund.js', {
- '../../../lib/utils/open-url.js': openUrl,
- pacote: {
- manifest: arg =>
- arg.name === 'ntl'
- ? Promise.resolve({
- funding: 'http://example.com/pacote',
- })
- : Promise.reject(new Error('ERROR')),
- },
-})
-const npm = mockNpm({
- config,
- output: msg => {
- result += msg + '\n'
- },
-})
-const fund = new Fund(npm)
-t.afterEach(() => {
- printUrl = ''
- result = ''
-})
t.test('fund with no package containing funding', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'no-funding-package',
- version: '0.0.0',
- }),
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'no-funding-package',
+ version: '0.0.0',
+ }),
+ },
+ config: {},
})
- await fund.exec([])
- t.matchSnapshot(result, 'should print empty funding info')
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should print empty funding info')
})
t.test('fund in which same maintainer owns all its deps', async t => {
- npm.prefix = t.testdir(maintainerOwnsAllDeps)
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: maintainerOwnsAllDeps,
+ config: {},
+ })
- await fund.exec([])
- t.matchSnapshot(result, 'should print stack packages together')
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should print stack packages together')
})
t.test('fund in which same maintainer owns all its deps, using --json option', async t => {
- config.json = true
- npm.prefix = t.testdir(maintainerOwnsAllDeps)
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: maintainerOwnsAllDeps,
+ config: { json: true },
+ })
- await fund.exec([])
+ await fund()
t.same(
- JSON.parse(result),
+ JSON.parse(joinedOutput()),
{
length: 3,
name: 'maintainer-owns-all-deps',
@@ -268,24 +255,27 @@ t.test('fund in which same maintainer owns all its deps, using --json option', a
},
'should print stack packages together'
)
- config.json = false
})
t.test('fund containing multi-level nested deps with no funding', async t => {
- npm.prefix = t.testdir(nestedNoFundingPackages)
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: nestedNoFundingPackages,
+ config: {},
+ })
- await fund.exec([])
- t.matchSnapshot(result, 'should omit dependencies with no funding declared')
- t.end()
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should omit dependencies with no funding declared')
})
t.test('fund containing multi-level nested deps with no funding, using --json option', async t => {
- npm.prefix = t.testdir(nestedNoFundingPackages)
- config.json = true
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: nestedNoFundingPackages,
+ config: { json: true },
+ })
- await fund.exec([])
+ await fund()
t.same(
- JSON.parse(result),
+ JSON.parse(joinedOutput()),
{
length: 2,
name: 'nested-no-funding-packages',
@@ -303,16 +293,17 @@ t.test('fund containing multi-level nested deps with no funding, using --json op
},
'should omit dependencies with no funding declared in json output'
)
- config.json = false
})
t.test('fund containing multi-level nested deps with no funding, using --json option', async t => {
- npm.prefix = t.testdir(nestedMultipleFundingPackages)
- config.json = true
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: nestedMultipleFundingPackages,
+ config: { json: true },
+ })
- await fund.exec([])
+ await fund()
t.same(
- JSON.parse(result),
+ JSON.parse(joinedOutput()),
{
length: 2,
name: 'nested-multiple-funding-packages',
@@ -355,376 +346,337 @@ t.test('fund containing multi-level nested deps with no funding, using --json op
},
'should list multiple funding entries in json output'
)
- config.json = false
})
t.test('fund does not support global', async t => {
- npm.prefix = t.testdir({})
- config.global = true
+ const { fund } = await setup(t, {
+ config: { global: true },
+ })
- await t.rejects(fund.exec([]), { code: 'EFUNDGLOBAL' }, 'should throw EFUNDGLOBAL error')
- config.global = false
+ await t.rejects(fund(), { code: 'EFUNDGLOBAL' }, 'should throw EFUNDGLOBAL error')
})
t.test('fund using package argument', async t => {
- npm.prefix = t.testdir(maintainerOwnsAllDeps)
+ const { fund, openedUrls, joinedOutput } = await setup(t, {
+ prefixDir: maintainerOwnsAllDeps,
+ config: {},
+ })
- await fund.exec(['.'])
- t.matchSnapshot(printUrl, 'should open funding url')
+ await fund('.')
+ t.equal(joinedOutput(), '')
+ t.strictSame(openedUrls(), ['http://example.com/donate'], 'should open funding url')
})
t.test('fund does not support global, using --json option', async t => {
- npm.prefix = t.testdir({})
- config.global = true
- config.json = true
+ const { fund } = await setup(t, {
+ prefixDir: {},
+ config: { global: true, json: true },
+ })
await t.rejects(
- fund.exec([]),
+ fund(),
{ code: 'EFUNDGLOBAL', message: '`npm fund` does not support global packages' },
'should use expected error msg'
)
- config.global = false
- config.json = false
})
t.test('fund using string shorthand', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'funding-string-shorthand',
- version: '0.0.0',
- funding: 'https://example.com/sponsor',
- }),
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'funding-string-shorthand',
+ version: '0.0.0',
+ funding: 'https://example.com/sponsor',
+ }),
+ },
+ config: {},
})
- await fund.exec(['.'])
- t.matchSnapshot(printUrl, 'should open string-only url')
+ await fund('.')
+ t.strictSame(openedUrls(), ['https://example.com/sponsor'], 'should open string-only url')
})
t.test('fund using nested packages with multiple sources', async t => {
- npm.prefix = t.testdir(nestedMultipleFundingPackages)
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: nestedMultipleFundingPackages,
+ config: {},
+ })
- await fund.exec(['.'])
- t.matchSnapshot(result, 'should prompt with all available URLs')
+ await fund('.')
+ t.matchSnapshot(joinedOutput(), 'should prompt with all available URLs')
})
t.test('fund using symlink ref', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'using-symlink-ref',
- version: '1.0.0',
- }),
- a: {
+ const f = 'http://example.com/a'
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'a',
+ name: 'using-symlink-ref',
version: '1.0.0',
- funding: 'http://example.com/a',
}),
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ funding: f,
+ }),
+ },
+ node_modules: {
+ a: t.fixture('symlink', '../a'),
+ },
},
- node_modules: {
- a: t.fixture('symlink', '../a'),
- },
+ config: {},
})
// using symlinked ref
- await fund.exec(['./node_modules/a'])
- t.match(printUrl, 'http://example.com/a', 'should retrieve funding url from symlink')
-
- printUrl = ''
- result = ''
+ await fund('./node_modules/a')
+ t.strictSame(openedUrls(), [f], 'should retrieve funding url from symlink')
// using target ref
- await fund.exec(['./a'])
-
- t.match(printUrl, 'http://example.com/a', 'should retrieve funding url from symlink target')
+ await fund('./a')
+ t.strictSame(openedUrls(), [f, f], 'should retrieve funding url from symlink target')
})
t.test('fund using data from actual tree', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'using-actual-tree',
- version: '1.0.0',
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- funding: 'http://example.com/a',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- funding: 'http://example.com/b',
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.1',
- funding: 'http://example.com/_AAA',
- }),
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'using-actual-tree',
+ version: '1.0.0',
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ funding: 'http://example.com/a',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ funding: 'http://example.com/b',
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.1',
+ funding: 'http://example.com/_AAA',
+ }),
+ },
},
},
},
},
+ config: {},
})
// using symlinked ref
- await fund.exec(['a'])
- t.match(
- printUrl,
- 'http://example.com/_AAA',
+ await fund('a')
+ t.strictSame(
+ openedUrls(),
+ ['http://example.com/_AAA'],
'should retrieve fund info from actual tree, using greatest version found'
)
})
t.test('fund using nested packages with multiple sources, with a source number', async t => {
- npm.prefix = t.testdir(nestedMultipleFundingPackages)
- config.which = '1'
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: nestedMultipleFundingPackages,
+ config: { which: '1' },
+ })
- await fund.exec(['.'])
- t.matchSnapshot(printUrl, 'should open the numbered URL')
- config.which = null
+ await fund('.')
+ t.strictSame(openedUrls(), ['https://one.example.com'], 'should open the numbered URL')
})
t.test('fund using pkg name while having conflicting versions', async t => {
- npm.prefix = t.testdir(conflictingFundingPackages)
- config.which = '1'
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: conflictingFundingPackages,
+ config: { which: '1' },
+ })
- await fund.exec(['foo'])
- t.matchSnapshot(printUrl, 'should open greatest version')
+ await fund('foo')
+ t.strictSame(openedUrls(), ['http://example.com/2'], 'should open greatest version')
+})
+
+t.test('fund using bad which value: index too high', async t => {
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: nestedMultipleFundingPackages,
+ config: { which: '100' },
+ })
+
+ await fund('foo')
+ t.match(joinedOutput(), 'not a valid index')
+ t.matchSnapshot(joinedOutput(), 'should print message about invalid which')
})
t.test('fund using package argument with no browser, using --json option', async t => {
- npm.prefix = t.testdir(maintainerOwnsAllDeps)
- config.json = true
+ const { fund, openedUrls, joinedOutput } = await setup(t, {
+ prefixDir: maintainerOwnsAllDeps,
+ config: { json: true },
+ })
- await fund.exec(['.'])
+ await fund('.')
+ t.equal(joinedOutput(), '', 'no output')
t.same(
- JSON.parse(printUrl),
- {
- title: 'individual funding available at the following URL',
- url: 'http://example.com/donate',
- },
+ openedUrls(),
+ ['http://example.com/donate'],
'should open funding url using json output'
)
- config.json = false
})
t.test('fund using package info fetch from registry', async t => {
- npm.prefix = t.testdir({})
+ const { fund, openedUrls } = await setup(t, {
+ prefixDir: {},
+ config: {},
+ })
- await fund.exec(['ntl'])
+ await fund('ntl')
t.match(
- printUrl,
+ openedUrls(),
/http:\/\/example.com\/pacote/,
'should open funding url that was loaded from registry manifest'
)
})
t.test('fund tries to use package info fetch from registry but registry has nothing', async t => {
- npm.prefix = t.testdir({})
+ const { fund } = await setup(t, {
+ prefixDir: {},
+ config: {},
+ })
await t.rejects(
- fund.exec(['foo']),
+ fund('foo'),
{ code: 'ENOFUND', message: 'No valid funding method available for: foo' },
'should have no valid funding message'
)
})
t.test('fund but target module has no funding info', async t => {
- npm.prefix = t.testdir(nestedNoFundingPackages)
+ const { fund } = await setup(t, {
+ prefixDir: nestedNoFundingPackages,
+ config: {},
+ })
await t.rejects(
- fund.exec(['foo']),
+ fund('foo'),
{ code: 'ENOFUND', message: 'No valid funding method available for: foo' },
'should have no valid funding message'
)
})
t.test('fund using bad which value', async t => {
- npm.prefix = t.testdir(nestedMultipleFundingPackages)
- config.which = 3
+ const { fund } = await setup(t, {
+ prefixDir: nestedMultipleFundingPackages,
+ config: { which: '0' },
+ })
await t.rejects(
- fund.exec(['bar']),
+ fund('bar'),
{
code: 'EFUNDNUMBER',
- /* eslint-disable-next-line max-len */
- message: '`npm fund [<@scope>/]<pkg> [--which=fundingSourceNumber]` must be given a positive integer',
+ message: /must be given a positive integer/,
},
'should have bad which option error message'
)
- config.which = null
})
t.test('fund pkg missing version number', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- funding: 'http://example.com/foo',
- }),
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ funding: 'http://example.com/foo',
+ }),
+ },
+ config: {},
})
- await fund.exec([])
- t.matchSnapshot(result, 'should print name only')
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should print name only')
})
t.test('fund a package throws on openUrl', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- funding: 'http://npmjs.org',
- }),
+ const { fund } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ funding: 'http://npmjs.org',
+ }),
+ },
+ config: {},
+ openUrl: () => {
+ throw new Error('ERROR')
+ },
})
- await t.rejects(fund.exec(['.']), { message: 'ERROR' }, 'should throw unknown error')
+ await t.rejects(fund('.'), { message: 'ERROR' }, 'should throw unknown error')
})
t.test('fund a package with type and multiple sources', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- funding: [
- {
- type: 'Foo',
- url: 'http://example.com/foo',
- },
- {
- type: 'Lorem',
- url: 'http://example.com/foo-lorem',
- },
- ],
- }),
- })
-
- await fund.exec(['.'])
- t.matchSnapshot(result, 'should print prompt select message')
-})
-
-t.test('fund colors', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-fund-colors',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^1.0.0',
- c: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- funding: 'http://example.com/a',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- funding: 'http://example.com/b',
- dependencies: {
- d: '^1.0.0',
- e: '^1.0.0',
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ funding: [
+ {
+ type: 'Foo',
+ url: 'http://example.com/foo',
},
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- funding: 'http://example.com/b',
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- funding: 'http://example.com/d',
- }),
- },
- e: {
- 'package.json': JSON.stringify({
- name: 'e',
- version: '1.0.0',
- funding: 'http://example.com/e',
- }),
- },
- },
- })
- npm.color = true
-
- await fund.exec([])
- t.matchSnapshot(result, 'should print output with color info')
- npm.color = false
-})
-
-t.test('sub dep with fund info and a parent with no funding info', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-multiple-funding-sources',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- c: '^1.0.0',
+ {
+ type: 'Lorem',
+ url: 'http://example.com/foo-lorem',
},
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- funding: 'http://example.com/b',
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- funding: ['http://example.com/c', 'http://example.com/c-other'],
- }),
- },
+ ],
+ }),
},
+ config: {},
})
- await fund.exec([])
- t.matchSnapshot(result, 'should nest sub dep as child of root')
+ await fund('.')
+ t.matchSnapshot(joinedOutput(), 'should print prompt select message')
})
-t.test('workspaces', async t => {
- t.test('filter funding info by a specific workspace', async t => {
- npm.localPrefix = npm.prefix = t.testdir({
+t.test('fund colors', async t => {
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'workspaces-support',
+ name: 'test-fund-colors',
version: '1.0.0',
- workspaces: ['packages/*'],
dependencies: {
- d: '^1.0.0',
+ a: '^1.0.0',
+ b: '^1.0.0',
+ c: '^1.0.0',
},
}),
node_modules: {
- a: t.fixture('symlink', '../packages/a'),
- b: t.fixture('symlink', '../packages/b'),
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ funding: 'http://example.com/a',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ funding: 'http://example.com/b',
+ dependencies: {
+ d: '^1.0.0',
+ e: '^1.0.0',
+ },
+ }),
+ },
c: {
'package.json': JSON.stringify({
name: 'c',
version: '1.0.0',
- funding: ['http://example.com/c', 'http://example.com/c-other'],
+ funding: 'http://example.com/b',
}),
},
d: {
@@ -734,13 +686,38 @@ t.test('workspaces', async t => {
funding: 'http://example.com/d',
}),
},
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ version: '1.0.0',
+ funding: 'http://example.com/e',
+ }),
+ },
},
- packages: {
+ },
+ config: { color: 'always' },
+ })
+
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should print output with color info')
+})
+
+t.test('sub dep with fund info and a parent with no funding info', async t => {
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-multiple-funding-sources',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ b: '^1.0.0',
+ },
+ }),
+ node_modules: {
a: {
'package.json': JSON.stringify({
name: 'a',
version: '1.0.0',
- funding: 'https://example.com/a',
dependencies: {
c: '^1.0.0',
},
@@ -751,22 +728,97 @@ t.test('workspaces', async t => {
name: 'b',
version: '1.0.0',
funding: 'http://example.com/b',
- dependencies: {
- d: '^1.0.0',
- },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ funding: ['http://example.com/c', 'http://example.com/c-other'],
}),
},
},
- })
+ },
+ config: {},
+ })
- await fund.execWorkspaces([], ['a'])
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should nest sub dep as child of root')
+})
- t.matchSnapshot(result, 'should display only filtered workspace name and its deps')
+t.test('workspaces', async t => {
+ const wsPrefixDir = {
+ 'package.json': JSON.stringify({
+ name: 'workspaces-support',
+ version: '1.0.0',
+ workspaces: ['packages/*'],
+ dependencies: {
+ d: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: t.fixture('symlink', '../packages/a'),
+ b: t.fixture('symlink', '../packages/b'),
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ funding: ['http://example.com/c', 'http://example.com/c-other'],
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ funding: 'http://example.com/d',
+ }),
+ },
+ },
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ funding: 'https://example.com/a',
+ dependencies: {
+ c: '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ funding: 'http://example.com/b',
+ dependencies: {
+ d: '^1.0.0',
+ },
+ }),
+ },
+ },
+ }
- result = ''
+ t.test('filter funding info by a specific workspace name', async t => {
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: wsPrefixDir,
+ config: {
+ workspace: 'a',
+ },
+ })
- await fund.execWorkspaces([], ['./packages/a'])
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should display only filtered workspace name and its deps')
+ })
+
+ t.test('filter funding info by a specific workspace path', async t => {
+ const { fund, joinedOutput } = await setup(t, {
+ prefixDir: wsPrefixDir,
+ config: {
+ workspace: './packages/a',
+ },
+ })
- t.matchSnapshot(result, 'should display only filtered workspace path and its deps')
+ await fund()
+ t.matchSnapshot(joinedOutput(), 'should display only filtered workspace name and its deps')
})
})
diff --git a/deps/npm/test/lib/commands/help-search.js b/deps/npm/test/lib/commands/help-search.js
index 7fbeb195d2..ce6e5f7cf0 100644
--- a/deps/npm/test/lib/commands/help-search.js
+++ b/deps/npm/test/lib/commands/help-search.js
@@ -1,130 +1,89 @@
const t = require('tap')
-const { join } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
const chalk = require('chalk')
-const OUTPUT = []
-const output = msg => {
- OUTPUT.push(msg)
-}
-
-const config = {
- long: false,
-}
-const npmHelpErr = null
-const npm = mockNpm({
- color: false,
- config,
- flatOptions: {
- long: false,
+/* eslint-disable max-len */
+const docsFixtures = {
+ dir1: {
+ 'npm-exec.md': 'the exec command\nhelp has multiple lines of exec help\none of them references exec',
},
- usage: 'npm test usage',
- exec: async () => {
- if (npmHelpErr) {
- throw npmHelpErr
- }
+ dir2: {
+ 'npm-something.md': 'another\ncommand you run\nthat\nreferences exec\nand has multiple lines\nwith no matches\nthat will be ignored\nand another line\nthat does have exec as well',
+ 'npm-run-script.md': 'the scripted run-script command runs scripts\nand has lines\nsome of which dont match the string run\nor script\nscript',
+ 'npm-install.md': 'does a thing in a script\nif a thing does not exist in a thing you run\nto install it and run it maybe in a script',
+ },
+ dir3: {
+ 'npm-help.md': 'will run the `help-search` command if you need to run it to help you search',
+ 'npm-help-search.md': 'is the help search command\nthat you get if you run help-search',
+ 'npm-useless.md': 'exec\nexec',
+ 'npm-more-useless.md': 'exec exec',
+ 'npm-extra-useless.md': 'exec\nexec\nexec',
},
- output,
-})
-
-let globRoot = null
-const globDir = {
- 'npm-exec.md':
- 'the exec command\nhelp has multiple lines of exec help\none of them references exec',
- /* eslint-disable-next-line max-len */
- 'npm-something.md': 'another\ncommand you run\nthat\nreferences exec\nand has multiple lines\nwith no matches\nthat will be ignored\nand another line\nthat does have exec as well',
- /* eslint-disable-next-line max-len */
- 'npm-run-script.md': 'the scripted run-script command runs scripts\nand has lines\nsome of which dont match the string run\nor script\nscript',
- /* eslint-disable-next-line max-len */
- 'npm-install.md': 'does a thing in a script\nif a thing does not exist in a thing you run\nto install it and run it maybe in a script',
- 'npm-help.md': 'will run the `help-search` command if you need to run it to help you search',
- 'npm-help-search.md': 'is the help search command\nthat you get if you run help-search',
- 'npm-useless.md': 'exec\nexec',
- 'npm-more-useless.md': 'exec exec',
- 'npm-extra-useless.md': 'exec\nexec\nexec',
}
-const glob = (p, cb) =>
- cb(
- null,
- Object.keys(globDir).map(file => join(globRoot, file))
- )
+/* eslint-enable max-len */
+
+const execHelpSearch = async (t, exec = [], opts) => {
+ const { npm, ...rest } = await loadMockNpm(t, {
+ npm: ({ other }) => ({ npmRoot: other }),
+ // docs/content is hardcoded into the glob path in the command
+ otherDirs: {
+ docs: {
+ content: docsFixtures,
+ },
+ },
+ ...opts,
+ })
-const HelpSearch = t.mock('../../../lib/commands/help-search.js', {
- glob,
-})
-const helpSearch = new HelpSearch(npm)
+ await npm.exec('help-search', exec)
-t.test('npm help-search', async t => {
- globRoot = t.testdir(globDir)
- t.teardown(() => {
- OUTPUT.length = 0
- globRoot = null
- })
+ return { npm, output: rest.joinedOutput(), ...rest }
+}
- await helpSearch.exec(['exec'])
+t.test('npm help-search', async t => {
+ const { output } = await execHelpSearch(t, ['exec'])
- t.match(OUTPUT, /Top hits for "exec"/, 'outputs results')
+ t.match(output, /Top hits for "exec"/, 'outputs results')
})
t.test('npm help-search multiple terms', async t => {
- globRoot = t.testdir(globDir)
- t.teardown(() => {
- OUTPUT.length = 0
- globRoot = null
- })
+ const { output } = await execHelpSearch(t, ['run', 'script'])
- await helpSearch.exec(['run', 'script'])
-
- t.match(OUTPUT, /Top hits for/, 'outputs results')
- t.match(OUTPUT, /run:\d+ script:\d+/, 'shows hit counts for both terms')
+ t.match(output, /Top hits for/, 'outputs results')
+ t.match(output, /run:\d+ script:\d+/, 'shows hit counts for both terms')
})
t.test('npm help-search long output', async t => {
- globRoot = t.testdir(globDir)
- config.long = true
- t.teardown(() => {
- OUTPUT.length = 0
- config.long = false
- globRoot = null
+ const { output } = await execHelpSearch(t, ['exec'], {
+ config: {
+ long: true,
+ },
})
- await helpSearch.exec(['exec'])
-
- t.match(OUTPUT, /has multiple lines of exec help/, 'outputs detailed results')
+ t.match(output, /has multiple lines of exec help/, 'outputs detailed results')
})
t.test('npm help-search long output with color', async t => {
- globRoot = t.testdir(globDir)
- config.long = true
- npm.color = true
- t.teardown(() => {
- OUTPUT.length = 0
- config.long = false
- npm.color = false
- globRoot = null
+ const { output } = await execHelpSearch(t, ['help-search'], {
+ config: {
+ long: true,
+ color: 'always',
+ },
})
- await helpSearch.exec(['help-search'])
-
const highlightedText = chalk.bgBlack.red('help-search')
t.equal(
- OUTPUT.some(line => line.includes(highlightedText)),
+ output.split('\n').some(line => line.includes(highlightedText)),
true,
'returned highlighted search terms'
)
})
t.test('npm help-search no args', async t => {
- t.rejects(helpSearch.exec([]), /npm help-search/, 'outputs usage')
+ await t.rejects(execHelpSearch(t), /npm help-search/, 'outputs usage')
})
t.test('npm help-search no matches', async t => {
- globRoot = t.testdir(globDir)
- t.teardown(() => {
- OUTPUT.length = 0
- globRoot = null
- })
+ const { output } = await execHelpSearch(t, ['asdfasdf'])
- await helpSearch.exec(['asdfasdf'])
- t.match(OUTPUT, /No matches/)
+ t.match(output, /No matches/)
})
diff --git a/deps/npm/test/lib/commands/help.js b/deps/npm/test/lib/commands/help.js
index 1e623dab93..d4e7a81f84 100644
--- a/deps/npm/test/lib/commands/help.js
+++ b/deps/npm/test/lib/commands/help.js
@@ -1,351 +1,231 @@
const t = require('tap')
-const { EventEmitter } = require('events')
-
-const npmConfig = {
- usage: false,
- viewer: undefined,
- loglevel: undefined,
-}
-
-let helpSearchArgs = null
-const OUTPUT = []
-const npm = {
- usage: 'test npm usage',
- config: {
- get: key => npmConfig[key],
- set: (key, value) => {
- npmConfig[key] = value
- },
- parsedArgv: {
- cooked: [],
- },
- validate: () => {},
- },
- exec: async (cmd, args) => {
- if (cmd === 'help-search') {
- helpSearchArgs = args
- } else if (cmd === 'help') {
- return { usage: 'npm help <term>' }
+const localeCompare = require('@isaacs/string-locale-compare')('en')
+const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
+const genManPages = (obj) => {
+ const man = {}
+ const resPages = new Set()
+
+ for (const [section, pages] of Object.entries(obj)) {
+ const num = parseInt(section, 10)
+ man[`man${num}`] = {}
+
+ const sectionPages = []
+ for (const name of pages) {
+ man[`man${num}`][`${name}.${section}`] = `.TH "${name.toUpperCase()}" "${num}"`
+ sectionPages.push(name.replace(/^npm-/, ''))
}
- },
- deref: cmd => {},
- output: msg => {
- OUTPUT.push(msg)
- },
-}
-const globDefaults = [
- '/root/man/man1/npm-whoami.1',
- '/root/man/man5/npmrc.5',
- '/root/man/man7/disputes.7',
-]
-
-let globErr = null
-let globResult = globDefaults
-let globParam
-const glob = (p, cb) => {
- globParam = p
- return cb(globErr, globResult)
-}
-
-let spawnBin = null
-let spawnArgs = null
-let spawnCode = 0
-const spawn = (bin, args) => {
- spawnBin = bin
- spawnArgs = args
- const spawnEmitter = new EventEmitter()
- process.nextTick(() => {
- spawnEmitter.emit('exit', spawnCode)
- })
- return spawnEmitter
-}
+ // return a sorted list of uniq pages in order to test completion
+ for (const p of sectionPages.sort(localeCompare)) {
+ resPages.add(p)
+ }
+ }
-let openUrlArg = null
-const openUrl = async (npm, url, msg) => {
- openUrlArg = url
+ // man directory name is hardcoded in the command
+ return { fixtures: { man }, pages: [...resPages.values()] }
}
-const Help = t.mock('../../../lib/commands/help.js', {
- '../../../lib/utils/open-url.js': openUrl,
- child_process: {
- spawn,
+const mockHelp = async (t, {
+ man = {
+ 1: ['whoami', 'install', 'star', 'unstar', 'uninstall', 'unpublish'].map(p => `npm-${p}`),
+ 5: ['npmrc', 'install', 'package-json'],
+ 7: ['disputes', 'config'],
},
- glob,
-})
-const help = new Help(npm)
+ browser = false,
+ woman = false,
+ exec: execArgs = null,
+ spawnErr,
+ ...opts
+} = {}) => {
+ const config = {
+ // always set viewer to test the same on all platforms
+ viewer: browser ? 'browser' : woman ? 'woman' : 'man',
+ ...opts.config,
+ }
+
+ let args = null
+ const mockSpawn = async (...a) => {
+ args = a
+ if (spawnErr) {
+ throw spawnErr
+ }
+ }
+ mockSpawn.open = async (url) => args = [cleanCwd(decodeURI(url))]
+
+ const manPages = genManPages(man)
+
+ const { npm, ...rest } = await loadMockNpm(t, {
+ npm: ({ other }) => ({ npmRoot: other }),
+ mocks: { '@npmcli/promise-spawn': mockSpawn },
+ otherDirs: { ...manPages.fixtures },
+ config,
+ ...opts,
+ })
+
+ const help = await npm.cmd('help')
+ const exec = execArgs
+ ? await npm.exec('help', execArgs)
+ : (...a) => npm.exec('help', a)
+
+ return {
+ npm,
+ help,
+ exec,
+ manPages: manPages.pages,
+ getArgs: () => args,
+ ...rest,
+ }
+}
t.test('npm help', async t => {
- await help.exec([])
+ const { exec, joinedOutput } = await mockHelp(t)
+ await exec()
- t.match(OUTPUT, ['test npm usage'], 'showed npm usage')
+ t.match(joinedOutput(), 'npm <command>', 'showed npm usage')
})
t.test('npm help completion', async t => {
- t.teardown(() => {
- globErr = null
- })
+ const { help, manPages } = await mockHelp(t)
const noArgs = await help.completion({ conf: { argv: { remain: [] } } })
- t.strictSame(noArgs, ['help', 'whoami', 'npmrc', 'disputes'], 'outputs available help pages')
+ t.strictSame(noArgs, ['help', ...manPages], 'outputs available help pages')
const threeArgs = await help.completion({ conf: { argv: { remain: ['one', 'two', 'three'] } } })
t.strictSame(threeArgs, [], 'outputs no results when more than 2 args are provided')
- globErr = new Error('glob failed')
- t.rejects(
- help.completion({ conf: { argv: { remain: [] } } }),
- /glob failed/,
- 'glob errors propagate'
- )
})
t.test('npm help multiple args calls search', async t => {
- t.teardown(() => {
- helpSearchArgs = null
- })
-
- await help.exec(['run', 'script'])
+ const { joinedOutput } = await mockHelp(t, { exec: ['run', 'script'] })
- t.strictSame(helpSearchArgs, ['run', 'script'], 'passed the args to help-search')
+ t.match(joinedOutput(), 'No matches in help for: run script', 'calls help-search')
})
t.test('npm help no matches calls search', async t => {
- globResult = []
- t.teardown(() => {
- helpSearchArgs = null
- globResult = globDefaults
- })
-
- await help.exec(['asdfasdf'])
- t.strictSame(helpSearchArgs, ['asdfasdf'], 'passed the args to help-search')
-})
-
-t.test('npm help glob errors propagate', async t => {
- globErr = new Error('glob failed')
- t.teardown(() => {
- globErr = null
- spawnBin = null
- spawnArgs = null
- })
+ const { joinedOutput } = await mockHelp(t, { exec: ['asdfasdf'] })
- await t.rejects(help.exec(['whoami']), /glob failed/, 'glob error propagates')
+ t.match(joinedOutput(), 'No matches in help for: asdfasdf', 'passed the args to help-search')
})
t.test('npm help whoami', async t => {
- globResult = ['/root/man/man1/npm-whoami.1.xz']
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
- })
-
- await help.exec(['whoami'])
+ const { getArgs } = await mockHelp(t, { exec: ['whoami'] })
+ const [spawnBin, spawnArgs] = getArgs()
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, [globResult[0]], 'passes the correct arguments')
+ t.equal(spawnArgs.length, 1)
+ t.match(spawnArgs[0], /\/man\/man1\/npm-whoami\.1$/)
})
t.test('npm help 1 install', async t => {
- npmConfig.viewer = 'browser'
- globResult = ['/root/man/man5/install.5', '/root/man/man1/npm-install.1']
-
- t.teardown(() => {
- npmConfig.viewer = undefined
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['1', 'install'],
+ browser: true,
})
- await help.exec(['1', 'install'])
-
- t.match(openUrlArg, /commands(\/|\\)npm-install.html$/, 'attempts to open the correct url')
- t.ok(openUrlArg.startsWith('file:///'), 'opens with the correct uri schema')
+ const [url] = getArgs()
+ t.match(url, /commands\/npm-install.html$/, 'attempts to open the correct url')
+ t.ok(url.startsWith('file:///'), 'opens with the correct uri schema')
})
t.test('npm help 5 install', async t => {
- npmConfig.viewer = 'browser'
- globResult = ['/root/man/man5/install.5']
-
- t.teardown(() => {
- npmConfig.viewer = undefined
- globResult = globDefaults
- globParam = null
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['5', 'install'],
+ browser: true,
})
- await help.exec(['5', 'install'])
-
- t.match(globParam, /man5/, 'searches only in man5 folder')
- t.match(openUrlArg, /configuring-npm(\/|\\)install.html$/, 'attempts to open the correct url')
+ const [url] = getArgs()
+ t.match(url, /configuring-npm\/install.html$/, 'attempts to open the correct url')
})
t.test('npm help 7 config', async t => {
- npmConfig.viewer = 'browser'
- globResult = ['/root/man/man7/config.7']
- t.teardown(() => {
- npmConfig.viewer = undefined
- globParam = null
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['7', 'config'],
+ browser: true,
})
- await help.exec(['7', 'config'])
-
- t.match(globParam, /man7/, 'searches only in man5 folder')
- t.match(openUrlArg, /using-npm(\/|\\)config.html$/, 'attempts to open the correct url')
+ const [url] = getArgs()
+ t.match(url, /using-npm\/config.html$/, 'attempts to open the correct url')
})
t.test('npm help package.json redirects to package-json', async t => {
- globResult = ['/root/man/man5/package-json.5']
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['package.json'],
})
- await help.exec(['package.json'])
-
+ const [spawnBin, spawnArgs] = getArgs()
t.equal(spawnBin, 'man', 'calls man by default')
- t.match(globParam, /package-json/, 'glob was asked to find package-json')
- t.strictSame(spawnArgs, [globResult[0]], 'passes the correct arguments')
+ t.equal(spawnArgs.length, 1)
+ t.match(spawnArgs[0], /\/man\/man5\/package-json\.5$/)
})
t.test('npm help ?(un)star', async t => {
- npmConfig.viewer = 'woman'
- globResult = ['/root/man/man1/npm-star.1', '/root/man/man1/npm-unstar.1']
- t.teardown(() => {
- npmConfig.viewer = undefined
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
- })
-
- await help.exec(['?(un)star'])
-
- t.equal(spawnBin, 'emacsclient', 'maps woman to emacs correctly')
- t.strictSame(
- spawnArgs,
- ['-e', `(woman-find-file '/root/man/man1/npm-star.1')`],
- 'passes the correct arguments'
- )
-})
-
-t.test('npm help - woman viewer propagates errors', async t => {
- npmConfig.viewer = 'woman'
- spawnCode = 1
- globResult = ['/root/man/man1/npm-star.1', '/root/man/man1/npm-unstar.1']
- t.teardown(() => {
- npmConfig.viewer = undefined
- spawnCode = 0
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['?(un)star'],
+ woman: true,
})
- await t.rejects(
- help.exec(['?(un)star']),
- /help process exited with code: 1/,
- 'received the correct error'
- )
+ const [spawnBin, spawnArgs] = getArgs()
t.equal(spawnBin, 'emacsclient', 'maps woman to emacs correctly')
- t.strictSame(
- spawnArgs,
- ['-e', `(woman-find-file '/root/man/man1/npm-star.1')`],
- 'passes the correct arguments'
- )
+ t.equal(spawnArgs.length, 2)
+ t.match(spawnArgs[1], /^\(woman-find-file '/)
+ t.match(spawnArgs[1], /\/man\/man1\/npm-star.1'\)$/)
})
t.test('npm help un*', async t => {
- globResult = [
- '/root/man/man1/npm-unstar.1',
- '/root/man/man1/npm-uninstall.1',
- '/root/man/man1/npm-unpublish.1',
- ]
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+ const { getArgs } = await mockHelp(t, {
+ exec: ['un*'],
})
- await help.exec(['un*'])
-
+ const [spawnBin, spawnArgs] = getArgs()
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['/root/man/man1/npm-uninstall.1'], 'passes the correct arguments')
+ t.equal(spawnArgs.length, 1)
+ t.match(spawnArgs[0], /\/man\/man1\/npm-uninstall\.1$/)
})
-t.test('npm help - man viewer propagates errors', async t => {
- spawnCode = 1
- globResult = [
- '/root/man/man1/npm-unstar.1',
- '/root/man/man1/npm-uninstall.1',
- '/root/man/man1/npm-unpublish.1',
- ]
- t.teardown(() => {
- spawnCode = 0
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+t.test('npm help - prefers npm help pages', async t => {
+ const { getArgs } = await mockHelp(t, {
+ man: {
+ 6: ['npm-install'],
+ 1: ['install'],
+ 5: ['install', 'npm-install'],
+ },
+ exec: ['install'],
})
- await t.rejects(help.exec(['un*']), /help process exited with code: 1/, 'received correct error')
+ const [spawnBin, spawnArgs] = getArgs()
t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['/root/man/man1/npm-uninstall.1'], 'passes the correct arguments')
+ t.equal(spawnArgs.length, 1)
+ t.match(spawnArgs[0], /\/man\/man5\/npm-install\.5$/)
})
-t.test('npm help with complex installation path finds proper help file', async t => {
- npmConfig.viewer = 'browser'
- globResult = [
- 'C:/Program Files/node-v14.15.5-win-x64/node_modules/npm/man/man1/npm-install.1',
- // glob always returns forward slashes, even on Windows
- ]
-
- t.teardown(() => {
- npmConfig.viewer = undefined
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+t.test('npm help - works in the presence of strange man pages', async t => {
+ const { getArgs } = await mockHelp(t, {
+ man: {
+ '6strange': ['config'],
+ 1: ['config'],
+ '5ssl': ['config'],
+ },
+ exec: ['config'],
})
- await help.exec(['1', 'install'])
-
- t.match(openUrlArg, /commands(\/|\\)npm-install.html$/, 'attempts to open the correct url')
+ const [spawnBin, spawnArgs] = getArgs()
+ t.equal(spawnBin, 'man', 'calls man by default')
+ t.equal(spawnArgs.length, 1)
+ t.match(spawnArgs[0], /\/man\/man1\/config\.1$/)
})
-t.test('npm help - prefers npm help pages', async t => {
- // Unusual ordering is to get full test coverage of all branches inside the
- // sort function.
- globResult = [
- '/root/man/man6/npm-install.6',
- '/root/man/man1/install.1',
- '/root/man/man5/npm-install.5',
- ]
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+t.test('rejects with code', async t => {
+ const { exec } = await mockHelp(t, {
+ spawnErr: Object.assign(new Error('errrrr'), { code: 'SPAWN_ERR' }),
})
- await help.exec(['install'])
- t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['/root/man/man5/npm-install.5'], 'passes the correct arguments')
+ await t.rejects(exec('whoami'), /help process exited with code: SPAWN_ERR/)
})
-t.test('npm help - works in the presence of strange man pages', async t => {
- // Unusual ordering is to get full test coverage of all branches inside the
- // sort function.
- globResult = [
- '/root/man/man6/config.6strange',
- '/root/man/man1/config.1',
- '/root/man/man5/config.5ssl',
- ]
- t.teardown(() => {
- globResult = globDefaults
- spawnBin = null
- spawnArgs = null
+t.test('rejects with no code', async t => {
+ const { exec } = await mockHelp(t, {
+ spawnErr: new Error('errrrr'),
})
- await help.exec(['config'])
- t.equal(spawnBin, 'man', 'calls man by default')
- t.strictSame(spawnArgs, ['/root/man/man1/config.1'], 'passes the correct arguments')
+ await t.rejects(exec('whoami'), /errrrr/)
})
diff --git a/deps/npm/test/lib/commands/hook.js b/deps/npm/test/lib/commands/hook.js
index 0cd6a7490d..01da9dc720 100644
--- a/deps/npm/test/lib/commands/hook.js
+++ b/deps/npm/test/lib/commands/hook.js
@@ -1,86 +1,81 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const output = []
-const npm = mockNpm({
- flatOptions: {
- json: false,
- parseable: false,
- unicode: false,
- },
- config: {
- loglevel: 'info',
- },
- output: msg => {
- output.push(msg)
- },
-})
+const mockNpm = require('../../fixtures/mock-npm')
-const pkgTypes = {
- semver: 'package',
- '@npmcli': 'scope',
- npm: 'owner',
-}
+const mockHook = async (t, { hookResponse, ...npmOpts } = {}) => {
+ const now = Date.now()
-const now = Date.now()
-let hookResponse = null
-let hookArgs = null
-const libnpmhook = {
- add: async (pkg, uri, secret, opts) => {
- hookArgs = { pkg, uri, secret, opts }
- return { id: 1, name: pkg, type: pkgTypes[pkg], endpoint: uri }
- },
- ls: async opts => {
- hookArgs = opts
- let id = 0
- if (hookResponse) {
- return hookResponse
- }
-
- return Object.keys(pkgTypes).map(name => ({
- id: ++id,
- name,
- type: pkgTypes[name],
- endpoint: 'https://google.com',
- last_delivery: id % 2 === 0 ? now : undefined,
- }))
- },
- rm: async (id, opts) => {
- hookArgs = { id, opts }
- const pkg = Object.keys(pkgTypes)[0]
- return {
- id: 1,
- name: pkg,
- type: pkgTypes[pkg],
- endpoint: 'https://google.com',
- }
- },
- update: async (id, uri, secret, opts) => {
- hookArgs = { id, uri, secret, opts }
- const pkg = Object.keys(pkgTypes)[0]
- return { id, name: pkg, type: pkgTypes[pkg], endpoint: uri }
- },
-}
+ let hookArgs = null
-const Hook = t.mock('../../../lib/commands/hook.js', {
- libnpmhook,
-})
-const hook = new Hook(npm)
+ const pkgTypes = {
+ semver: 'package',
+ '@npmcli': 'scope',
+ npm: 'owner',
+ }
+
+ const libnpmhook = {
+ add: async (pkg, uri, secret, opts) => {
+ hookArgs = { pkg, uri, secret, opts }
+ return { id: 1, name: pkg, type: pkgTypes[pkg], endpoint: uri }
+ },
+ ls: async opts => {
+ hookArgs = opts
+ let id = 0
+ if (hookResponse) {
+ return hookResponse
+ }
+
+ return Object.keys(pkgTypes).map(name => ({
+ id: ++id,
+ name,
+ type: pkgTypes[name],
+ endpoint: 'https://google.com',
+ last_delivery: id % 2 === 0 ? now : undefined,
+ }))
+ },
+ rm: async (id, opts) => {
+ hookArgs = { id, opts }
+ const pkg = Object.keys(pkgTypes)[0]
+ return {
+ id: 1,
+ name: pkg,
+ type: pkgTypes[pkg],
+ endpoint: 'https://google.com',
+ }
+ },
+ update: async (id, uri, secret, opts) => {
+ hookArgs = { id, uri, secret, opts }
+ const pkg = Object.keys(pkgTypes)[0]
+ return { id, name: pkg, type: pkgTypes[pkg], endpoint: uri }
+ },
+ }
+
+ const mock = await mockNpm(t, {
+ ...npmOpts,
+ mocks: {
+ libnpmhook,
+ ...npmOpts.mocks,
+ },
+ })
+
+ return {
+ ...mock,
+ now,
+ hook: { exec: (args) => mock.npm.exec('hook', args) },
+ hookArgs: () => hookArgs,
+ }
+}
t.test('npm hook no args', async t => {
+ const { hook } = await mockHook(t)
await t.rejects(hook.exec([]), hook.usage, 'throws usage with no arguments')
})
t.test('npm hook add', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
- })
-
+ const { npm, hook, outputs, hookArgs } = await mockHook(t)
await hook.exec(['add', 'semver', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: 'semver',
uri: 'https://google.com',
@@ -89,19 +84,15 @@ t.test('npm hook add', async t => {
},
'provided the correct arguments to libnpmhook'
)
- t.strictSame(output, ['+ semver -> https://google.com'], 'prints the correct output')
+ t.strictSame(outputs[0], ['+ semver -> https://google.com'], 'prints the correct output')
})
t.test('npm hook add - correct owner hook output', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
- })
-
+ const { npm, hook, outputs, hookArgs } = await mockHook(t)
await hook.exec(['add', '~npm', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: '~npm',
uri: 'https://google.com',
@@ -110,19 +101,15 @@ t.test('npm hook add - correct owner hook output', async t => {
},
'provided the correct arguments to libnpmhook'
)
- t.strictSame(output, ['+ ~npm -> https://google.com'], 'prints the correct output')
+ t.strictSame(outputs[0], ['+ ~npm -> https://google.com'], 'prints the correct output')
})
t.test('npm hook add - correct scope hook output', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
- })
-
+ const { npm, hook, outputs, hookArgs } = await mockHook(t)
await hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: '@npmcli',
uri: 'https://google.com',
@@ -131,21 +118,21 @@ t.test('npm hook add - correct scope hook output', async t => {
},
'provided the correct arguments to libnpmhook'
)
- t.strictSame(output, ['+ @npmcli -> https://google.com'], 'prints the correct output')
+ t.strictSame(outputs[0], ['+ @npmcli -> https://google.com'], 'prints the correct output')
})
t.test('npm hook add - unicode output', async t => {
- npm.flatOptions.unicode = true
- t.teardown(() => {
- npm.flatOptions.unicode = false
- hookArgs = null
- output.length = 0
+ const config = {
+ unicode: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['add', 'semver', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: 'semver',
uri: 'https://google.com',
@@ -154,21 +141,21 @@ t.test('npm hook add - unicode output', async t => {
},
'provided the correct arguments to libnpmhook'
)
- t.strictSame(output, ['+ semver ➜ https://google.com'], 'prints the correct output')
+ t.strictSame(outputs[0], ['+ semver ➜ https://google.com'], 'prints the correct output')
})
t.test('npm hook add - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- hookArgs = null
- output.length = 0
+ const config = {
+ json: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: '@npmcli',
uri: 'https://google.com',
@@ -178,7 +165,7 @@ t.test('npm hook add - json output', async t => {
'provided the correct arguments to libnpmhook'
)
t.strictSame(
- JSON.parse(output[0]),
+ JSON.parse(outputs[0][0]),
{
id: 1,
name: '@npmcli',
@@ -190,17 +177,17 @@ t.test('npm hook add - json output', async t => {
})
t.test('npm hook add - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- hookArgs = null
- output.length = 0
+ const config = {
+ parseable: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: '@npmcli',
uri: 'https://google.com',
@@ -209,30 +196,29 @@ t.test('npm hook add - parseable output', async t => {
},
'provided the correct arguments to libnpmhook'
)
+
t.strictSame(
- output[0].split(/\t/),
+ outputs[0][0].split(/\t/),
['id', 'name', 'type', 'endpoint'],
'prints the correct parseable output headers'
)
t.strictSame(
- output[1].split(/\t/),
+ outputs[1][0].split(/\t/),
['1', '@npmcli', 'scope', 'https://google.com'],
'prints the correct parseable values'
)
})
t.test('npm hook add - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- hookArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['add', '@npmcli', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
pkg: '@npmcli',
uri: 'https://google.com',
@@ -241,55 +227,49 @@ t.test('npm hook add - silent output', async t => {
},
'provided the correct arguments to libnpmhook'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
t.test('npm hook ls', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
- })
-
+ const { npm, hook, outputs, hookArgs } = await mockHook(t)
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
},
'received the correct arguments'
)
- t.equal(output[0], 'You have 3 hooks configured.', 'prints the correct header')
- const out = require('../../../lib/utils/ansi-trim')(output[1])
+ t.equal(outputs[0][0], 'You have 3 hooks configured.', 'prints the correct header')
+ const out = require('../../../lib/utils/ansi-trim')(outputs[1][0])
t.match(out, /semver.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints package hook')
t.match(out, /@npmcli.*https:\/\/google.com.*\n.*\n.*triggered just now/, 'prints scope hook')
t.match(out, /~npm.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints owner hook')
})
t.test('npm hook ls, no results', async t => {
- hookResponse = []
- t.teardown(() => {
- hookResponse = null
- hookArgs = null
- output.length = 0
+ const hookResponse = []
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ hookResponse,
})
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
},
'received the correct arguments'
)
- t.equal(output[0], "You don't have any hooks configured yet.", 'prints the correct result')
+ t.equal(outputs[0][0], "You don't have any hooks configured yet.", 'prints the correct result')
})
t.test('npm hook ls, single result', async t => {
- hookResponse = [
+ const hookResponse = [
{
id: 1,
name: 'semver',
@@ -297,47 +277,44 @@ t.test('npm hook ls, single result', async t => {
endpoint: 'https://google.com',
},
]
-
- t.teardown(() => {
- hookResponse = null
- hookArgs = null
- output.length = 0
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ hookResponse,
})
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
},
'received the correct arguments'
)
- t.equal(output[0], 'You have one hook configured.', 'prints the correct header')
- const out = require('../../../lib/utils/ansi-trim')(output[1])
+ t.equal(outputs[0][0], 'You have one hook configured.', 'prints the correct header')
+ const out = require('../../../lib/utils/ansi-trim')(outputs[1][0])
t.match(out, /semver.*https:\/\/google.com.*\n.*\n.*never triggered/, 'prints package hook')
})
t.test('npm hook ls - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- hookArgs = null
- output.length = 0
+ const config = {
+ json: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
},
'received the correct arguments'
)
- const out = JSON.parse(output[0])
+ const out = JSON.parse(outputs[0])
t.match(
out,
[
@@ -365,17 +342,17 @@ t.test('npm hook ls - json output', async t => {
})
t.test('npm hook ls - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- hookArgs = null
- output.length = 0
+ const config = {
+ parseable: true,
+ }
+ const { npm, hook, outputs, hookArgs, now } = await mockHook(t, {
+ config,
})
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
@@ -383,7 +360,7 @@ t.test('npm hook ls - parseable output', async t => {
'received the correct arguments'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['id', 'name', 'type', 'endpoint', 'last_delivery'],
['1', 'semver', 'package', 'https://google.com', ''],
@@ -395,99 +372,92 @@ t.test('npm hook ls - parseable output', async t => {
})
t.test('npm hook ls - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- hookArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['ls'])
t.match(
- hookArgs,
+ hookArgs(),
{
...npm.flatOptions,
package: undefined,
},
'received the correct arguments'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
t.test('npm hook rm', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
})
-
await hook.exec(['rm', '1'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
opts: npm.flatOptions,
},
'received the correct arguments'
)
- t.strictSame(output, ['- semver X https://google.com'], 'printed the correct output')
+ t.strictSame(outputs[0], ['- semver X https://google.com'], 'printed the correct output')
})
t.test('npm hook rm - unicode output', async t => {
- npm.flatOptions.unicode = true
- t.teardown(() => {
- npm.flatOptions.unicode = false
- hookArgs = null
- output.length = 0
+ const config = {
+ unicode: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['rm', '1'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
opts: npm.flatOptions,
},
'received the correct arguments'
)
- t.strictSame(output, ['- semver ✘ https://google.com'], 'printed the correct output')
+ t.strictSame(outputs[0], ['- semver ✘ https://google.com'], 'printed the correct output')
})
t.test('npm hook rm - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- hookArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['rm', '1'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
opts: npm.flatOptions,
},
'received the correct arguments'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
t.test('npm hook rm - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- hookArgs = null
- output.length = 0
+ const config = {
+ json: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['rm', '1'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
opts: npm.flatOptions,
@@ -495,7 +465,7 @@ t.test('npm hook rm - json output', async t => {
'received the correct arguments'
)
t.strictSame(
- JSON.parse(output[0]),
+ JSON.parse(outputs[0]),
{
id: 1,
name: 'semver',
@@ -507,17 +477,17 @@ t.test('npm hook rm - json output', async t => {
})
t.test('npm hook rm - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- hookArgs = null
- output.length = 0
+ const config = {
+ parseable: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['rm', '1'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
opts: npm.flatOptions,
@@ -525,7 +495,7 @@ t.test('npm hook rm - parseable output', async t => {
'received the correct arguments'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['id', 'name', 'type', 'endpoint'],
['1', 'semver', 'package', 'https://google.com'],
@@ -535,15 +505,12 @@ t.test('npm hook rm - parseable output', async t => {
})
t.test('npm hook update', async t => {
- t.teardown(() => {
- hookArgs = null
- output.length = 0
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
})
-
await hook.exec(['update', '1', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
uri: 'https://google.com',
@@ -552,21 +519,21 @@ t.test('npm hook update', async t => {
},
'received the correct arguments'
)
- t.strictSame(output, ['+ semver -> https://google.com'], 'printed the correct output')
+ t.strictSame(outputs[0], ['+ semver -> https://google.com'], 'printed the correct output')
})
t.test('npm hook update - unicode', async t => {
- npm.flatOptions.unicode = true
- t.teardown(() => {
- npm.flatOptions.unicode = false
- hookArgs = null
- output.length = 0
+ const config = {
+ unicode: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['update', '1', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
uri: 'https://google.com',
@@ -575,21 +542,21 @@ t.test('npm hook update - unicode', async t => {
},
'received the correct arguments'
)
- t.strictSame(output, ['+ semver ➜ https://google.com'], 'printed the correct output')
+ t.strictSame(outputs[0], ['+ semver ➜ https://google.com'], 'printed the correct output')
})
t.test('npm hook update - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- hookArgs = null
- output.length = 0
+ const config = {
+ json: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['update', '1', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
uri: 'https://google.com',
@@ -599,7 +566,7 @@ t.test('npm hook update - json output', async t => {
'received the correct arguments'
)
t.strictSame(
- JSON.parse(output[0]),
+ JSON.parse(outputs[0]),
{
id: '1',
name: 'semver',
@@ -611,17 +578,17 @@ t.test('npm hook update - json output', async t => {
})
t.test('npm hook update - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- hookArgs = null
- output.length = 0
+ const config = {
+ parseable: true,
+ }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['update', '1', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
uri: 'https://google.com',
@@ -631,7 +598,7 @@ t.test('npm hook update - parseable output', async t => {
'received the correct arguments'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['id', 'name', 'type', 'endpoint'],
['1', 'semver', 'package', 'https://google.com'],
@@ -641,17 +608,15 @@ t.test('npm hook update - parseable output', async t => {
})
t.test('npm hook update - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- hookArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, hook, outputs, hookArgs } = await mockHook(t, {
+ config,
})
await hook.exec(['update', '1', 'https://google.com', 'some-secret'])
t.match(
- hookArgs,
+ hookArgs(),
{
id: '1',
uri: 'https://google.com',
@@ -660,5 +625,5 @@ t.test('npm hook update - silent output', async t => {
},
'received the correct arguments'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
diff --git a/deps/npm/test/lib/commands/init.js b/deps/npm/test/lib/commands/init.js
index d11e0091b7..2d59f47d98 100644
--- a/deps/npm/test/lib/commands/init.js
+++ b/deps/npm/test/lib/commands/init.js
@@ -1,108 +1,88 @@
const t = require('tap')
-const fs = require('fs')
-const { resolve } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const config = {
- cache: 'bad-cache-dir',
- 'init-module': '~/.npm-init.js',
- yes: true,
-}
-const flatOptions = {
- cache: 'test-config-dir/_cacache',
- npxCache: 'test-config-dir/_npx',
-}
-const npm = mockNpm({
- flatOptions,
- config,
-})
-const mocks = {
- npmlog: {
- disableProgress: () => null,
- enableProgress: () => null,
- },
- 'proc-log': {
- info: () => null,
- pause: () => null,
- resume: () => null,
- silly: () => null,
- },
+const fs = require('fs/promises')
+const { resolve, basename } = require('path')
+const _mockNpm = require('../../fixtures/mock-npm')
+const { cleanTime } = require('../../fixtures/clean-snapshot')
+
+t.cleanSnapshot = cleanTime
+
+const mockNpm = async (t, { noLog, libnpmexec, initPackageJson, packageJson, ...opts } = {}) => {
+ const res = await _mockNpm(t, {
+ ...opts,
+ mocks: {
+ ...(libnpmexec ? { libnpmexec } : {}),
+ ...(initPackageJson ? { 'init-package-json': initPackageJson } : {}),
+ ...(packageJson ? { '@npmcli/package-json': packageJson } : {}),
+ },
+ globals: {
+ // init-package-json prints directly to console.log
+ // this avoids poluting test output with those logs
+ ...(noLog ? { 'console.log': () => {} } : {}),
+ },
+ })
+
+ return res
}
-const Init = t.mock('../../../lib/commands/init.js', mocks)
-const init = new Init(npm)
-const _cwd = process.cwd()
-const _consolelog = console.log
-const noop = () => {}
-
-t.afterEach(() => {
- config.yes = true
- config.package = undefined
- process.chdir(_cwd)
- console.log = _consolelog
+
+t.test('displays output', async t => {
+ const { npm, joinedOutput } = await mockNpm(t, {
+ initPackageJson: (...args) => args[3](),
+ })
+
+ await npm.exec('init', [])
+ t.matchSnapshot(joinedOutput(), 'displays helper info')
})
t.test('classic npm init -y', async t => {
- npm.localPrefix = t.testdir({})
-
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
+ const { npm, prefix } = await mockNpm(t, {
+ config: { yes: true },
+ noLog: true,
+ })
- process.chdir(npm.localPrefix)
- await init.exec([])
+ await npm.exec('init', [])
- const pkg = require(resolve(npm.localPrefix, 'package.json'))
+ const pkg = require(resolve(prefix, 'package.json'))
t.equal(pkg.version, '1.0.0')
t.equal(pkg.license, 'ISC')
})
t.test('classic interactive npm init', async t => {
- npm.localPrefix = t.testdir({})
- config.yes = undefined
+ t.plan(1)
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- 'init-package-json': (path, initFile, config, cb) => {
+ const { npm } = await mockNpm(t, {
+ initPackageJson: (...args) => {
t.equal(
- path,
+ args[0],
resolve(npm.localPrefix),
'should start init package.json in expected path'
)
- cb()
+ args[3]()
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec([])
+ await npm.exec('init', [])
})
t.test('npm init <arg>', async t => {
- t.plan(3)
- npm.localPrefix = t.testdir({})
+ t.plan(1)
- const Init = t.mock('../../../lib/commands/init.js', {
- libnpmexec: ({ args, cache, npxCache }) => {
+ const { npm } = await mockNpm(t, {
+ libnpmexec: ({ args }) => {
t.same(
args,
['create-react-app@*'],
'should npx with listed packages'
)
- t.same(cache, flatOptions.cache)
- t.same(npxCache, flatOptions.npxCache)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['react-app'])
+ await npm.exec('init', ['react-app'])
})
t.test('npm init <arg> -- other-args', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -110,18 +90,16 @@ t.test('npm init <arg> -- other-args', async t => {
'should npm exec with expected args'
)
},
+
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['react-app', 'my-path', '--some-option', 'some-value'])
+ await npm.exec('init', ['react-app', 'my-path', '--some-option', 'some-value'])
})
t.test('npm init @scope/name', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -130,17 +108,14 @@ t.test('npm init @scope/name', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['@npmcli/something'])
+ await npm.exec('init', ['@npmcli/something'])
})
t.test('npm init @scope@spec', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -149,17 +124,14 @@ t.test('npm init @scope@spec', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['@npmcli@foo'])
+ await npm.exec('init', ['@npmcli@foo'])
})
t.test('npm init @scope/name@spec', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -168,17 +140,13 @@ t.test('npm init @scope/name@spec', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['@npmcli/something@foo'])
+ await npm.exec('init', ['@npmcli/something@foo'])
})
t.test('npm init git spec', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
-
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -187,17 +155,14 @@ t.test('npm init git spec', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['npm/something'])
+ await npm.exec('init', ['npm/something'])
})
t.test('npm init @scope', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -206,18 +171,15 @@ t.test('npm init @scope', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['@npmcli'])
+ await npm.exec('init', ['@npmcli'])
})
t.test('npm init tgz', async t => {
- npm.localPrefix = t.testdir({})
+ const { npm } = await mockNpm(t)
- process.chdir(npm.localPrefix)
await t.rejects(
- init.exec(['something.tgz']),
+ npm.exec('init', ['something.tgz']),
/Unrecognized initializer: something.tgz/,
'should throw error when using an unsupported spec'
)
@@ -225,9 +187,8 @@ t.test('npm init tgz', async t => {
t.test('npm init <arg>@next', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: ({ args }) => {
t.same(
args,
@@ -236,25 +197,19 @@ t.test('npm init <arg>@next', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['something@next'])
+ await npm.exec('init', ['something@next'])
})
t.test('npm init exec error', async t => {
- npm.localPrefix = t.testdir({})
-
- const Init = t.mock('../../../lib/commands/init.js', {
- libnpmexec: async ({ args }) => {
+ const { npm } = await mockNpm(t, {
+ libnpmexec: async () => {
throw new Error('ERROR')
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
await t.rejects(
- init.exec(['something@next']),
+ npm.exec('init', ['something@next']),
/ERROR/,
'should exit with exec error'
)
@@ -262,9 +217,8 @@ t.test('npm init exec error', async t => {
t.test('should not rewrite flatOptions', async t => {
t.plan(1)
- npm.localPrefix = t.testdir({})
- const Init = t.mock('../../../lib/commands/init.js', {
+ const { npm } = await mockNpm(t, {
libnpmexec: async ({ args }) => {
t.same(
args,
@@ -273,270 +227,217 @@ t.test('should not rewrite flatOptions', async t => {
)
},
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec(['react-app', 'my-app'])
+ await npm.exec('init', ['react-app', 'my-app'])
})
t.test('npm init cancel', async t => {
- t.plan(2)
- npm.localPrefix = t.testdir({})
-
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- 'init-package-json': (dir, initFile, config, cb) => cb(
+ const { npm, logs } = await mockNpm(t, {
+ initPackageJson: (...args) => args[3](
new Error('canceled')
),
- 'proc-log': {
- ...mocks['proc-log'],
- warn: (title, msg) => {
- t.equal(title, 'init', 'should have init title')
- t.equal(msg, 'canceled', 'should log canceled')
- },
- },
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
- await init.exec([])
+ await npm.exec('init', [])
+
+ t.equal(logs.warn[0][0], 'init', 'should have init title')
+ t.equal(logs.warn[0][1], 'canceled', 'should log canceled')
})
t.test('npm init error', async t => {
- npm.localPrefix = t.testdir({})
-
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- 'init-package-json': (dir, initFile, config, cb) => cb(
+ const { npm } = await mockNpm(t, {
+ initPackageJson: (...args) => args[3](
new Error('Unknown Error')
),
})
- const init = new Init(npm)
- process.chdir(npm.localPrefix)
await t.rejects(
- init.exec([]),
+ npm.exec('init', []),
/Unknown Error/,
'should throw error'
)
})
-t.test('workspaces', t => {
- t.test('no args', async t => {
- t.teardown(() => {
- npm._mockOutputs.length = 0
- })
- npm._mockOutputs.length = 0
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'top-level',
- }),
- })
-
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- 'init-package-json': (dir, initFile, config, cb) => {
- t.equal(dir, resolve(npm.localPrefix, 'a'), 'should use the ws path')
- cb()
+t.test('workspaces', async t => {
+ await t.test('no args -- yes', async t => {
+ const { npm, prefix, joinedOutput } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'top-level',
+ }),
},
+ config: { workspace: 'a', yes: true },
+ noLog: true,
})
- const init = new Init(npm)
- await init.execWorkspaces([], ['a'])
- t.matchSnapshot(npm._mockOutputs, 'should print helper info')
- })
- t.test('post workspace-init reify', async t => {
- const _consolelog = console.log
- console.log = () => null
- t.teardown(() => {
- console.log = _consolelog
- npm._mockOutputs.length = 0
- delete npm.flatOptions.workspacesUpdate
- })
- npm.started = Date.now()
- npm._mockOutputs.length = 0
- npm.flatOptions.workspacesUpdate = true
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'top-level',
- }),
- })
+ await npm.exec('init', [])
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- 'init-package-json': (dir, initFile, config, cb) => {
- t.equal(dir, resolve(npm.localPrefix, 'a'), 'should use the ws path')
- return require('init-package-json')(dir, initFile, config, cb)
- },
- })
- const init = new Init(npm)
- await init.execWorkspaces([], ['a'])
- const output = npm._mockOutputs.map(arr => arr.map(i => i.replace(/[0-9]*m?s$/, '100ms')))
- t.matchSnapshot(output, 'should print helper info')
- const lockFilePath = resolve(npm.localPrefix, 'package-lock.json')
- const lockFile = fs.readFileSync(lockFilePath, { encoding: 'utf8' })
- t.matchSnapshot(lockFile, 'should reify tree on init ws complete')
- })
-
- t.test('no args, existing folder', async t => {
- t.teardown(() => {
- npm._mockOutputs.length = 0
- })
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
+ const pkg = require(resolve(prefix, 'a/package.json'))
+ t.equal(pkg.name, 'a')
+ t.equal(pkg.version, '1.0.0')
+ t.equal(pkg.license, 'ISC')
- npm.localPrefix = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- },
- 'package.json': JSON.stringify({
- name: 'top-level',
- workspaces: ['packages/a'],
- }),
- })
+ t.matchSnapshot(joinedOutput(), 'should print helper info')
- await init.execWorkspaces([], ['packages/a'])
-
- t.matchSnapshot(npm._mockOutputs, 'should print helper info')
+ const lock = require(resolve(prefix, 'package-lock.json'))
+ t.ok(lock.packages.a)
})
- t.test('with arg but missing workspace folder', async t => {
- t.teardown(() => {
- npm._mockOutputs.length = 0
- })
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
-
- npm.localPrefix = t.testdir({
- node_modules: {
- a: t.fixture('symlink', '../a'),
- 'create-index': {
- 'index.js': ``,
+ await t.test('no args, existing folder', async t => {
+ const { npm, prefix } = await mockNpm(t, {
+ prefixDir: {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '2.0.0',
+ }),
+ },
},
- },
- a: {
'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
+ name: 'top-level',
+ workspaces: ['packages/a'],
}),
},
- 'package.json': JSON.stringify({
- name: 'top-level',
- }),
+ config: { workspace: 'packages/a', yes: true },
+ noLog: true,
})
- await init.execWorkspaces([], ['packages/a'])
+ await npm.exec('init', [])
- t.matchSnapshot(npm._mockOutputs, 'should print helper info')
+ const pkg = require(resolve(prefix, 'packages/a/package.json'))
+ t.equal(pkg.name, 'a')
+ t.equal(pkg.version, '2.0.0')
+ t.equal(pkg.license, 'ISC')
})
- t.test('fail parsing top-level package.json to set workspace', async t => {
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
-
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'top-level',
- }),
- })
-
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- '@npmcli/package-json': {
+ await t.test('fail parsing top-level package.json to set workspace', async t => {
+ const { npm } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'top-level',
+ }),
+ },
+ packageJson: {
async load () {
throw new Error('ERR')
},
},
+ config: { workspace: 'a', yes: true },
+ noLog: true,
})
- const init = new Init(npm)
await t.rejects(
- init.execWorkspaces([], ['a']),
+ npm.exec('init', []),
/ERR/,
'should exit with error'
)
})
- t.test('missing top-level package.json when settting workspace', async t => {
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
-
- npm.localPrefix = t.testdir({})
-
- const Init = require('../../../lib/commands/init.js')
- const init = new Init(npm)
+ await t.test('missing top-level package.json when settting workspace', async t => {
+ const { npm, logs } = await mockNpm(t, {
+ config: { workspace: 'a' },
+ })
await t.rejects(
- init.execWorkspaces([], ['a']),
+ npm.exec('init', []),
{ code: 'ENOENT' },
'should exit with missing package.json file error'
)
+
+ t.equal(logs.warn[0][0], 'Missing package.json. Try with `--include-workspace-root`.')
+ })
+
+ await t.test('bad package.json when settting workspace', async t => {
+ const { npm, logs } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': '{{{{',
+ },
+ config: { workspace: 'a' },
+ })
+
+ await t.rejects(
+ npm.exec('init', []),
+ { code: 'EJSONPARSE' },
+ 'should exit with parse file error'
+ )
+
+ t.strictSame(logs.warn, [])
})
- t.test('using args', async t => {
- npm.localPrefix = t.testdir({
- b: {
+ await t.test('using args - no package.json', async t => {
+ const { npm, prefix } = await mockNpm(t, {
+ prefixDir: {
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ }),
+ },
'package.json': JSON.stringify({
- name: 'b',
+ name: 'top-level',
+ workspaces: ['b'],
}),
},
- 'package.json': JSON.stringify({
- name: 'top-level',
- workspaces: ['b'],
- }),
+ // Important: exec did not write a package.json here
+ libnpmexec: async () => {},
+ config: { workspace: 'a', yes: true },
})
- const Init = t.mock('../../../lib/commands/init.js', {
- ...mocks,
- libnpmexec: ({ args, path }) => {
- t.same(
- args,
- ['create-react-app@*'],
- 'should npx with listed packages'
- )
- t.same(
- path,
- resolve(npm.localPrefix, 'a'),
- 'should use workspace path'
- )
- fs.writeFileSync(
- resolve(npm.localPrefix, 'a/package.json'),
- JSON.stringify({ name: 'a' })
- )
+ await npm.exec('init', ['react-app'])
+
+ const pkg = require(resolve(prefix, 'package.json'))
+ t.strictSame(pkg.workspaces, ['b'], 'pkg workspaces did not get updated')
+ })
+
+ await t.test('init template - bad package.json', async t => {
+ const { npm, prefix } = await mockNpm(t, {
+ prefixDir: {
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ }),
+ },
+ 'package.json': JSON.stringify({
+ name: 'top-level',
+ workspaces: ['b'],
+ }),
+ },
+ initPackageJson: async (...args) => {
+ const [dir] = args
+ if (dir.endsWith('c')) {
+ await fs.writeFile(resolve(dir, 'package.json'), JSON.stringify({
+ name: basename(dir),
+ }), 'utf-8')
+ }
+ args[3]()
},
+ config: { yes: true, workspace: ['a', 'c'] },
})
- const init = new Init(npm)
- await init.execWorkspaces(['react-app'], ['a'])
- })
+ await npm.exec('init', [])
- t.end()
-})
+ const pkg = require(resolve(prefix, 'package.json'))
+ t.strictSame(pkg.workspaces, ['b', 'c'])
-t.test('npm init workspces with root', async t => {
- t.teardown(() => {
- npm._mockOutputs.length = 0
+ const lock = require(resolve(prefix, 'package-lock.json'))
+ t.notOk(lock.packages.a)
})
- npm.localPrefix = t.testdir({})
- npm.flatOptions.includeWorkspaceRoot = true
- // init-package-json prints directly to console.log
- // this avoids poluting test output with those logs
- console.log = noop
+ t.test('workspace root', async t => {
+ const { npm } = await mockNpm(t, {
+ config: { workspace: 'packages/a', 'include-workspace-root': true, yes: true },
+ noLog: true,
+ })
+
+ await npm.exec('init', [])
- process.chdir(npm.localPrefix)
- await init.execWorkspaces([], ['packages/a'])
- const pkg = require(resolve(npm.localPrefix, 'package.json'))
- t.equal(pkg.version, '1.0.0')
- t.equal(pkg.license, 'ISC')
- t.matchSnapshot(npm._mockOutputs, 'does not print helper info')
+ const pkg = require(resolve(npm.localPrefix, 'package.json'))
+ t.equal(pkg.version, '1.0.0')
+ t.equal(pkg.license, 'ISC')
+ t.strictSame(pkg.workspaces, ['packages/a'])
+
+ const ws = require(resolve(npm.localPrefix, 'packages/a/package.json'))
+ t.equal(ws.version, '1.0.0')
+ t.equal(ws.license, 'ISC')
+ })
})
diff --git a/deps/npm/test/lib/commands/install.js b/deps/npm/test/lib/commands/install.js
index 4c3251f52f..1be42d6e61 100644
--- a/deps/npm/test/lib/commands/install.js
+++ b/deps/npm/test/lib/commands/install.js
@@ -1,9 +1,5 @@
const t = require('tap')
-
-const { load: _loadMockNpm } = require('../../fixtures/mock-npm')
-
-// Make less churn in the test to pass in mocks only signature
-const loadMockNpm = (t, mocks) => _loadMockNpm(t, { mocks })
+const { load: loadMockNpm } = require('../../fixtures/mock-npm')
t.test('exec commands', async t => {
await t.test('with args, dev=true', async t => {
@@ -13,29 +9,32 @@ t.test('exec commands', async t => {
let ARB_OBJ = null
const { npm } = await loadMockNpm(t, {
- '@npmcli/run-script': ({ event }) => {
- SCRIPTS.push(event)
- },
- '@npmcli/arborist': function (args) {
- ARB_ARGS = args
- ARB_OBJ = this
- this.reify = () => {
- REIFY_CALLED = true
- }
+ mocks: {
+ '@npmcli/run-script': ({ event }) => {
+ SCRIPTS.push(event)
+ },
+ '@npmcli/arborist': function (args) {
+ ARB_ARGS = args
+ ARB_OBJ = this
+ this.reify = () => {
+ REIFY_CALLED = true
+ }
+ },
+ '{LIB}/utils/reify-finish.js': (_, arb) => {
+ if (arb !== ARB_OBJ) {
+ throw new Error('got wrong object passed to reify-finish')
+ }
+ },
},
- '../../lib/utils/reify-finish.js': (npm, arb) => {
- if (arb !== ARB_OBJ) {
- throw new Error('got wrong object passed to reify-finish')
- }
+ config: {
+ // This is here because CI calls tests with `--ignore-scripts`, which config
+ // picks up from argv
+ 'ignore-scripts': false,
+ 'audit-level': 'low',
+ dev: true,
},
})
- // This is here because CI calls tests with `--ignore-scripts`, which config
- // picks up from argv
- npm.config.set('ignore-scripts', false)
- npm.config.set('audit-level', 'low')
- npm.config.set('dev', true)
-
await npm.exec('install', ['fizzbuzz'])
t.match(
@@ -54,24 +53,28 @@ t.test('exec commands', async t => {
let ARB_OBJ = null
const { npm } = await loadMockNpm(t, {
- '@npmcli/run-script': ({ event }) => {
- SCRIPTS.push(event)
- },
- '@npmcli/arborist': function (args) {
- ARB_ARGS = args
- ARB_OBJ = this
- this.reify = () => {
- REIFY_CALLED = true
- }
+ mocks: {
+ '@npmcli/run-script': ({ event }) => {
+ SCRIPTS.push(event)
+ },
+ '@npmcli/arborist': function (args) {
+ ARB_ARGS = args
+ ARB_OBJ = this
+ this.reify = () => {
+ REIFY_CALLED = true
+ }
+ },
+ '{LIB}/utils/reify-finish.js': (_, arb) => {
+ if (arb !== ARB_OBJ) {
+ throw new Error('got wrong object passed to reify-finish')
+ }
+ },
},
- '../../lib/utils/reify-finish.js': (npm, arb) => {
- if (arb !== ARB_OBJ) {
- throw new Error('got wrong object passed to reify-finish')
- }
+ config: {
+
},
})
- npm.config.set('ignore-scripts', false)
await npm.exec('install', [])
t.match(ARB_ARGS, { global: false, path: npm.prefix })
t.equal(REIFY_CALLED, true, 'called reify')
@@ -90,17 +93,22 @@ t.test('exec commands', async t => {
const SCRIPTS = []
let REIFY_CALLED = false
const { npm } = await loadMockNpm(t, {
- '../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/run-script': ({ event }) => {
- SCRIPTS.push(event)
+ mocks: {
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/run-script': ({ event }) => {
+ SCRIPTS.push(event)
+ },
+ '@npmcli/arborist': function () {
+ this.reify = () => {
+ REIFY_CALLED = true
+ }
+ },
},
- '@npmcli/arborist': function () {
- this.reify = () => {
- REIFY_CALLED = true
- }
+ config: {
+ 'ignore-scripts': true,
},
})
- npm.config.set('ignore-scripts', true)
+
await npm.exec('install', [])
t.equal(REIFY_CALLED, true, 'called reify')
t.strictSame(SCRIPTS, [], 'no scripts when adding dep')
@@ -111,18 +119,22 @@ t.test('exec commands', async t => {
let ARB_ARGS = null
let REIFY_CALLED
const { npm } = await loadMockNpm(t, {
- '@npmcli/run-script': ({ event }) => {
- SCRIPTS.push(event)
+ mocks: {
+ '@npmcli/run-script': ({ event }) => {
+ SCRIPTS.push(event)
+ },
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/arborist': function (args) {
+ ARB_ARGS = args
+ this.reify = () => {
+ REIFY_CALLED = true
+ }
+ },
},
- '../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/arborist': function (args) {
- ARB_ARGS = args
- this.reify = () => {
- REIFY_CALLED = true
- }
+ config: {
+ global: true,
},
})
- npm.config.set('global', true)
await npm.exec('install', [])
t.match(
ARB_ARGS,
@@ -130,18 +142,22 @@ t.test('exec commands', async t => {
)
t.equal(REIFY_CALLED, true, 'called reify')
t.strictSame(SCRIPTS, [], 'no scripts when installing globally')
- t.equal(npm.config.get('audit', 'cli'), false)
+ t.notOk(npm.config.get('audit', 'cli'))
})
await t.test('should not install invalid global package name', async t => {
const { npm } = await loadMockNpm(t, {
- '@npmcli/run-script': () => {},
- '../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/arborist': function (args) {
- throw new Error('should not reify')
+ mocks: {
+ '@npmcli/run-script': () => {},
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/arborist': function (args) {
+ throw new Error('should not reify')
+ },
+ },
+ config: {
+ global: true,
},
})
- npm.config.set('global', true)
await t.rejects(
npm.exec('install', ['']),
/Usage:/,
@@ -151,41 +167,49 @@ t.test('exec commands', async t => {
await t.test('npm i -g npm engines check success', async t => {
const { npm } = await loadMockNpm(t, {
- '../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/arborist': function () {
- this.reify = () => {}
- },
- pacote: {
- manifest: () => {
- return {
- version: '100.100.100',
- engines: {
- node: '>1',
- },
- }
+ mocks: {
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/arborist': function () {
+ this.reify = () => {}
+ },
+ pacote: {
+ manifest: () => {
+ return {
+ version: '100.100.100',
+ engines: {
+ node: '>1',
+ },
+ }
+ },
},
},
+ config: {
+ global: true,
+ },
})
- npm.config.set('global', true)
await npm.exec('install', ['npm'])
t.ok('No exceptions happen')
})
await t.test('npm i -g npm engines check failure', async t => {
const { npm } = await loadMockNpm(t, {
- pacote: {
- manifest: () => {
- return {
- _id: 'npm@1.2.3',
- version: '100.100.100',
- engines: {
- node: '>1000',
- },
- }
+ mocks: {
+ pacote: {
+ manifest: () => {
+ return {
+ _id: 'npm@1.2.3',
+ version: '100.100.100',
+ engines: {
+ node: '>1000',
+ },
+ }
+ },
},
},
+ config: {
+ global: true,
+ },
})
- npm.config.set('global', true)
await t.rejects(
npm.exec('install', ['npm']),
{
@@ -205,43 +229,55 @@ t.test('exec commands', async t => {
await t.test('npm i -g npm engines check failure forced override', async t => {
const { npm } = await loadMockNpm(t, {
- '../../lib/utils/reify-finish.js': async () => {},
- '@npmcli/arborist': function () {
- this.reify = () => {}
- },
- pacote: {
- manifest: () => {
- return {
- _id: 'npm@1.2.3',
- version: '100.100.100',
- engines: {
- node: '>1000',
- },
- }
+ mocks: {
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/arborist': function () {
+ this.reify = () => {}
+ },
+ pacote: {
+ manifest: () => {
+ return {
+ _id: 'npm@1.2.3',
+ version: '100.100.100',
+ engines: {
+ node: '>1000',
+ },
+ }
+ },
},
},
+ config: {
+ global: true,
+ force: true,
+ },
})
- npm.config.set('global', true)
- npm.config.set('force', true)
await npm.exec('install', ['npm'])
t.ok('Does not throw')
})
await t.test('npm i -g npm@version engines check failure', async t => {
const { npm } = await loadMockNpm(t, {
- pacote: {
- manifest: () => {
- return {
- _id: 'npm@1.2.3',
- version: '100.100.100',
- engines: {
- node: '>1000',
- },
- }
+ mocks: {
+ '{LIB}/utils/reify-finish.js': async () => {},
+ '@npmcli/arborist': function () {
+ this.reify = () => {}
+ },
+ pacote: {
+ manifest: () => {
+ return {
+ _id: 'npm@1.2.3',
+ version: '100.100.100',
+ engines: {
+ node: '>1000',
+ },
+ }
+ },
},
},
+ config: {
+ global: true,
+ },
})
- npm.config.set('global', true)
await t.rejects(
npm.exec('install', ['npm@100']),
{
@@ -261,138 +297,129 @@ t.test('exec commands', async t => {
})
t.test('completion', async t => {
- const cwd = process.cwd()
- const testdir = t.testdir({
- arborist: {
- 'package.json': '{}',
+ const mockComp = async (t, { noChdir } = {}) => loadMockNpm(t, {
+ command: 'install',
+ prefixDir: {
+ arborist: {
+ 'package.json': '{}',
+ },
+ 'arborist.txt': 'just a file',
+ 'other-dir': { a: 'a' },
},
- 'arborist.txt': 'just a file',
- other: {},
- })
- t.afterEach(() => {
- process.chdir(cwd)
+ ...(noChdir ? { chdir: false } : {}),
})
- t.test('completion to folder - has a match', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('completion to folder - has a match', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: './ar' })
t.strictSame(res, ['arborist'], 'package dir match')
})
- t.test('completion to folder - invalid dir', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
+ await t.test('completion to folder - invalid dir', async t => {
+ const { install } = await mockComp(t, { noChdir: true })
const res = await install.completion({ partialWord: '/does/not/exist' })
t.strictSame(res, [], 'invalid dir: no matching')
})
- t.test('completion to folder - no matches', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('completion to folder - no matches', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: './pa' })
t.strictSame(res, [], 'no name match')
})
- t.test('completion to folder - match is not a package', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('completion to folder - match is not a package', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: './othe' })
t.strictSame(res, [], 'no name match')
})
- t.test('completion to url', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('completion to url', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: 'http://path/to/url' })
t.strictSame(res, [])
})
- t.test('no /', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('no /', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: 'toto' })
t.notOk(res)
})
- t.test('only /', async t => {
- const { npm } = await _loadMockNpm(t, { load: false })
- const install = await npm.cmd('install')
- process.chdir(testdir)
+ await t.test('only /', async t => {
+ const { install } = await mockComp(t)
const res = await install.completion({ partialWord: '/' })
t.strictSame(res, [])
})
})
-t.test('location detection and audit', async () => {
- t.test('audit false without package.json', async t => {
- const { npm } = await _loadMockNpm(t, {
+t.test('location detection and audit', async (t) => {
+ await t.test('audit false without package.json', async t => {
+ const { npm } = await loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
- other: {},
+ 'other-dir': { a: 'a' },
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), false)
})
- t.test('audit true with package.json', async t => {
- const { npm } = await _loadMockNpm(t, {
+
+ await t.test('audit true with package.json', async t => {
+ const { npm } = await loadMockNpm(t, {
prefixDir: {
'package.json': '{ "name": "testpkg", "version": "1.0.0" }',
'readme.txt': 'just a file',
},
})
const install = await npm.cmd('install')
- t.equal(install.npm.config.get('location'), 'project')
+ t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
})
- t.test('audit true without package.json when set', async t => {
- const { npm } = await _loadMockNpm(t, {
+
+ await t.test('audit true without package.json when set', async t => {
+ const { npm } = await loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
- other: {},
+ 'other-dir': { a: 'a' },
},
config: {
- audit: { value: true, where: 'cli' },
+ audit: true,
},
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
})
- t.test('audit true in root config without package.json', async t => {
- const { npm } = await _loadMockNpm(t, {
+
+ await t.test('audit true in root config without package.json', async t => {
+ const { npm } = await loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
- other: {},
- },
- config: {
- audit: { value: true, where: 'builtin' },
+ 'other-dir': { a: 'a' },
},
+ // change npmRoot to get it to use a builtin rc file
+ otherDirs: { npmrc: 'audit=true' },
+ npm: ({ other }) => ({ npmRoot: other }),
})
const install = await npm.cmd('install')
t.equal(install.npm.config.get('location'), 'user')
t.equal(install.npm.config.get('audit'), true)
})
- t.test('test for warning when --global & --audit', async t => {
- const { npm, logs } = await _loadMockNpm(t, {
+
+ await t.test('test for warning when --global & --audit', async t => {
+ const { npm, logs } = await loadMockNpm(t, {
prefixDir: {
// no package.json
'readme.txt': 'just a file',
- other: {},
+ 'other-dir': { a: 'a' },
},
config: {
- audit: { value: true, where: 'cli' },
- global: { value: true, where: 'cli' },
+ audit: true,
+ global: true,
},
})
const install = await npm.cmd('install')
diff --git a/deps/npm/test/lib/commands/link.js b/deps/npm/test/lib/commands/link.js
index d908fa025f..feae75a4b9 100644
--- a/deps/npm/test/lib/commands/link.js
+++ b/deps/npm/test/lib/commands/link.js
@@ -1,95 +1,86 @@
const t = require('tap')
const { resolve, join } = require('path')
const fs = require('fs')
-
const Arborist = require('@npmcli/arborist')
-const { fake: mockNpm, load: fullMockNpm } = require('../../fixtures/mock-npm')
-
-const redactCwd = (path) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
-}
-
-t.cleanSnapshot = (str) => redactCwd(str)
-
-const config = {}
-const npm = mockNpm({
- globalDir: null,
- prefix: null,
- config,
-})
+const { cleanCwd } = require('../../fixtures/clean-snapshot.js')
+const mockNpm = require('../../fixtures/mock-npm')
+
+t.cleanSnapshot = (str) => cleanCwd(str)
+
+const mockLink = async (t, { globalPrefixDir, ...opts } = {}) => {
+ const mock = await mockNpm(t, {
+ ...opts,
+ globalPrefixDir,
+ mocks: {
+ ...opts.mocks,
+ '{LIB}/utils/reify-output.js': async () => {},
+ },
+ })
-const printLinks = async (opts) => {
- let res = ''
- const arb = new Arborist(opts)
- const tree = await arb.loadActual()
- const linkedItems = [...tree.inventory.values()]
- .sort((a, b) => a.pkgid.localeCompare(b.pkgid, 'en'))
- for (const item of linkedItems) {
- if (item.isLink) {
- res += `${item.path} -> ${item.target.path}\n`
+ const printLinks = async ({ global = false } = {}) => {
+ let res = ''
+ const arb = new Arborist(global ? {
+ path: resolve(mock.npm.globalDir, '..'),
+ global: true,
+ } : { path: mock.prefix })
+ const tree = await arb.loadActual()
+ const linkedItems = [...tree.inventory.values()]
+ .sort((a, b) => a.pkgid.localeCompare(b.pkgid, 'en'))
+ for (const item of linkedItems) {
+ if (item.isLink) {
+ res += `${item.path} -> ${item.target.path}\n`
+ }
}
+ return res
}
- return res
-}
-const mocks = {
- '../../../lib/utils/reify-output.js': async () => {},
+ return {
+ ...mock,
+ link: {
+ exec: (args = []) => mock.npm.exec('link', args),
+ completion: (o) => mock.npm.cmd('link').then(c => c.completion(o)),
+ },
+ printLinks,
+ }
}
-const Link = t.mock('../../../lib/commands/link.js', mocks)
-const link = new Link(npm)
-
t.test('link to globalDir when in current working dir of pkg and no args', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
+ const { link, printLinks } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
},
},
- 'test-pkg-link': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'test-pkg-link',
version: '1.0.0',
}),
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'test-pkg-link')
- await link.exec([])
- const links = await printLinks({
- path: resolve(npm.globalDir, '..'),
- global: true,
- })
- t.matchSnapshot(links, 'should create a global link to current pkg')
+ await link.exec()
+ t.matchSnapshot(await printLinks({ global: true }), 'should create a global link to current pkg')
})
t.test('link ws to globalDir when workspace specified and no args', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
+ const { link, printLinks } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
},
},
- 'test-pkg-link': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'test-pkg-link',
version: '1.0.0',
@@ -104,77 +95,68 @@ t.test('link ws to globalDir when workspace specified and no args', async t => {
},
},
},
- })
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'test-pkg-link')
- npm.localPrefix = resolve(testdir, 'test-pkg-link')
-
- // link.workspaces = ['a']
- // link.workspacePaths = [resolve(testdir, 'test-pkg-link/packages/a')]
- await link.execWorkspaces([], ['a'])
- const links = await printLinks({
- path: resolve(npm.globalDir, '..'),
- global: true,
+ config: { workspace: 'a' },
})
- t.matchSnapshot(links, 'should create a global link to current pkg')
+ await link.exec()
+ t.matchSnapshot(await printLinks({ global: true }), 'should create a global link to current pkg')
})
t.test('link global linked pkg to local nm when using args', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- '@myscope': {
- foo: {
- 'package.json': JSON.stringify({
- name: '@myscope/foo',
- version: '1.0.0',
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: '@myscope/bar',
- version: '1.0.0',
- }),
- },
- linked: t.fixture('symlink', '../../../../scoped-linked'),
- },
- a: {
+ const { link, printLinks } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ '@myscope': {
+ foo: {
'package.json': JSON.stringify({
- name: 'a',
+ name: '@myscope/foo',
version: '1.0.0',
}),
},
- b: {
+ bar: {
'package.json': JSON.stringify({
- name: 'b',
+ name: '@myscope/bar',
version: '1.0.0',
}),
},
- 'test-pkg-link': t.fixture('symlink', '../../../test-pkg-link'),
+ linked: t.fixture('symlink', '../../../other/scoped-linked'),
+ },
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
},
+ 'test-pkg-link': t.fixture('symlink', '../../other/test-pkg-link'),
},
},
- 'test-pkg-link': {
- 'package.json': JSON.stringify({
- name: 'test-pkg-link',
- version: '1.0.0',
- }),
- },
- 'link-me-too': {
- 'package.json': JSON.stringify({
- name: 'link-me-too',
- version: '1.0.0',
- }),
- },
- 'scoped-linked': {
- 'package.json': JSON.stringify({
- name: '@myscope/linked',
- version: '1.0.0',
- }),
+ otherDirs: {
+ 'test-pkg-link': {
+ 'package.json': JSON.stringify({
+ name: 'test-pkg-link',
+ version: '1.0.0',
+ }),
+ },
+ 'link-me-too': {
+ 'package.json': JSON.stringify({
+ name: 'link-me-too',
+ version: '1.0.0',
+ }),
+ },
+ 'scoped-linked': {
+ 'package.json': JSON.stringify({
+ name: '@myscope/linked',
+ version: '1.0.0',
+ }),
+ },
},
- 'my-project': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'my-project',
version: '1.0.0',
@@ -192,11 +174,6 @@ t.test('link global linked pkg to local nm when using args', async t => {
},
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'my-project')
-
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
// installs examples for:
// - test-pkg-link: pkg linked to globalDir from local fs
@@ -209,71 +186,67 @@ t.test('link global linked pkg to local nm when using args', async t => {
'@myscope/linked',
'@myscope/bar',
'a',
- 'file:../link-me-too',
+ 'file:../other/link-me-too',
])
- process.chdir(_cwd)
- const links = await printLinks({
- path: npm.prefix,
- })
- t.matchSnapshot(links, 'should create a local symlink to global pkg')
+ t.matchSnapshot(await printLinks(), 'should create a local symlink to global pkg')
})
t.test('link global linked pkg to local workspace using args', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- '@myscope': {
- foo: {
- 'package.json': JSON.stringify({
- name: '@myscope/foo',
- version: '1.0.0',
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: '@myscope/bar',
- version: '1.0.0',
- }),
- },
- linked: t.fixture('symlink', '../../../../scoped-linked'),
- },
- a: {
+ const { link, printLinks } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ '@myscope': {
+ foo: {
'package.json': JSON.stringify({
- name: 'a',
+ name: '@myscope/foo',
version: '1.0.0',
}),
},
- b: {
+ bar: {
'package.json': JSON.stringify({
- name: 'b',
+ name: '@myscope/bar',
version: '1.0.0',
}),
},
- 'test-pkg-link': t.fixture('symlink', '../../../test-pkg-link'),
+ linked: t.fixture('symlink', '../../../other/scoped-linked'),
},
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ },
+ 'test-pkg-link': t.fixture('symlink', '../../other/test-pkg-link'),
},
},
- 'test-pkg-link': {
- 'package.json': JSON.stringify({
- name: 'test-pkg-link',
- version: '1.0.0',
- }),
- },
- 'link-me-too': {
- 'package.json': JSON.stringify({
- name: 'link-me-too',
- version: '1.0.0',
- }),
- },
- 'scoped-linked': {
- 'package.json': JSON.stringify({
- name: '@myscope/linked',
- version: '1.0.0',
- }),
+ otherDirs: {
+ 'test-pkg-link': {
+ 'package.json': JSON.stringify({
+ name: 'test-pkg-link',
+ version: '1.0.0',
+ }),
+ },
+ 'link-me-too': {
+ 'package.json': JSON.stringify({
+ name: 'link-me-too',
+ version: '1.0.0',
+ }),
+ },
+ 'scoped-linked': {
+ 'package.json': JSON.stringify({
+ name: '@myscope/linked',
+ version: '1.0.0',
+ }),
+ },
},
- 'my-project': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'my-project',
version: '1.0.0',
@@ -299,13 +272,8 @@ t.test('link global linked pkg to local workspace using args', async t => {
},
},
},
+ config: { workspace: 'x' },
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'my-project')
- npm.localPrefix = resolve(testdir, 'my-project')
-
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
// installs examples for:
// - test-pkg-link: pkg linked to globalDir from local fs
@@ -313,143 +281,113 @@ t.test('link global linked pkg to local workspace using args', async t => {
// - @myscope/bar: prev installed scoped package available in globalDir
// - a: prev installed package available in globalDir
// - file:./link-me-too: pkg that needs to be reified in globalDir first
- await link.execWorkspaces([
+ await link.exec([
'test-pkg-link',
'@myscope/linked',
'@myscope/bar',
'a',
- 'file:../link-me-too',
- ], ['x'])
- process.chdir(_cwd)
-
- const links = await printLinks({
- path: npm.prefix,
- })
+ 'file:../other/link-me-too',
+ ])
- t.matchSnapshot(links, 'should create a local symlink to global pkg')
+ t.matchSnapshot(await printLinks(), 'should create a local symlink to global pkg')
})
t.test('link pkg already in global space', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- '@myscope': {
- linked: t.fixture('symlink', '../../../../scoped-linked'),
- },
+ const { npm, link, printLinks, prefix } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ '@myscope': {
+ linked: t.fixture('symlink', '../../../other/scoped-linked'),
},
},
},
- 'scoped-linked': {
- 'package.json': JSON.stringify({
- name: '@myscope/linked',
- version: '1.0.0',
- }),
+ otherDirs: {
+ 'scoped-linked': {
+ 'package.json': JSON.stringify({
+ name: '@myscope/linked',
+ version: '1.0.0',
+ }),
+ },
},
- 'my-project': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'my-project',
version: '1.0.0',
}),
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'my-project')
+ // XXX: how to convert this to a config that gets passed in?
npm.config.find = () => 'default'
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
-
- // installs examples for:
- // - test-pkg-link: pkg linked to globalDir from local fs
- // - @myscope/linked: scoped pkg linked to globalDir from local fs
- // - @myscope/bar: prev installed scoped package available in globalDir
- // - a: prev installed package available in globalDir
- // - file:./link-me-too: pkg that needs to be reified in globalDir first
await link.exec(['@myscope/linked'])
- process.chdir(_cwd)
- npm.config.find = () => null
-
- const links = await printLinks({
- path: npm.prefix,
- })
t.equal(
- require(resolve(testdir, 'my-project', 'package.json')).dependencies,
+ require(resolve(prefix, 'package.json')).dependencies,
undefined,
'should not save to package.json upon linking'
)
- t.matchSnapshot(links, 'should create a local symlink to global pkg')
+ t.matchSnapshot(await printLinks(), 'should create a local symlink to global pkg')
})
t.test('link pkg already in global space when prefix is a symlink', async t => {
- const testdir = t.testdir({
- 'global-prefix': t.fixture('symlink', './real-global-prefix'),
- 'real-global-prefix': {
- lib: {
+ const { npm, link, printLinks, prefix } = await mockLink(t, {
+ globalPrefixDir: t.fixture('symlink', './other/real-global-prefix'),
+ otherDirs: {
+ // mockNpm does this automatically but only for globalPrefixDir so here we
+ // need to do it manually since we are making a symlink somewhere else
+ 'real-global-prefix': mockNpm.setGlobalNodeModules({
node_modules: {
'@myscope': {
- linked: t.fixture('symlink', '../../../../scoped-linked'),
+ linked: t.fixture('symlink', '../../../scoped-linked'),
},
},
- },
- },
- 'scoped-linked': {
- 'package.json': JSON.stringify({
- name: '@myscope/linked',
- version: '1.0.0',
}),
+ 'scoped-linked': {
+ 'package.json': JSON.stringify({
+ name: '@myscope/linked',
+ version: '1.0.0',
+ }),
+ },
},
- 'my-project': {
+ prefixDir: {
'package.json': JSON.stringify({
name: 'my-project',
version: '1.0.0',
}),
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'my-project')
npm.config.find = () => 'default'
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
-
await link.exec(['@myscope/linked'])
- process.chdir(_cwd)
- npm.config.find = () => null
-
- const links = await printLinks({
- path: npm.prefix,
- })
t.equal(
- require(resolve(testdir, 'my-project', 'package.json')).dependencies,
+ require(resolve(prefix, 'package.json')).dependencies,
undefined,
'should not save to package.json upon linking'
)
- t.matchSnapshot(links, 'should create a local symlink to global pkg')
+ t.matchSnapshot(await printLinks(), 'should create a local symlink to global pkg')
})
t.test('should not prune dependencies when linking packages', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- linked: t.fixture('symlink', '../../../linked'),
- },
+ const { link, prefix } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ linked: t.fixture('symlink', '../../other/linked'),
},
},
- linked: {
- 'package.json': JSON.stringify({
- name: 'linked',
- version: '1.0.0',
- }),
+ otherDirs: {
+ linked: {
+ 'package.json': JSON.stringify({
+ name: 'linked',
+ version: '1.0.0',
+ }),
+ },
},
- 'my-project': {
+ prefixDir: {
node_modules: {
foo: {
'package.json': JSON.stringify({ name: 'foo', version: '1.0.0' }),
@@ -461,37 +399,29 @@ t.test('should not prune dependencies when linking packages', async t => {
}),
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'my-project')
-
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
await link.exec(['linked'])
t.ok(
- fs.statSync(resolve(testdir, 'my-project/node_modules/foo')),
+ fs.statSync(resolve(prefix, 'node_modules/foo')),
'should not prune any extraneous dep when running npm link'
)
- process.chdir(_cwd)
})
t.test('completion', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- foo: {},
- bar: {},
- lorem: {},
- ipsum: {},
- },
+ const { link } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ foo: {},
+ bar: {},
+ lorem: {},
+ ipsum: {},
},
},
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
const words = await link.completion({})
+
t.same(
words,
['bar', 'foo', 'ipsum', 'lorem'],
@@ -500,13 +430,9 @@ t.test('completion', async t => {
})
t.test('--global option', async t => {
- t.teardown(() => {
- npm.config = _config
+ const { link } = await mockLink(t, {
+ config: { global: true },
})
- const _config = npm.config
- npm.config = { get () {
- return true
- } }
await t.rejects(
link.exec([]),
/link should never be --global/,
@@ -515,44 +441,37 @@ t.test('--global option', async t => {
})
t.test('hash character in working directory path', async t => {
- const testdir = t.testdir({
- 'global-prefix': {
- lib: {
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
+ const { link, printLinks } = await mockLink(t, {
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
},
},
- 'i_like_#_in_my_paths': {
- 'test-pkg-link': {
- 'package.json': JSON.stringify({
- name: 'test-pkg-link',
- version: '1.0.0',
- }),
+ otherDirs: {
+ 'i_like_#_in_my_paths': {
+ 'test-pkg-link': {
+ 'package.json': JSON.stringify({
+ name: 'test-pkg-link',
+ version: '1.0.0',
+ }),
+ },
},
},
+ chdir: ({ other }) => join(other, 'i_like_#_in_my_paths', 'test-pkg-link'),
})
- npm.globalDir = resolve(testdir, 'global-prefix', 'lib', 'node_modules')
- npm.prefix = resolve(testdir, 'i_like_#_in_my_paths', 'test-pkg-link')
-
- link.workspacePaths = null
await link.exec([])
- const links = await printLinks({
- path: resolve(npm.globalDir, '..'),
- global: true,
- })
- t.matchSnapshot(links, 'should create a global link to current pkg, even within path with hash')
+ t.matchSnapshot(await printLinks({ global: true }),
+ 'should create a global link to current pkg, even within path with hash')
})
t.test('test linked installed as symlinks', async t => {
- // fakeMock is insufficient due to lack of flatOptions
- const { npm } = await fullMockNpm(t, {
+ const { link, prefix, printLinks } = await mockLink(t, {
otherDirs: {
mylink: {
'package.json': JSON.stringify({
@@ -563,20 +482,13 @@ t.test('test linked installed as symlinks', async t => {
},
})
- const _cwd = process.cwd()
- process.chdir(npm.prefix)
-
- await npm.exec('link', [
+ await link.exec([
join('file:../other/mylink'),
])
- process.chdir(_cwd)
- const links = await printLinks({
- path: npm.prefix,
- })
- t.ok(fs.lstatSync(join(npm.prefix, 'node_modules', 'mylink')).isSymbolicLink(),
+ t.ok(fs.lstatSync(join(prefix, 'node_modules', 'mylink')).isSymbolicLink(),
'linked path should by symbolic link'
)
- t.matchSnapshot(links, 'linked package should not be installed')
+ t.matchSnapshot(await printLinks(), 'linked package should not be installed')
})
diff --git a/deps/npm/test/lib/commands/ll.js b/deps/npm/test/lib/commands/ll.js
index c39d433812..0977ef4ac5 100644
--- a/deps/npm/test/lib/commands/ll.js
+++ b/deps/npm/test/lib/commands/ll.js
@@ -1,4 +1,5 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
t.test('ll', t => {
t.plan(3)
@@ -13,8 +14,8 @@ t.test('ll', t => {
}
}
- const LL = t.mock('../../../lib/commands/ll.js', {
- '../../../lib/commands/ls.js': LS,
+ const LL = tmock(t, '{LIB}/commands/ll.js', {
+ '{LIB}/commands/ls.js': LS,
})
const ll = new LL({
config: {
diff --git a/deps/npm/test/lib/commands/logout.js b/deps/npm/test/lib/commands/logout.js
index 73fe8028c7..0043bb4c57 100644
--- a/deps/npm/test/lib/commands/logout.js
+++ b/deps/npm/test/lib/commands/logout.js
@@ -1,69 +1,53 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const config = {
- registry: 'https://registry.npmjs.org/',
- scope: '',
-}
-const flatOptions = {
- registry: 'https://registry.npmjs.org/',
- scope: '',
-}
-const npm = mockNpm({ config, flatOptions })
-let result = null
-
-const mockLogout = (otherMocks) => {
- const Logout = t.mock('../../../lib/commands/logout.js', {
- 'npm-registry-fetch': (url, opts) => {
- result = { url, opts }
+const fs = require('fs/promises')
+const npmFetch = require('npm-registry-fetch')
+const mockNpm = require('../../fixtures/mock-npm')
+const { join } = require('path')
+
+const mockLogout = async (t, { userRc = [], ...npmOpts } = {}) => {
+ let result = null
+
+ const mock = await mockNpm(t, {
+ mocks: {
+ // XXX: refactor to use mock registry
+ 'npm-registry-fetch': Object.assign(async (url, opts) => {
+ result = { url, opts }
+ }, npmFetch),
+ },
+ ...npmOpts,
+ homeDir: {
+ '.npmrc': userRc.join('\n'),
},
- ...otherMocks,
})
- return new Logout(npm)
-}
-
-t.afterEach(() => {
- delete flatOptions.token
- result = null
- config.clearCredentialsByURI = null
- config.delete = null
- config.save = null
-})
-
-t.test('token logout', async t => {
- t.plan(5)
-
- flatOptions['//registry.npmjs.org/:_authToken'] = '@foo/'
-
- npm.config.clearCredentialsByURI = registry => {
- t.equal(
- registry,
- 'https://registry.npmjs.org/',
- 'should clear credentials from the expected registry'
- )
- }
- npm.config.save = type => {
- t.equal(type, 'user', 'should save to user config')
+ return {
+ ...mock,
+ logout: { exec: (args) => mock.npm.exec('logout', args) },
+ result: () => result,
+ // get only the message portion of the verbose log from the command
+ logMsg: () => mock.logs.verbose.find(l => l[0] === 'logout')[1],
+ userRc: () => fs.readFile(join(mock.home, '.npmrc'), 'utf-8').then(r => r.trim()),
}
+}
- const logout = mockLogout({
- 'proc-log': {
- verbose: (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- },
- },
+t.test('token logout', async t => {
+ const { logout, logMsg, result, userRc } = await mockLogout(t, {
+ userRc: [
+ '//registry.npmjs.org/:_authToken=@foo/',
+ 'other-config=true',
+ ],
})
await logout.exec([])
+ t.equal(
+ logMsg(),
+ 'clearing token for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+
t.match(
- result,
+ result(),
{
url: '/-/user/token/%40foo%2F',
opts: {
@@ -76,64 +60,30 @@ t.test('token logout', async t => {
},
'should call npm-registry-fetch with expected values'
)
+
+ t.equal(await userRc(), 'other-config=true')
})
t.test('token scoped logout', async t => {
- t.teardown(() => {
- config.scope = ''
- delete flatOptions['//diff-registry.npmjs.com/:_authToken']
- delete flatOptions['//registry.npmjs.org/:_authToken']
- delete config['@myscope:registry']
- delete flatOptions.scope
- result = null
- config.clearCredentialsByURI = null
- config.delete = null
- config.save = null
- })
-
- t.plan(7)
-
- flatOptions['//diff-registry.npmjs.com/:_authToken'] = '@bar/'
- flatOptions['//registry.npmjs.org/:_authToken'] = '@foo/'
- config.scope = '@myscope'
- config['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
- flatOptions.scope = '@myscope'
- flatOptions['@myscope:registry'] = 'https://diff-registry.npmjs.com/'
-
- npm.config.clearCredentialsByURI = registry => {
- t.equal(
- registry,
- 'https://diff-registry.npmjs.com/',
- 'should clear credentials from the expected registry'
- )
- }
-
- npm.config.delete = (ref, type) => {
- t.equal(ref, '@myscope:registry', 'should delete scoped registyr from config')
- t.equal(type, 'user', 'should delete from user config')
- }
-
- npm.config.save = type => {
- t.equal(type, 'user', 'should save to user config')
- }
-
- const logout = mockLogout({
- 'proc-log': {
- verbose: (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://diff-registry.npmjs.com/',
- 'should log message with correct registry'
- )
- },
- },
+ const { logout, logMsg, result, userRc } = await mockLogout(t, {
+ config: { scope: '@myscope' },
+ userRc: [
+ '//diff-registry.npmjs.com/:_authToken=@bar/',
+ '//registry.npmjs.org/:_authToken=@foo/',
+ '@myscope:registry=https://diff-registry.npmjs.com/',
+ ],
})
await logout.exec([])
+ t.equal(
+ logMsg(),
+ 'clearing token for https://diff-registry.npmjs.com/',
+ 'should log message with correct registry'
+ )
+
t.match(
- result,
+ result(),
{
url: '/-/user/token/%40bar%2F',
opts: {
@@ -148,41 +98,32 @@ t.test('token scoped logout', async t => {
},
'should call npm-registry-fetch with expected values'
)
+
+ t.equal(await userRc(), '//registry.npmjs.org/:_authToken=@foo/')
})
t.test('user/pass logout', async t => {
- t.teardown(() => {
- delete flatOptions['//registry.npmjs.org/:username']
- delete flatOptions['//registry.npmjs.org/:_password']
- npm.config.clearCredentialsByURI = null
- npm.config.save = null
- })
- t.plan(2)
-
- flatOptions['//registry.npmjs.org/:username'] = 'foo'
- flatOptions['//registry.npmjs.org/:_password'] = 'bar'
-
- npm.config.clearCredentialsByURI = () => null
- npm.config.save = () => null
-
- const logout = mockLogout({
- 'proc-log': {
- verbose: (title, msg) => {
- t.equal(title, 'logout', 'should have correct log prefix')
- t.equal(
- msg,
- 'clearing user credentials for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- },
- },
+ const { logout, logMsg, userRc } = await mockLogout(t, {
+ userRc: [
+ '//registry.npmjs.org/:username=foo',
+ '//registry.npmjs.org/:_password=bar',
+ 'other-config=true',
+ ],
})
await logout.exec([])
+
+ t.equal(
+ logMsg(),
+ 'clearing user credentials for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+
+ t.equal(await userRc(), 'other-config=true')
})
t.test('missing credentials', async t => {
- const logout = mockLogout()
+ const { logout } = await mockLogout(t)
await t.rejects(
logout.exec([]),
@@ -195,57 +136,35 @@ t.test('missing credentials', async t => {
})
t.test('ignore invalid scoped registry config', async t => {
- t.teardown(() => {
- delete flatOptions.token
- result = null
- config.clearCredentialsByURI = null
- config.delete = null
- config.save = null
- })
- t.plan(4)
-
- flatOptions['//registry.npmjs.org/:_authToken'] = '@foo/'
- config.scope = '@myscope'
- flatOptions['@myscope:registry'] = ''
-
- npm.config.clearCredentialsByURI = registry => {
- t.equal(
- registry,
- 'https://registry.npmjs.org/',
- 'should clear credentials from the expected registry'
- )
- }
-
- npm.config.delete = () => null
- npm.config.save = () => null
-
- const logout = mockLogout({
- 'proc-log': {
- verbose: (title, msg) => {
- t.equal(title, 'logout', 'should have correcct log prefix')
- t.equal(
- msg,
- 'clearing token for https://registry.npmjs.org/',
- 'should log message with correct registry'
- )
- },
- },
+ const { logout, logMsg, result, userRc } = await mockLogout(t, {
+ config: { scope: '@myscope' },
+ userRc: [
+ '//registry.npmjs.org/:_authToken=@foo/',
+ 'other-config=true',
+ ],
})
await logout.exec([])
+ t.equal(
+ logMsg(),
+ 'clearing token for https://registry.npmjs.org/',
+ 'should log message with correct registry'
+ )
+
t.match(
- result,
+ result(),
{
url: '/-/user/token/%40foo%2F',
opts: {
'//registry.npmjs.org/:_authToken': '@foo/',
registry: 'https://registry.npmjs.org/',
- '@myscope:registry': '',
method: 'DELETE',
ignoreBody: true,
},
},
'should call npm-registry-fetch with expected values'
)
+
+ t.equal(await userRc(), 'other-config=true')
})
diff --git a/deps/npm/test/lib/commands/ls.js b/deps/npm/test/lib/commands/ls.js
index b9278dd206..9b77334552 100644
--- a/deps/npm/test/lib/commands/ls.js
+++ b/deps/npm/test/lib/commands/ls.js
@@ -2,17 +2,18 @@
// Consider using t.matchSnapshot on these instead, especially since many
// of them contain the tap testdir folders, which are auto-generated and
// may change when node-tap is updated.
-const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm.js')
-const { resolve } = require('path')
+const t = require('tap')
const { utimesSync } = require('fs')
+const mockNpm = require('../../fixtures/mock-npm.js')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
const touchHiddenPackageLock = prefix => {
const later = new Date(Date.now() + 10000)
utimesSync(`${prefix}/node_modules/.package-lock.json`, later, later)
}
-t.cleanSnapshot = str => str.split(/\r\n/).join('\n')
+t.cleanSnapshot = str => cleanCwd(str)
const simpleNmFixture = {
node_modules: {
@@ -89,775 +90,827 @@ const diffDepTypesNmFixture = {
},
}
-let result = ''
-const LS = t.mock('../../../lib/commands/ls.js', {
- path: {
- ...require('path'),
- sep: '/',
- },
-})
-const config = {
- all: true,
- color: false,
- depth: Infinity,
- global: false,
- json: false,
- link: false,
- location: 'project',
- omit: [],
- parseable: false,
- 'package-lock-only': false,
-}
-const flatOptions = {
- workspacesEnabled: true,
-}
-const npm = mockNpm({
- config,
- flatOptions,
- output: msg => {
- result = msg
- },
-})
-const ls = new LS(npm)
+const mockLs = async (t, { mocks, config, ...opts } = {}) => {
+ const mock = await mockNpm(t, {
+ ...opts,
+ config: {
+ all: true,
+ ...config,
+ },
+ command: 'ls',
+ mocks: {
+ path: {
+ ...require('path'),
+ sep: '/',
+ },
+ ...mocks,
+ },
+ })
-const redactCwd = res =>
- res &&
- res.replace(/\\+/g, '/').replace(new RegExp(__dirname.replace(/\\+/g, '/'), 'gi'), '{CWD}')
+ return {
+ ...mock,
+ result: () => mock.joinedOutput(),
+ }
+}
const redactCwdObj = obj => {
if (Array.isArray(obj)) {
return obj.map(o => redactCwdObj(o))
- } else if (typeof obj === 'string') {
- return redactCwd(obj)
- } else if (!obj) {
- return obj
- } else if (typeof obj === 'object') {
+ }
+ if (obj && typeof obj === 'object') {
return Object.keys(obj).reduce((o, k) => {
o[k] = redactCwdObj(obj[k])
return o
}, {})
- } else {
- return obj
}
+ return typeof obj === 'string' ? cleanCwd(obj) : obj
}
const jsonParse = res => redactCwdObj(JSON.parse(res))
-const cleanUpResult = () => (result = '')
-
-t.test('ls', t => {
- t.beforeEach(cleanUpResult)
- config.json = false
- config.unicode = false
+t.test('ls', async t => {
t.test('no args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ // config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree representation of dependencies structure'
)
})
t.test('missing package.json', async t => {
- npm.prefix = t.testdir({
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree missing name/version of top-level package'
)
})
t.test('workspace and missing optional dep', async t => {
- npm.prefix = npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'root',
- dependencies: {
- foo: '^1.0.0',
- },
- optionalDependencies: {
- bar: '^1.0.0',
- },
- workspaces: ['./baz'],
- }),
- baz: {
+ const config = {
+ 'include-workspace-root': true,
+ workspace: 'baz',
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'baz',
- version: '1.0.0',
+ name: 'root',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ optionalDependencies: {
+ bar: '^1.0.0',
+ },
+ workspaces: ['./baz'],
}),
- },
- node_modules: {
- baz: t.fixture('symlink', '../baz'),
- foo: {
+ baz: {
'package.json': JSON.stringify({
- name: 'foo',
+ name: 'baz',
version: '1.0.0',
}),
},
+ node_modules: {
+ baz: t.fixture('symlink', '../baz'),
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ }),
+ },
+ },
},
})
- npm.flatOptions.includeWorkspaceRoot = true
- t.teardown(() => {
- delete npm.flatOptions.includeWorkspaceRoot
- })
-
- await ls.execWorkspaces([], ['baz'])
- t.matchSnapshot(redactCwd(result), 'should omit missing optional dep')
+ await ls.exec([])
+ t.matchSnapshot(cleanCwd(result()), 'should omit missing optional dep')
})
t.test('extraneous deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output containing problems info')
+ t.matchSnapshot(cleanCwd(result()), 'should output containing problems info')
})
t.test('overridden dep', async t => {
- config.all = true
- t.teardown(() => {
- config.all = false
- })
+ const config = {
+ }
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-overridden',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- overrides: {
- bar: '1.0.0',
- },
- }),
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- dependencies: {
- bar: '^2.0.0',
- },
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-overridden',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ overrides: {
+ bar: '1.0.0',
+ },
+ }),
+ node_modules: {
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ dependencies: {
+ bar: '^2.0.0',
+ },
+ }),
+ },
+ bar: {
+ 'package.json': JSON.stringify({
+ name: 'bar',
+ version: '1.0.0',
+ }),
+ },
},
},
})
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should contain overridden outout')
+ await
+
+ ls.exec([])
+ t.matchSnapshot(cleanCwd(result()), 'should contain overridden outout')
})
t.test('overridden dep w/ color', async t => {
- config.all = true
- npm.color = true
- t.teardown(() => {
- config.all = false
- npm.color = false
- })
+ const config = {
+ color: 'always',
+ }
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-overridden',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- overrides: {
- bar: '1.0.0',
- },
- }),
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- dependencies: {
- bar: '^2.0.0',
- },
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-overridden',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ overrides: {
+ bar: '1.0.0',
+ },
+ }),
+ node_modules: {
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ dependencies: {
+ bar: '^2.0.0',
+ },
+ }),
+ },
+ bar: {
+ 'package.json': JSON.stringify({
+ name: 'bar',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should contain overridden outout')
+ t.matchSnapshot(cleanCwd(result()), 'should contain overridden outout')
})
t.test('with filter arg', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const config = {
+ color: 'always',
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['chai'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree contaning only occurrences of filtered by package and colored output'
)
- npm.color = false
})
t.test('with dot filter arg', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const config = {
+ all: false,
+ depth: 0,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['.'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree contaning only occurrences of filtered by package and colored output'
)
- config.all = true
- config.depth = Infinity
- process.exitCode = 0
})
t.test('with filter arg nested dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['dog'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree contaning only occurrences of filtered package and its ancestors'
)
})
t.test('with multiple filter args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- node_modules: {
- ...simpleNmFixture.node_modules,
- ipsum: {
- 'package.json': JSON.stringify({
- name: 'ipsum',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ ...simpleNmFixture.node_modules,
+ ipsum: {
+ 'package.json': JSON.stringify({
+ name: 'ipsum',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec(['dog@*', 'chai@1.0.0'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
/* eslint-disable-next-line max-len */
'should output tree contaning only occurrences of multiple filtered packages and their ancestors'
)
})
t.test('with missing filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['notadep'])
- t.matchSnapshot(redactCwd(result), 'should output tree containing no dependencies info')
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing no dependencies info')
t.equal(process.exitCode, 1, 'should exit with error code 1')
- process.exitCode = 0
})
t.test('default --depth value should be 0', async t => {
- config.all = false
- config.depth = undefined
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const config = {
+ all: false,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- config.all = true
- config.depth = Infinity
+ t.matchSnapshot(cleanCwd(result()),
+ 'should output tree containing only top-level dependencies')
})
t.test('--depth=0', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const config = {
+ all: false,
+ depth: 0,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- config.all = true
- config.depth = Infinity
+ t.matchSnapshot(cleanCwd(result()),
+ 'should output tree containing only top-level dependencies')
})
t.test('--depth=1', async t => {
- config.all = false
- config.depth = 1
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- e: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- c: '^1.0.0',
- d: '*',
- },
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- }),
- },
- e: {
- 'package.json': JSON.stringify({
- name: 'e',
- version: '1.0.0',
- }),
+ const config = {
+ all: false,
+ depth: 1,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ e: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ c: '^1.0.0',
+ d: '*',
+ },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ }),
+ },
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree containing top-level deps and their deps only'
)
- config.all = true
- config.depth = Infinity
})
t.test('missing/invalid/extraneous', async t => {
t.plan(3)
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([]).catch(err => {
t.equal(err.code, 'ELSPROBLEMS', 'should have error code')
t.equal(
- redactCwd(err.message).replace(/\r\n/g, '\n'),
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls-missing-invalid-extraneous/node_modules/chai\n' +
- 'invalid: foo@1.0.0 {CWD}/tap-testdir-ls-ls-missing-invalid-extraneous/node_modules/foo\n' +
+ cleanCwd(err.message),
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai\n' +
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo\n' +
'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
'should log missing/invalid/extraneous errors'
)
})
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree containing missing, invalid, extraneous labels'
)
})
t.test('colored output', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const config = {
+ color: 'always',
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should have error code')
- t.matchSnapshot(redactCwd(result), 'should output tree containing color info')
- npm.color = false
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing color info')
})
t.test('--dev', async t => {
- flatOptions.omit = ['peer', 'prod', 'optional']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ omit: ['peer', 'prod', 'optional'],
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps')
- flatOptions.omit = []
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing dev deps')
})
t.test('--link', async t => {
- config.link = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- 'linked-dep': '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- 'linked-dep': {
+ const config = {
+ link: true,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'linked-dep',
+ name: 'test-npm-ls',
version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ 'linked-dep': '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
}),
- },
- node_modules: {
- 'linked-dep': t.fixture('symlink', '../linked-dep'),
- ...diffDepTypesNmFixture.node_modules,
+ 'linked-dep': {
+ 'package.json': JSON.stringify({
+ name: 'linked-dep',
+ version: '1.0.0',
+ }),
+ },
+ node_modules: {
+ 'linked-dep': t.fixture('symlink', '../linked-dep'),
+ ...diffDepTypesNmFixture.node_modules,
+ },
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- config.link = false
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing linked deps')
})
t.test('print deduped symlinks', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'print-deduped-symlinks',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^1.0.0',
- },
- }),
- b: {
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'b',
+ name: 'print-deduped-symlinks',
version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ b: '^1.0.0',
+ },
}),
- },
- node_modules: {
- a: {
+ b: {
'package.json': JSON.stringify({
- name: 'a',
+ name: 'b',
version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
}),
},
- b: t.fixture('symlink', '../b'),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ },
+ }),
+ },
+ b: t.fixture('symlink', '../b'),
+ },
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- config.link = false
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing linked deps')
})
t.test('--production', async t => {
- flatOptions.omit = ['dev', 'peer']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: { omit: ['dev', 'peer'] },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing production deps')
- flatOptions.omit = []
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing production deps')
})
t.test('--long', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const config = {
+ long: true,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions')
- config.long = true
+ t.matchSnapshot(cleanCwd(result()), 'should output tree info with descriptions')
})
t.test('--long --depth=0', async t => {
- config.all = false
- config.depth = 0
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const config = {
+ all: false,
+ depth: 0,
+ long: true,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree containing top-level deps with descriptions'
)
- config.all = true
- config.depth = Infinity
- config.long = false
})
t.test('json read problems', async t => {
- npm.prefix = t.testdir({
- 'package.json': '{broken json',
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': '{broken json',
+ },
})
await t.rejects(ls.exec([]), { code: 'EJSONPARSE' }, 'should throw EJSONPARSE error')
- t.matchSnapshot(redactCwd(result), 'should print empty result')
+ t.matchSnapshot(cleanCwd(result()), 'should print empty result')
})
t.test('empty location', async t => {
- npm.prefix = t.testdir({})
+ const { ls, result } = await mockLs(t)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print empty result')
+ t.matchSnapshot(cleanCwd(result()), 'should print empty result')
})
t.test('invalid peer dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^2.0.0', // mismatching version #
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^2.0.0', // mismatching version #
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(ls.exec([]))
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree signaling mismatching peer dep in problems'
)
})
t.test('invalid deduped dep', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'invalid-deduped-dep',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^2.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^2.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
+ const config = {
+ color: 'always',
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'invalid-deduped-dep',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ b: '^2.0.0',
+ },
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^2.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await t.rejects(ls.exec([]))
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree signaling mismatching peer dep in problems'
)
- npm.color = false
})
t.test('deduped missing dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ b: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ },
+ }),
+ },
},
},
})
@@ -867,51 +920,58 @@ t.test('ls', t => {
'should list missing dep problem'
)
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable signaling missing peer dep in problems'
)
})
t.test('unmet peer dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- peerDependencies: {
- 'peer-dep': '*',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ peerDependencies: {
+ 'peer-dep': '*',
+ },
+ }),
+ },
})
await t.rejects(
ls.exec([]),
{ code: 'ELSPROBLEMS', message: 'missing: peer-dep@*, required by test-npm-ls@1.0.0' },
'should have missing peer-dep error msg'
)
- t.matchSnapshot(redactCwd(result), 'should output tree signaling missing peer dep in problems')
+ t.matchSnapshot(cleanCwd(result()),
+ 'should output tree signaling missing peer dep in problems')
})
t.test('unmet optional dep', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'missing-optional-dep': '^1.0.0',
- 'optional-dep': '^2.0.0', // mismatching version #
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const config = { color: 'always' }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'missing-optional-dep': '^1.0.0',
+ 'optional-dep': '^2.0.0', // mismatching version #
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(
ls.exec([]),
@@ -919,116 +979,38 @@ t.test('ls', t => {
'should have invalid dep error msg'
)
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree with empty entry for missing optional deps'
)
- npm.color = false
})
t.test('cycle deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- },
- },
- })
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- })
-
- t.test('cycle deps with filter args', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- },
- },
- })
- await ls.exec(['a'])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- npm.color = false
- })
-
- t.test('with no args dedupe entries', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'dedupe-entries',
- version: '1.0.0',
- dependencies: {
- '@npmcli/a': '^1.0.0',
- '@npmcli/b': '^1.0.0',
- '@npmcli/c': '^1.0.0',
- },
- }),
- node_modules: {
- '@npmcli': {
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ node_modules: {
a: {
'package.json': JSON.stringify({
- name: '@npmcli/a',
+ name: 'a',
version: '1.0.0',
dependencies: {
- '@npmcli/b': '^1.0.0',
+ b: '^1.0.0',
},
}),
},
b: {
'package.json': JSON.stringify({
- name: '@npmcli/b',
- version: '1.1.2',
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: '@npmcli/c',
+ name: 'b',
version: '1.0.0',
dependencies: {
- '@npmcli/b': '^1.0.0',
+ a: '^1.0.0',
},
}),
},
@@ -1036,400 +1018,509 @@ t.test('ls', t => {
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
})
- t.test('with no args dedupe entries and not displaying all', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'dedupe-entries',
- version: '1.0.0',
- dependencies: {
- '@npmcli/a': '^1.0.0',
- '@npmcli/b': '^1.0.0',
- '@npmcli/c': '^1.0.0',
- },
- }),
- node_modules: {
- '@npmcli': {
+ t.test('cycle deps with filter args', async t => {
+ const config = { color: 'always' }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ node_modules: {
a: {
'package.json': JSON.stringify({
- name: '@npmcli/a',
+ name: 'a',
version: '1.0.0',
dependencies: {
- '@npmcli/b': '^1.0.0',
+ b: '^1.0.0',
},
}),
},
b: {
'package.json': JSON.stringify({
- name: '@npmcli/b',
- version: '1.1.2',
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: '@npmcli/c',
+ name: 'b',
version: '1.0.0',
dependencies: {
- '@npmcli/b': '^1.0.0',
+ a: '^1.0.0',
},
}),
},
},
},
})
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- config.all = true
- config.depth = Infinity
+ await ls.exec(['a'])
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
})
- t.test('with args and dedupe entries', async t => {
- npm.color = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'dedupe-entries',
- version: '1.0.0',
- dependencies: {
- '@npmcli/a': '^1.0.0',
- '@npmcli/b': '^1.0.0',
- '@npmcli/c': '^1.0.0',
+ t.test('with no args dedupe entries', async t => {
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'dedupe-entries',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/a': '^1.0.0',
+ '@npmcli/b': '^1.0.0',
+ '@npmcli/c': '^1.0.0',
+ },
+ }),
+ node_modules: {
+ '@npmcli': {
+ a: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/a',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/b',
+ version: '1.1.2',
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/c',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
+ },
},
- }),
- node_modules: {
- '@npmcli': {
- a: {
- 'package.json': JSON.stringify({
- name: '@npmcli/a',
- version: '1.0.0',
- dependencies: {
- '@npmcli/b': '^1.0.0',
- },
- }),
+ },
+ })
+ await ls.exec([])
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
+ })
+
+ t.test('with no args dedupe entries and not displaying all', async t => {
+ const config = {
+ all: false,
+ depth: 0,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'dedupe-entries',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/a': '^1.0.0',
+ '@npmcli/b': '^1.0.0',
+ '@npmcli/c': '^1.0.0',
},
- b: {
- 'package.json': JSON.stringify({
- name: '@npmcli/b',
- version: '1.1.2',
- }),
+ }),
+ node_modules: {
+ '@npmcli': {
+ a: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/a',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/b',
+ version: '1.1.2',
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/c',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
},
- c: {
- 'package.json': JSON.stringify({
- name: '@npmcli/c',
- version: '1.0.0',
- dependencies: {
- '@npmcli/b': '^1.0.0',
- },
- }),
+ },
+ },
+ })
+ await ls.exec([])
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
+ })
+
+ t.test('with args and dedupe entries', async t => {
+ const config = { color: 'always' }
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'dedupe-entries',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/a': '^1.0.0',
+ '@npmcli/b': '^1.0.0',
+ '@npmcli/c': '^1.0.0',
+ },
+ }),
+ node_modules: {
+ '@npmcli': {
+ a: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/a',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/b',
+ version: '1.1.2',
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/c',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/b': '^1.0.0',
+ },
+ }),
+ },
},
},
},
})
await ls.exec(['@npmcli/b'])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
- npm.color = false
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
})
t.test('with args and different order of items', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'dedupe-entries',
- version: '1.0.0',
- dependencies: {
- '@npmcli/a': '^1.0.0',
- '@npmcli/b': '^1.0.0',
- '@npmcli/c': '^1.0.0',
- },
- }),
- node_modules: {
- '@npmcli': {
- a: {
- 'package.json': JSON.stringify({
- name: '@npmcli/a',
- version: '1.0.0',
- dependencies: {
- '@npmcli/c': '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: '@npmcli/b',
- version: '1.1.2',
- dependencies: {
- '@npmcli/c': '^1.0.0',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'dedupe-entries',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/a': '^1.0.0',
+ '@npmcli/b': '^1.0.0',
+ '@npmcli/c': '^1.0.0',
},
- c: {
- 'package.json': JSON.stringify({
- name: '@npmcli/c',
- version: '1.0.0',
- }),
+ }),
+ node_modules: {
+ '@npmcli': {
+ a: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/a',
+ version: '1.0.0',
+ dependencies: {
+ '@npmcli/c': '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/b',
+ version: '1.1.2',
+ dependencies: {
+ '@npmcli/c': '^1.0.0',
+ },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: '@npmcli/c',
+ version: '1.0.0',
+ }),
+ },
},
},
},
})
await ls.exec(['@npmcli/c'])
- t.matchSnapshot(redactCwd(result), 'should print tree output containing deduped ref')
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output containing deduped ref')
})
t.test('using aliases', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: 'npm:b@1.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/a': {
+ const { npm, result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: 'npm:b@1.0.0',
+ },
+ }),
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/a': {
+ name: 'b',
+ version: '1.0.0',
+ from: 'a@npm:b',
+ resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
+ requested: {
+ type: 'alias',
+ },
+ },
+ },
+ }),
+ a: {
+ 'package.json': JSON.stringify({
name: 'b',
version: '1.0.0',
- from: 'a@npm:b',
- resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
- requested: {
+ _from: 'a@npm:b',
+ _resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
+ _requested: {
type: 'alias',
},
- },
+ }),
},
- }),
- a: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- _from: 'a@npm:b',
- _resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
- _requested: {
- type: 'alias',
- },
- }),
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing aliases')
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing aliases')
})
t.test('resolved points to git ref', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/abbrev': {
- name: 'abbrev',
- version: '1.1.1',
- from: 'git+https://github.com/isaacs/abbrev-js.git',
- /* eslint-disable-next-line max-len */
- resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
},
}),
- abbrev: {
- 'package.json': JSON.stringify({
- name: 'abbrev',
- version: '1.1.1',
- _id: 'abbrev@1.1.1',
- _from: 'git+https://github.com/isaacs/abbrev-js.git',
- /* eslint-disable-next-line max-len */
- _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- _requested: {
- type: 'git',
- raw: 'git+https:github.com/isaacs/abbrev-js.git',
- rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
- saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
- fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
- gitCommittish: null,
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/abbrev': {
+ name: 'abbrev',
+ version: '1.1.1',
+ from: 'git+https://github.com/isaacs/abbrev-js.git',
+ /* eslint-disable-next-line max-len */
+ resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ },
},
}),
+ abbrev: {
+ 'package.json': JSON.stringify({
+ name: 'abbrev',
+ version: '1.1.1',
+ _id: 'abbrev@1.1.1',
+ _from: 'git+https://github.com/isaacs/abbrev-js.git',
+ /* eslint-disable-next-line max-len */
+ _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ _requested: {
+ type: 'git',
+ raw: 'git+https:github.com/isaacs/abbrev-js.git',
+ rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
+ saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
+ fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
+ gitCommittish: null,
+ },
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing git refs')
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing git refs')
})
t.test('broken resolved field', async t => {
- npm.prefix = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.1',
- }),
- },
- },
- 'package-lock.json': JSON.stringify({
- name: 'npm-broken-resolved-field-test',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- packages: {
- '': {
- name: 'a',
- version: '1.0.1',
- },
- },
- dependencies: {
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ node_modules: {
a: {
- version: '1.0.1',
- resolved: 'foo@dog://b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.1',
+ }),
},
},
- }),
- 'package.json': JSON.stringify({
- name: 'npm-broken-resolved-field-test',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.1',
- },
- }),
+ 'package-lock.json': JSON.stringify({
+ name: 'npm-broken-resolved-field-test',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'a',
+ version: '1.0.1',
+ },
+ },
+ dependencies: {
+ a: {
+ version: '1.0.1',
+ resolved: 'foo@dog://b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ },
+ },
+ }),
+ 'package.json': JSON.stringify({
+ name: 'npm-broken-resolved-field-test',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.1',
+ },
+ }),
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should NOT print git refs in output tree')
+ t.matchSnapshot(cleanCwd(result()), 'should NOT print git refs in output tree')
})
t.test('from and resolved properties', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'simple-output': '^2.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/simple-output': {
- name: 'simple-output',
- version: '2.1.1',
- resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
- shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'simple-output': '^2.0.0',
},
}),
- 'simple-output': {
- 'package.json': JSON.stringify({
- name: 'simple-output',
- version: '2.1.1',
- _from: 'simple-output',
- _id: 'simple-output@2.1.1',
- _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
- _requested: {
- type: 'tag',
- registry: true,
- raw: 'simple-output',
- name: 'simple-output',
- escapedName: 'simple-output',
- rawSpec: '',
- saveSpec: null,
- fetchSpec: 'latest',
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/simple-output': {
+ name: 'simple-output',
+ version: '2.1.1',
+ resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
+ shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
+ },
},
- _requiredBy: ['#USER', '/'],
- _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
- _spec: 'simple-output',
}),
+ 'simple-output': {
+ 'package.json': JSON.stringify({
+ name: 'simple-output',
+ version: '2.1.1',
+ _from: 'simple-output',
+ _id: 'simple-output@2.1.1',
+ _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
+ _requested: {
+ type: 'tag',
+ registry: true,
+ raw: 'simple-output',
+ name: 'simple-output',
+ escapedName: 'simple-output',
+ rawSpec: '',
+ saveSpec: null,
+ fetchSpec: 'latest',
+ },
+ _requiredBy: ['#USER', '/'],
+ _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
+ _spec: 'simple-output',
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should not be printed in tree output')
+ t.matchSnapshot(cleanCwd(result()), 'should not be printed in tree output')
})
t.test('global', async t => {
- config.global = true
- const fixtures = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- node_modules: {
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
+ const config = {
+ global: true,
+ }
+ const { result, ls } = await mockLs(t, {
+ config,
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ node_modules: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
},
},
},
},
})
- // mimics lib/npm.js globalDir getter but pointing to fixtures
- npm.globalDir = resolve(fixtures, 'node_modules')
-
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print tree and not mark top-level items extraneous')
- npm.globalDir = 'MISSING_GLOBAL_DIR'
- config.global = false
+ t.matchSnapshot(cleanCwd(result()),
+ 'should print tree and not mark top-level items extraneous')
})
t.test('filtering by child of missing dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'filter-by-child-of-missing-dep',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- node_modules: {
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- c: '^1.0.0',
- },
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- dependencies: {
- c: '^2.0.0',
- },
- }),
- node_modules: {
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '2.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'filter-by-child-of-missing-dep',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ c: '^1.0.0',
+ },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ dependencies: {
+ c: '^2.0.0',
+ },
+ }),
+ node_modules: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '2.0.0',
+ }),
+ },
},
},
},
@@ -1438,772 +1529,830 @@ t.test('ls', t => {
await ls.exec(['c'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should print tree and not duplicate child of missing items'
)
})
t.test('loading a tree containing workspaces', async t => {
- npm.localPrefix = npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'workspaces-tree',
- version: '1.0.0',
- workspaces: ['./a', './b', './d', './group/*'],
- dependencies: { pacote: '1.0.0' },
- }),
- node_modules: {
- a: t.fixture('symlink', '../a'),
- b: t.fixture('symlink', '../b'),
- c: {
+ const mockWorkspaces = async (t, exec = [], config = {}) => {
+ const { result, ls } = await mockLs(t, {
+ config,
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'c',
+ name: 'workspaces-tree',
version: '1.0.0',
+ workspaces: ['./a', './b', './d', './group/*'],
+ dependencies: { pacote: '1.0.0' },
}),
- },
- d: t.fixture('symlink', '../d'),
- e: t.fixture('symlink', '../group/e'),
- f: t.fixture('symlink', '../group/f'),
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- dependencies: {
- bar: '^1.0.0',
+ node_modules: {
+ a: t.fixture('symlink', '../a'),
+ b: t.fixture('symlink', '../b'),
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
+ d: t.fixture('symlink', '../d'),
+ e: t.fixture('symlink', '../group/e'),
+ f: t.fixture('symlink', '../group/f'),
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ dependencies: {
+ bar: '^1.0.0',
+ },
+ }),
+ },
+ bar: {
+ 'package.json': JSON.stringify({ name: 'bar', version: '1.0.0' }),
+ },
+ baz: {
+ 'package.json': JSON.stringify({ name: 'baz', version: '1.0.0' }),
+ },
+ pacote: {
+ 'package.json': JSON.stringify({ name: 'pacote', version: '1.0.0' }),
},
- }),
- },
- bar: {
- 'package.json': JSON.stringify({ name: 'bar', version: '1.0.0' }),
- },
- baz: {
- 'package.json': JSON.stringify({ name: 'baz', version: '1.0.0' }),
- },
- pacote: {
- 'package.json': JSON.stringify({ name: 'pacote', version: '1.0.0' }),
- },
- },
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- c: '^1.0.0',
- d: '^1.0.0',
},
- devDependencies: {
- baz: '^1.0.0',
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ c: '^1.0.0',
+ d: '^1.0.0',
+ },
+ devDependencies: {
+ baz: '^1.0.0',
+ },
+ }),
},
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- dependencies: {
- foo: '^1.1.1',
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.1.1',
+ },
+ }),
+ },
+ group: {
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ version: '1.0.0',
+ }),
+ },
+ f: {
+ 'package.json': JSON.stringify({
+ name: 'f',
+ version: '1.0.0',
+ }),
+ },
},
- }),
- },
- group: {
- e: {
- 'package.json': JSON.stringify({
- name: 'e',
- version: '1.0.0',
- }),
- },
- f: {
- 'package.json': JSON.stringify({
- name: 'f',
- version: '1.0.0',
- }),
},
- },
- })
+ })
- config.all = false
- config.depth = 0
- npm.color = true
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should list workspaces properly with default configs')
+ await ls.exec(exec)
- config.all = false
- config.depth = 0
- npm.color = true
- npm.flatOptions.workspacesEnabled = false
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should not list workspaces with --no-workspaces')
+ t.matchSnapshot(cleanCwd(result(), t), 'output')
+ }
+
+ t.test('should list workspaces properly with default configs', t => mockWorkspaces(t, [], {
+ depth: 0,
+ color: 'always',
+ }))
- config.all = true
- config.depth = Infinity
- npm.color = false
- npm.flatOptions.workspacesEnabled = true
+ t.test('should not list workspaces with --no-workspaces', t => mockWorkspaces(t, [], {
+ depth: 0,
+ color: 'always',
+ workspaces: false,
+ }))
// --all
- await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should list --all workspaces properly')
+ t.test('should list --all workspaces properly', t => mockWorkspaces(t))
// --production
- flatOptions.omit = ['dev', 'peer', 'optional']
- await ls.exec([])
-
- t.matchSnapshot(redactCwd(result), 'should list only prod deps of workspaces')
-
- flatOptions.omit = []
+ t.test('should list only prod deps of workspaces', t => mockWorkspaces(t, [], {
+ omit: ['dev', 'peer', 'optional'],
+ }))
// filter out a single workspace using args
- await ls.exec(['d'])
- t.matchSnapshot(redactCwd(result), 'should filter single workspace')
+ t.test('should filter single workspace', t => mockWorkspaces(t, ['d']))
// filter out a single workspace and its deps using workspaces filters
- await ls.execWorkspaces([], ['a'])
-
- t.matchSnapshot(redactCwd(result), 'should filter using workspace config')
+ t.test('should filter using workspace config', t => mockWorkspaces(t, [], {
+ workspace: 'a',
+ }))
// filter out a single workspace and include root
- npm.flatOptions.includeWorkspaceRoot = true
- await ls.execWorkspaces([], ['d'])
- t.matchSnapshot(redactCwd(result), 'should inlude root and specified workspace')
- npm.flatOptions.includeWorkspaceRoot = false
+ t.test('should inlude root and specified workspace', t => mockWorkspaces(t, [], {
+ 'include-workspace-root': true,
+ workspace: 'd',
+ }))
// filter out a workspace by parent path
- await ls.execWorkspaces([], ['./group'])
-
- t.matchSnapshot(redactCwd(result), 'should filter by parent folder workspace config')
+ t.test('should filter by parent folder workspace config', t => mockWorkspaces(t, [], {
+ workspace: './group',
+ }))
// filter by a dep within a workspaces sub tree
- await ls.execWorkspaces(['bar'], ['d'])
-
- t.matchSnapshot(
- redactCwd(result),
- 'should print all tree and filter by dep within only the ws subtree'
- )
+ t.test('should print all tree and filter by dep within only the ws subtree', t =>
+ mockWorkspaces(t, ['bar'], {
+ workspace: 'd',
+ }))
})
t.test('filter pkg arg using depth option', async t => {
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-pkg-arg-filter-with-depth-opt',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- b: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
+ const mock = async (t, exec, depth = 0) => {
+ const { result, ls } = await mockLs(t, {
+ config: typeof depth === 'number' ? { depth } : {},
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
+ name: 'test-pkg-arg-filter-with-depth-opt',
version: '1.0.0',
dependencies: {
- c: '^1.0.0',
+ a: '^1.0.0',
+ b: '^1.0.0',
},
}),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- dependencies: {
- d: '^1.0.0',
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ c: '^1.0.0',
+ },
+ }),
},
- }),
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ dependencies: {
+ d: '^1.0.0',
+ },
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ },
+ },
},
- },
- })
+ })
- t.plan(3)
- await ls.exec(['a'])
- t.matchSnapshot(redactCwd(result), 'should list a in top-level only')
+ await ls.exec(exec)
- await ls.exec(['d'])
- t.matchSnapshot(redactCwd(result), 'should print empty results msg')
+ t.matchSnapshot(cleanCwd(result(), t), 'output')
+ }
- // if no --depth config is defined, should print path to dep
- config.depth = null // default config value
- await ls.exec(['d'])
- t.matchSnapshot(redactCwd(result), 'should print expected result')
- process.exitCode = 0
- })
+ t.test('should list a in top-level only', t => mock(t, ['a']))
- t.teardown(() => {
- config.depth = Infinity
- })
+ t.test('should print empty results msg', t => mock(t, ['d']))
- t.end()
+ // if no --depth config is defined, should print path to dep
+ t.test('should print expected result', t => mock(t, ['d'], null))
+ })
})
-t.test('ls --parseable', t => {
- t.beforeEach(cleanUpResult)
- config.json = false
- config.unicode = false
- config.parseable = true
+t.test('ls --parseable', async t => {
+ const parseable = { parseable: true }
t.test('no args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable representation of dependencies structure'
)
})
t.test('missing package.json', async t => {
- npm.prefix = t.testdir({
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable missing name/version of top-level package'
)
})
t.test('extraneous deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output containing problems info')
+ t.matchSnapshot(cleanCwd(result()), 'should output containing problems info')
})
t.test('overridden dep', async t => {
- config.all = true
- config.long = true
- t.teardown(() => {
- config.all = false
- config.long = false
- })
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-overridden',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- overrides: {
- bar: '1.0.0',
- },
- }),
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- dependencies: {
- bar: '^2.0.0',
- },
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: { ...parseable, long: true },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-overridden',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ overrides: {
+ bar: '1.0.0',
+ },
+ }),
+ node_modules: {
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ dependencies: {
+ bar: '^2.0.0',
+ },
+ }),
+ },
+ bar: {
+ 'package.json': JSON.stringify({
+ name: 'bar',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should contain overridden outout')
+ t.matchSnapshot(cleanCwd(result()), 'should contain overridden outout')
})
t.test('with filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['chai'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable contaning only occurrences of filtered by package'
)
})
t.test('with filter arg nested dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['dog'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable contaning only occurrences of filtered package'
)
})
t.test('with multiple filter args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- node_modules: {
- ...simpleNmFixture.node_modules,
- ipsum: {
- 'package.json': JSON.stringify({
- name: 'ipsum',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ ...simpleNmFixture.node_modules,
+ ipsum: {
+ 'package.json': JSON.stringify({
+ name: 'ipsum',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec(['dog@*', 'chai@1.0.0'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
/* eslint-disable-next-line max-len */
'should output parseable contaning only occurrences of multiple filtered packages and their ancestors'
)
})
t.test('with missing filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['notadep'])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable output containing no dependencies info'
)
})
t.test('default --depth value should be 0', async t => {
- config.all = false
- config.depth = undefined
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: { ...parseable, all: false },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable output containing only top-level dependencies'
)
- config.all = true
- config.depth = Infinity
})
t.test('--depth=0', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: { ...parseable, all: false, depth: 0 },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing only top-level dependencies')
- config.all = true
- config.depth = Infinity
+ t.matchSnapshot(cleanCwd(result()),
+ 'should output tree containing only top-level dependencies')
})
t.test('--depth=1', async t => {
- config.all = false
- config.depth = 1
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: { ...parseable, all: false, depth: 1 },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable containing top-level deps and their deps only'
)
- config.all = true
- config.depth = Infinity
})
t.test('missing/invalid/extraneous', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: parseable,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should list dep problems')
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable containing top-level deps and their deps only'
)
})
t.test('--dev', async t => {
- flatOptions.omit = ['peer', 'prod', 'optional']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ omit: ['peer', 'prod', 'optional'],
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing dev deps')
- flatOptions.omit = []
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing dev deps')
})
t.test('--link', async t => {
- config.link = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- 'linked-dep': '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- 'linked-dep': {
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ link: true,
+ },
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'linked-dep',
+ name: 'test-npm-ls',
version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ 'linked-dep': '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
}),
- },
- node_modules: {
- 'linked-dep': t.fixture('symlink', '../linked-dep'),
- ...diffDepTypesNmFixture.node_modules,
+ 'linked-dep': {
+ 'package.json': JSON.stringify({
+ name: 'linked-dep',
+ version: '1.0.0',
+ }),
+ },
+ node_modules: {
+ 'linked-dep': t.fixture('symlink', '../linked-dep'),
+ ...diffDepTypesNmFixture.node_modules,
+ },
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing linked deps')
- config.link = false
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing linked deps')
})
t.test('--production', async t => {
- flatOptions.omit = ['dev', 'peer']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ omit: ['dev', 'peer'],
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing production deps')
- flatOptions.omit = []
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing production deps')
})
t.test('--long', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree info with descriptions')
- config.long = true
+ t.matchSnapshot(cleanCwd(result()), 'should output tree info with descriptions')
})
t.test('--long with extraneous deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output long parseable output with extraneous info')
+ t.matchSnapshot(cleanCwd(result()), 'should output long parseable output with extraneous info')
})
t.test('--long missing/invalid/extraneous', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should list dep problems')
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable result containing EXTRANEOUS/INVALID labels'
)
- config.long = false
})
t.test('--long print symlink target location', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- 'linked-dep': '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- 'linked-dep': {
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ long: true,
+ },
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'linked-dep',
+ name: 'test-npm-ls',
version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ 'linked-dep': '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
}),
- },
- node_modules: {
- 'linked-dep': t.fixture('symlink', '../linked-dep'),
- ...diffDepTypesNmFixture.node_modules,
+ 'linked-dep': {
+ 'package.json': JSON.stringify({
+ name: 'linked-dep',
+ version: '1.0.0',
+ }),
+ },
+ node_modules: {
+ 'linked-dep': t.fixture('symlink', '../linked-dep'),
+ ...diffDepTypesNmFixture.node_modules,
+ },
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output parseable results with symlink targets')
- config.long = false
+ t.matchSnapshot(cleanCwd(result()), 'should output parseable results with symlink targets')
})
t.test('--long --depth=0', async t => {
- config.all = false
- config.depth = 0
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ all: false,
+ depth: 0,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output tree containing top-level deps with descriptions'
)
- config.all = true
- config.depth = Infinity
- config.long = false
})
t.test('json read problems', async t => {
- npm.prefix = t.testdir({
- 'package.json': '{broken json',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': '{broken json',
+ },
})
await t.rejects(ls.exec([]), { code: 'EJSONPARSE' }, 'should throw EJSONPARSE error')
- t.matchSnapshot(redactCwd(result), 'should print empty result')
+ t.matchSnapshot(cleanCwd(result()), 'should print empty result')
})
t.test('empty location', async t => {
- npm.prefix = t.testdir({})
+ const { ls, result } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ })
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print empty result')
+ t.matchSnapshot(cleanCwd(result()), 'should print empty result')
})
t.test('unmet peer dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^2.0.0', // mismatching version #
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^2.0.0', // mismatching version #
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(ls.exec([]))
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable signaling missing peer dep in problems'
)
})
t.test('unmet optional dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'missing-optional-dep': '^1.0.0',
- 'optional-dep': '^2.0.0', // mismatching version #
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'missing-optional-dep': '^1.0.0',
+ 'optional-dep': '^2.0.0', // mismatching version #
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(
ls.exec([]),
@@ -2211,326 +2360,340 @@ t.test('ls --parseable', t => {
'should have invalid dep error msg'
)
t.matchSnapshot(
- redactCwd(result),
+ cleanCwd(result()),
'should output parseable with empty entry for missing optional deps'
)
})
t.test('cycle deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ },
},
},
})
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print tree output omitting deduped ref')
+ t.matchSnapshot(cleanCwd(result()), 'should print tree output omitting deduped ref')
})
t.test('using aliases', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: 'npm:b@1.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/a': {
- name: 'b',
- version: '1.0.0',
- resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: 'npm:b@1.0.0',
},
}),
- a: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- _from: 'a@npm:b',
- _resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
- _requested: {
- type: 'alias',
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/a': {
+ name: 'b',
+ version: '1.0.0',
+ resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
+ },
},
}),
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ _from: 'a@npm:b',
+ _resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
+ _requested: {
+ type: 'alias',
+ },
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing aliases')
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing aliases')
})
t.test('resolved points to git ref', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/abbrev': {
- name: 'abbrev',
- version: '1.1.1',
- /* eslint-disable-next-line max-len */
- resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
},
}),
- abbrev: {
- 'package.json': JSON.stringify({
- name: 'abbrev',
- version: '1.1.1',
- _id: 'abbrev@1.1.1',
- _from: 'git+https://github.com/isaacs/abbrev-js.git',
- /* eslint-disable-next-line max-len */
- _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- _requested: {
- type: 'git',
- raw: 'git+https:github.com/isaacs/abbrev-js.git',
- rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
- saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
- fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
- gitCommittish: null,
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/abbrev': {
+ name: 'abbrev',
+ version: '1.1.1',
+ /* eslint-disable-next-line max-len */
+ resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ },
},
}),
+ abbrev: {
+ 'package.json': JSON.stringify({
+ name: 'abbrev',
+ version: '1.1.1',
+ _id: 'abbrev@1.1.1',
+ _from: 'git+https://github.com/isaacs/abbrev-js.git',
+ /* eslint-disable-next-line max-len */
+ _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ _requested: {
+ type: 'git',
+ raw: 'git+https:github.com/isaacs/abbrev-js.git',
+ rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
+ saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
+ fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
+ gitCommittish: null,
+ },
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should output tree containing git refs')
+ t.matchSnapshot(cleanCwd(result()), 'should output tree containing git refs')
})
t.test('from and resolved properties', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'simple-output': '^2.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/simple-output': {
- name: 'simple-output',
- version: '2.1.1',
- resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
- shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...parseable,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'simple-output': '^2.0.0',
},
}),
- 'simple-output': {
- 'package.json': JSON.stringify({
- name: 'simple-output',
- version: '2.1.1',
- _from: 'simple-output',
- _id: 'simple-output@2.1.1',
- _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
- _requested: {
- type: 'tag',
- registry: true,
- raw: 'simple-output',
- name: 'simple-output',
- escapedName: 'simple-output',
- rawSpec: '',
- saveSpec: null,
- fetchSpec: 'latest',
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/simple-output': {
+ name: 'simple-output',
+ version: '2.1.1',
+ resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
+ shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
+ },
},
- _requiredBy: ['#USER', '/'],
- _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
- _spec: 'simple-output',
}),
+ 'simple-output': {
+ 'package.json': JSON.stringify({
+ name: 'simple-output',
+ version: '2.1.1',
+ _from: 'simple-output',
+ _id: 'simple-output@2.1.1',
+ _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
+ _requested: {
+ type: 'tag',
+ registry: true,
+ raw: 'simple-output',
+ name: 'simple-output',
+ escapedName: 'simple-output',
+ rawSpec: '',
+ saveSpec: null,
+ fetchSpec: 'latest',
+ },
+ _requiredBy: ['#USER', '/'],
+ _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
+ _spec: 'simple-output',
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should not be printed in tree output')
+ t.matchSnapshot(cleanCwd(result()), 'should not be printed in tree output')
})
t.test('global', async t => {
- config.global = true
- const fixtures = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- node_modules: {
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: { ...parseable, global: true },
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ node_modules: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
},
},
},
},
})
- // mimics lib/npm.js globalDir getter but pointing to fixtures
- npm.globalDir = resolve(fixtures, 'node_modules')
-
await ls.exec([])
- t.matchSnapshot(redactCwd(result), 'should print parseable output for global deps')
- npm.globalDir = 'MISSING_GLOBAL_DIR'
- config.global = false
+ t.matchSnapshot(cleanCwd(result()), 'should print parseable output for global deps')
})
-
- t.end()
})
t.test('ignore missing optional deps', async t => {
- t.beforeEach(cleanUpResult)
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls-ignore-missing-optional',
- version: '1.2.3',
- peerDependencies: {
- 'peer-ok': '1',
- 'peer-missing': '1',
- 'peer-wrong': '1',
- 'peer-optional-ok': '1',
- 'peer-optional-missing': '1',
- 'peer-optional-wrong': '1',
- },
- peerDependenciesMeta: {
- 'peer-optional-ok': {
- optional: true,
- },
- 'peer-optional-missing': {
- optional: true,
- },
- 'peer-optional-wrong': {
- optional: true,
+ const mock = async (t, config = {}) => {
+ const { result, ls } = await mockLs(t, {
+ config: config,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls-ignore-missing-optional',
+ version: '1.2.3',
+ peerDependencies: {
+ 'peer-ok': '1',
+ 'peer-missing': '1',
+ 'peer-wrong': '1',
+ 'peer-optional-ok': '1',
+ 'peer-optional-missing': '1',
+ 'peer-optional-wrong': '1',
+ },
+ peerDependenciesMeta: {
+ 'peer-optional-ok': {
+ optional: true,
+ },
+ 'peer-optional-missing': {
+ optional: true,
+ },
+ 'peer-optional-wrong': {
+ optional: true,
+ },
+ },
+ optionalDependencies: {
+ 'optional-ok': '1',
+ 'optional-missing': '1',
+ 'optional-wrong': '1',
+ },
+ dependencies: {
+ 'prod-ok': '1',
+ 'prod-missing': '1',
+ 'prod-wrong': '1',
+ },
+ }),
+ node_modules: {
+ 'prod-ok': {
+ 'package.json': JSON.stringify({ name: 'prod-ok', version: '1.2.3' }),
+ },
+ 'prod-wrong': {
+ 'package.json': JSON.stringify({ name: 'prod-wrong', version: '3.2.1' }),
+ },
+ 'optional-ok': {
+ 'package.json': JSON.stringify({ name: 'optional-ok', version: '1.2.3' }),
+ },
+ 'optional-wrong': {
+ 'package.json': JSON.stringify({ name: 'optional-wrong', version: '3.2.1' }),
+ },
+ 'peer-optional-ok': {
+ 'package.json': JSON.stringify({ name: 'peer-optional-ok', version: '1.2.3' }),
+ },
+ 'peer-optional-wrong': {
+ 'package.json': JSON.stringify({ name: 'peer-optional-wrong', version: '3.2.1' }),
+ },
+ 'peer-ok': {
+ 'package.json': JSON.stringify({ name: 'peer-ok', version: '1.2.3' }),
+ },
+ 'peer-wrong': {
+ 'package.json': JSON.stringify({ name: 'peer-wrong', version: '3.2.1' }),
+ },
},
},
- optionalDependencies: {
- 'optional-ok': '1',
- 'optional-missing': '1',
- 'optional-wrong': '1',
- },
- dependencies: {
- 'prod-ok': '1',
- 'prod-missing': '1',
- 'prod-wrong': '1',
- },
- }),
- node_modules: {
- 'prod-ok': {
- 'package.json': JSON.stringify({ name: 'prod-ok', version: '1.2.3' }),
- },
- 'prod-wrong': {
- 'package.json': JSON.stringify({ name: 'prod-wrong', version: '3.2.1' }),
- },
- 'optional-ok': {
- 'package.json': JSON.stringify({ name: 'optional-ok', version: '1.2.3' }),
- },
- 'optional-wrong': {
- 'package.json': JSON.stringify({ name: 'optional-wrong', version: '3.2.1' }),
- },
- 'peer-optional-ok': {
- 'package.json': JSON.stringify({ name: 'peer-optional-ok', version: '1.2.3' }),
- },
- 'peer-optional-wrong': {
- 'package.json': JSON.stringify({ name: 'peer-optional-wrong', version: '3.2.1' }),
- },
- 'peer-ok': {
- 'package.json': JSON.stringify({ name: 'peer-ok', version: '1.2.3' }),
- },
- 'peer-wrong': {
- 'package.json': JSON.stringify({ name: 'peer-wrong', version: '3.2.1' }),
- },
- },
- })
+ })
+
+ await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' })
- config.all = true
- const prefix = npm.prefix.toLowerCase().replace(/\\/g, '/')
- const cleanupPaths = str => str.toLowerCase().replace(/\\/g, '/').split(prefix).join('{project}')
+ return config.json ? jsonParse(result()).problems : cleanCwd(result())
+ }
t.test('--json', async t => {
- config.json = true
- config.parseable = false
- await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' })
- result = JSON.parse(result)
- const problems = result.problems.map(cleanupPaths)
- t.matchSnapshot(problems, 'ls --json problems')
+ const result = await mock(t, { json: true })
+ t.matchSnapshot(result, 'ls --json problems')
})
t.test('--parseable', async t => {
- config.json = false
- config.parseable = true
- await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' })
- t.matchSnapshot(cleanupPaths(result), 'ls --parseable result')
+ const result = await mock(t, { parseable: true })
+ t.matchSnapshot(result, 'ls --parseable result')
})
t.test('human output', async t => {
- config.json = false
- config.parseable = false
- await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' })
- t.matchSnapshot(cleanupPaths(result), 'ls result')
+ const result = await mock(t)
+ t.matchSnapshot(result, 'ls result')
})
})
-t.test('ls --json', t => {
- t.beforeEach(cleanUpResult)
- config.json = true
- config.parseable = false
+t.test('ls --json', async t => {
+ const json = { json: true }
t.test('no args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2556,20 +2719,22 @@ t.test('ls --json', t => {
})
t.test('missing package.json', async t => {
- npm.prefix = t.testdir({
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/chai',
- /* eslint-disable-next-line max-len */
- 'extraneous: dog@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/dog',
- /* eslint-disable-next-line max-len */
- 'extraneous: foo@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/foo',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
+ 'extraneous: dog@1.0.0 {CWD}/prefix/node_modules/dog',
+ 'extraneous: foo@1.0.0 {CWD}/prefix/node_modules/foo',
],
dependencies: {
dog: {
@@ -2577,8 +2742,7 @@ t.test('ls --json', t => {
extraneous: true,
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: dog@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/dog',
+ 'extraneous: dog@1.0.0 {CWD}/prefix/node_modules/dog',
],
},
foo: {
@@ -2586,8 +2750,7 @@ t.test('ls --json', t => {
extraneous: true,
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: foo@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/foo',
+ 'extraneous: foo@1.0.0 {CWD}/prefix/node_modules/foo',
],
dependencies: {
dog: {
@@ -2600,8 +2763,7 @@ t.test('ls --json', t => {
extraneous: true,
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-package.json/node_modules/chai',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
],
},
},
@@ -2611,24 +2773,29 @@ t.test('ls --json', t => {
})
t.test('extraneous deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
problems: [
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-extraneous-deps/node_modules/chai',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
],
dependencies: {
foo: {
@@ -2646,8 +2813,7 @@ t.test('ls --json', t => {
extraneous: true,
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-extraneous-deps/node_modules/chai',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
],
},
},
@@ -2657,40 +2823,43 @@ t.test('ls --json', t => {
})
t.test('overridden dep', async t => {
- config.all = true
- t.teardown(() => config.all = false)
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-overridden',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- overrides: {
- bar: '1.0.0',
- },
- }),
- node_modules: {
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- dependencies: {
- bar: '^2.0.0',
- },
- }),
- },
- bar: {
- 'package.json': JSON.stringify({
- name: 'bar',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-overridden',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ },
+ overrides: {
+ bar: '1.0.0',
+ },
+ }),
+ node_modules: {
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ dependencies: {
+ bar: '^2.0.0',
+ },
+ }),
+ },
+ bar: {
+ 'package.json': JSON.stringify({
+ name: 'bar',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec([])
- t.same(JSON.parse(result), {
+ t.same(JSON.parse(result()), {
name: 'test-overridden',
version: '1.0.0',
dependencies: {
@@ -2710,31 +2879,36 @@ t.test('ls --json', t => {
t.test('missing deps --long', async t => {
t.plan(3)
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- dog: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ dog: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([]).catch(err => {
t.equal(
- redactCwd(err.message),
+ cleanCwd(err.message),
'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
'should log missing dep as error'
)
t.equal(err.code, 'ELSPROBLEMS', 'should have ELSPROBLEMS error code')
})
t.match(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2742,24 +2916,28 @@ t.test('ls --json', t => {
},
'should output json containing problems info'
)
- config.long = false
})
t.test('with filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['chai'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2776,20 +2954,25 @@ t.test('ls --json', t => {
})
t.test('with filter arg nested dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['dog'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2808,33 +2991,38 @@ t.test('ls --json', t => {
},
'should output json contaning only occurrences of filtered by package'
)
- t.notOk(jsonParse(result).dependencies.chai)
+ t.notOk(jsonParse(result()).dependencies.chai)
})
t.test('with multiple filter args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- node_modules: {
- ...simpleNmFixture.node_modules,
- ipsum: {
- 'package.json': JSON.stringify({
- name: 'ipsum',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ ...simpleNmFixture.node_modules,
+ ipsum: {
+ 'package.json': JSON.stringify({
+ name: 'ipsum',
+ version: '1.0.0',
+ }),
+ },
},
},
})
await ls.exec(['dog@*', 'chai@1.0.0'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
version: '1.0.0',
name: 'test-npm-ls',
@@ -2861,20 +3049,25 @@ t.test('ls --json', t => {
})
t.test('with missing filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec(['notadep'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2882,26 +3075,29 @@ t.test('ls --json', t => {
'should output json containing no dependencies info'
)
t.equal(process.exitCode, 1, 'should exit with error code 1')
- process.exitCode = 0
})
t.test('default --depth value should now be 0', async t => {
- config.all = false
- config.depth = undefined
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ all: false,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2918,27 +3114,30 @@ t.test('ls --json', t => {
},
'should output json containing only top-level dependencies'
)
- config.all = true
- config.depth = Infinity
})
t.test('--depth=0', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ all: false,
+ depth: 0,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2955,27 +3154,30 @@ t.test('ls --json', t => {
},
'should output json containing only top-level dependencies'
)
- config.all = true
- config.depth = Infinity
})
t.test('--depth=1', async t => {
- config.all = false
- config.depth = 1
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ all: false,
+ depth: 1,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -2998,33 +3200,34 @@ t.test('ls --json', t => {
},
'should output json containing top-level deps and their deps only'
)
- config.all = true
- config.depth = Infinity
})
t.test('missing/invalid/extraneous', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- ...simpleNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
+ },
+ }),
+ ...simpleNmFixture,
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should list dep problems')
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-invalid-extraneous/node_modules/chai',
- /* eslint-disable-next-line max-len */
- 'invalid: foo@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-invalid-extraneous/node_modules/foo',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
],
dependencies: {
@@ -3033,8 +3236,7 @@ t.test('ls --json', t => {
invalid: '"^2.0.0" from the root project',
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: foo@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-invalid-extraneous/node_modules/foo',
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
],
dependencies: {
dog: {
@@ -3048,8 +3250,7 @@ t.test('ls --json', t => {
extraneous: true,
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'extraneous: chai@1.0.0 {CWD}/tap-testdir-ls-ls---json-missing-invalid-extraneous/node_modules/chai',
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
],
},
ipsum: {
@@ -3058,36 +3259,50 @@ t.test('ls --json', t => {
problems: ['missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0'],
},
},
+ error: {
+ code: 'ELSPROBLEMS',
+ summary: [
+ 'extraneous: chai@1.0.0 {CWD}/prefix/node_modules/chai',
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
+ 'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
+ ].join('\n'),
+ detail: '',
+ },
},
'should output json containing top-level deps and their deps only'
)
})
t.test('--dev', async t => {
- flatOptions.omit = ['prod', 'optional', 'peer']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ omit: ['prod', 'optional', 'peer'],
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3112,44 +3327,48 @@ t.test('ls --json', t => {
},
'should output json containing dev deps'
)
- flatOptions.omit = []
})
t.test('--link', async t => {
- config.link = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- 'linked-dep': '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- 'linked-dep': {
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ link: true,
+ },
+ prefixDir: {
'package.json': JSON.stringify({
- name: 'linked-dep',
+ name: 'test-npm-ls',
version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ 'linked-dep': '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
}),
- },
- node_modules: {
- 'linked-dep': t.fixture('symlink', '../linked-dep'),
- ...diffDepTypesNmFixture.node_modules,
+ 'linked-dep': {
+ 'package.json': JSON.stringify({
+ name: 'linked-dep',
+ version: '1.0.0',
+ }),
+ },
+ node_modules: {
+ 'linked-dep': t.fixture('symlink', '../linked-dep'),
+ ...diffDepTypesNmFixture.node_modules,
+ },
},
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3163,34 +3382,38 @@ t.test('ls --json', t => {
},
'should output json containing linked deps'
)
- config.link = false
})
t.test('--production', async t => {
- flatOptions.omit = ['dev', 'peer']
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ omit: ['dev', 'peer'],
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3217,118 +3440,122 @@ t.test('ls --json', t => {
},
'should output json containing production deps'
)
- flatOptions.omit = []
})
t.test('from lockfile', async t => {
- npm.prefix = t.testdir({
- node_modules: {
- '@isaacs': {
- 'dedupe-tests-a': {
- 'package.json': JSON.stringify({
- name: '@isaacs/dedupe-tests-a',
- version: '1.0.1',
- }),
- node_modules: {
- '@isaacs': {
- 'dedupe-tests-b': {
- name: '@isaacs/dedupe-tests-b',
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ node_modules: {
+ '@isaacs': {
+ 'dedupe-tests-a': {
+ 'package.json': JSON.stringify({
+ name: '@isaacs/dedupe-tests-a',
+ version: '1.0.1',
+ }),
+ node_modules: {
+ '@isaacs': {
+ 'dedupe-tests-b': {
+ name: '@isaacs/dedupe-tests-b',
+ version: '1.0.0',
+ },
},
},
},
- },
- 'dedupe-tests-b': {
- 'package.json': JSON.stringify({
- name: '@isaacs/dedupe-tests-b',
- version: '2.0.0',
- }),
+ 'dedupe-tests-b': {
+ 'package.json': JSON.stringify({
+ name: '@isaacs/dedupe-tests-b',
+ version: '2.0.0',
+ }),
+ },
},
},
- },
- 'package-lock.json': JSON.stringify({
- name: 'dedupe-lockfile',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- packages: {
- '': {
- name: 'dedupe-lockfile',
- version: '1.0.0',
- dependencies: {
- '@isaacs/dedupe-tests-a': '1.0.1',
- '@isaacs/dedupe-tests-b': '1||2',
+ 'package-lock.json': JSON.stringify({
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ dependencies: {
+ '@isaacs/dedupe-tests-a': '1.0.1',
+ '@isaacs/dedupe-tests-b': '1||2',
+ },
},
- },
- 'node_modules/@isaacs/dedupe-tests-a': {
- name: '@isaacs/dedupe-tests-a',
- version: '1.0.1',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
- dependencies: {
- '@isaacs/dedupe-tests-b': '1',
+ 'node_modules/@isaacs/dedupe-tests-a': {
+ name: '@isaacs/dedupe-tests-a',
+ version: '1.0.1',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ dependencies: {
+ '@isaacs/dedupe-tests-b': '1',
+ },
},
- },
- 'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
- name: '@isaacs/dedupe-tests-b',
- version: '1.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
- },
- 'node_modules/@isaacs/dedupe-tests-b': {
- name: '@isaacs/dedupe-tests-b',
- version: '2.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
- },
- },
- dependencies: {
- '@isaacs/dedupe-tests-a': {
- version: '1.0.1',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
- requires: {
- '@isaacs/dedupe-tests-b': '1',
+ 'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
+ name: '@isaacs/dedupe-tests-b',
+ version: '1.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
- dependencies: {
- '@isaacs/dedupe-tests-b': {
- version: '1.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
+ 'node_modules/@isaacs/dedupe-tests-b': {
+ name: '@isaacs/dedupe-tests-b',
+ version: '2.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ },
+ },
+ dependencies: {
+ '@isaacs/dedupe-tests-a': {
+ version: '1.0.1',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ requires: {
+ '@isaacs/dedupe-tests-b': '1',
+ },
+ dependencies: {
+ '@isaacs/dedupe-tests-b': {
+ version: '1.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
+ },
},
},
+ '@isaacs/dedupe-tests-b': {
+ version: '2.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ },
},
- '@isaacs/dedupe-tests-b': {
- version: '2.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ }),
+ 'package.json': JSON.stringify({
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ dependencies: {
+ '@isaacs/dedupe-tests-a': '1.0.1',
+ '@isaacs/dedupe-tests-b': '1||2',
},
- },
- }),
- 'package.json': JSON.stringify({
- name: 'dedupe-lockfile',
- version: '1.0.0',
- dependencies: {
- '@isaacs/dedupe-tests-a': '1.0.1',
- '@isaacs/dedupe-tests-b': '1||2',
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
version: '1.0.0',
name: 'dedupe-lockfile',
@@ -3346,7 +3573,7 @@ t.test('ls --json', t => {
overridden: false,
problems: [
/* eslint-disable-next-line max-len */
- 'extraneous: @isaacs/dedupe-tests-b@ {CWD}/tap-testdir-ls-ls---json-from-lockfile/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
+ 'extraneous: @isaacs/dedupe-tests-b@ {CWD}/prefix/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
],
},
},
@@ -3360,7 +3587,7 @@ t.test('ls --json', t => {
},
problems: [
/* eslint-disable-next-line max-len */
- 'extraneous: @isaacs/dedupe-tests-b@ {CWD}/tap-testdir-ls-ls---json-from-lockfile/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
+ 'extraneous: @isaacs/dedupe-tests-b@ {CWD}/prefix/node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b',
],
},
'should output json containing only prod deps'
@@ -3368,30 +3595,35 @@ t.test('ls --json', t => {
})
t.test('--long', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3405,7 +3637,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/peer-dep',
+ path: '{CWD}/prefix/node_modules/peer-dep',
extraneous: false,
},
'dev-dep': {
@@ -3427,7 +3659,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/dog',
+ path: '{CWD}/prefix/node_modules/dog',
extraneous: false,
},
},
@@ -3435,7 +3667,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: { dog: '^1.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/foo',
+ path: '{CWD}/prefix/node_modules/foo',
extraneous: false,
},
},
@@ -3443,7 +3675,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: { foo: '^1.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/dev-dep',
+ path: '{CWD}/prefix/node_modules/dev-dep',
extraneous: false,
},
chai: {
@@ -3454,7 +3686,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/chai',
+ path: '{CWD}/prefix/node_modules/chai',
extraneous: false,
},
'optional-dep': {
@@ -3466,7 +3698,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/optional-dep',
+ path: '{CWD}/prefix/node_modules/optional-dep',
extraneous: false,
},
'prod-dep': {
@@ -3484,8 +3716,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- /* eslint-disable-next-line max-len */
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/prod-dep/node_modules/dog',
+ path: '{CWD}/prefix/node_modules/prod-dep/node_modules/dog',
extraneous: false,
},
},
@@ -3493,7 +3724,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: { dog: '^2.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long/node_modules/prod-dep',
+ path: '{CWD}/prefix/node_modules/prod-dep',
extraneous: false,
},
},
@@ -3502,41 +3733,45 @@ t.test('ls --json', t => {
peerDependencies: { 'peer-dep': '^1.0.0' },
_id: 'test-npm-ls@1.0.0',
_dependencies: { 'prod-dep': '^1.0.0', chai: '^1.0.0', 'optional-dep': '^1.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long',
+ path: '{CWD}/prefix',
extraneous: false,
},
'should output long json info'
)
- config.long = true
})
t.test('--long --depth=0', async t => {
- config.all = false
- config.depth = 0
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ all: false,
+ depth: 0,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3550,7 +3785,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0/node_modules/peer-dep',
+ path: '{CWD}/prefix/node_modules/peer-dep',
extraneous: false,
},
'dev-dep': {
@@ -3562,7 +3797,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: { foo: '^1.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0/node_modules/dev-dep',
+ path: '{CWD}/prefix/node_modules/dev-dep',
extraneous: false,
},
chai: {
@@ -3573,7 +3808,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0/node_modules/chai',
+ path: '{CWD}/prefix/node_modules/chai',
extraneous: false,
},
'optional-dep': {
@@ -3585,7 +3820,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: {},
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0/node_modules/optional-dep',
+ path: '{CWD}/prefix/node_modules/optional-dep',
extraneous: false,
},
'prod-dep': {
@@ -3597,7 +3832,7 @@ t.test('ls --json', t => {
devDependencies: {},
peerDependencies: {},
_dependencies: { dog: '^2.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0/node_modules/prod-dep',
+ path: '{CWD}/prefix/node_modules/prod-dep',
extraneous: false,
},
},
@@ -3606,19 +3841,21 @@ t.test('ls --json', t => {
peerDependencies: { 'peer-dep': '^1.0.0' },
_id: 'test-npm-ls@1.0.0',
_dependencies: { 'prod-dep': '^1.0.0', chai: '^1.0.0', 'optional-dep': '^1.0.0' },
- path: '{CWD}/tap-testdir-ls-ls---json---long---depth-0',
+ path: '{CWD}/prefix',
extraneous: false,
},
'should output json containing top-level deps in long format'
)
- config.all = true
- config.depth = Infinity
- config.long = false
})
t.test('json read problems', async t => {
- npm.prefix = t.testdir({
- 'package.json': '{broken json',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': '{broken json',
+ },
})
await t.rejects(
ls.exec([]),
@@ -3626,54 +3863,65 @@ t.test('ls --json', t => {
'should have missin root package.json msg'
)
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
invalid: true,
problems: [
- /* eslint-disable-next-line max-len */
- 'error in {CWD}/tap-testdir-ls-ls---json-json-read-problems: Failed to parse root package.json',
+ 'error in {CWD}/prefix: Failed to parse root package.json',
],
+ error: {
+ code: 'EJSONPARSE',
+ summary: 'Failed to parse root package.json',
+ detail: [
+ 'Failed to parse JSON data.',
+ 'Note: package.json must be actual JSON, not just JavaScript.',
+ ].join('\n'),
+ },
},
'should print empty json result'
)
})
t.test('empty location', async t => {
- npm.prefix = t.testdir({})
+ const { ls, result } = await mockLs(t, { config: json })
await ls.exec([])
- t.same(jsonParse(result), {}, 'should print empty json result')
+ t.same(jsonParse(result()), {}, 'should print empty json result')
})
t.test('unmet peer dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'optional-dep': '^1.0.0',
- },
- peerDependencies: {
- 'peer-dep': '^2.0.0', // mismatching version #
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'optional-dep': '^1.0.0',
+ },
+ peerDependencies: {
+ 'peer-dep': '^2.0.0', // mismatching version #
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'Should have ELSPROBLEMS error code')
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: peer-dep@1.0.0 {CWD}/tap-testdir-ls-ls---json-unmet-peer-dep/node_modules/peer-dep',
+ 'invalid: peer-dep@1.0.0 {CWD}/prefix/node_modules/peer-dep',
],
dependencies: {
'peer-dep': {
@@ -3681,8 +3929,7 @@ t.test('ls --json', t => {
invalid: '"^2.0.0" from the root project',
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: peer-dep@1.0.0 {CWD}/tap-testdir-ls-ls---json-unmet-peer-dep/node_modules/peer-dep',
+ 'invalid: peer-dep@1.0.0 {CWD}/prefix/node_modules/peer-dep',
],
},
'dev-dep': {
@@ -3720,32 +3967,42 @@ t.test('ls --json', t => {
},
},
},
+ error: {
+ code: 'ELSPROBLEMS',
+ summary: 'invalid: peer-dep@1.0.0 {CWD}/prefix/node_modules/peer-dep',
+ detail: '',
+ },
},
'should output json signaling missing peer dep in problems'
)
})
t.test('unmet optional dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'prod-dep': '^1.0.0',
- chai: '^1.0.0',
- },
- devDependencies: {
- 'dev-dep': '^1.0.0',
- },
- optionalDependencies: {
- 'missing-optional-dep': '^1.0.0',
- 'optional-dep': '^2.0.0', // mismatching version #
- },
- peerDependencies: {
- 'peer-dep': '^1.0.0',
- },
- }),
- ...diffDepTypesNmFixture,
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'prod-dep': '^1.0.0',
+ chai: '^1.0.0',
+ },
+ devDependencies: {
+ 'dev-dep': '^1.0.0',
+ },
+ optionalDependencies: {
+ 'missing-optional-dep': '^1.0.0',
+ 'optional-dep': '^2.0.0', // mismatching version #
+ },
+ peerDependencies: {
+ 'peer-dep': '^1.0.0',
+ },
+ }),
+ ...diffDepTypesNmFixture,
+ },
})
await t.rejects(
ls.exec([]),
@@ -3753,13 +4010,13 @@ t.test('ls --json', t => {
'should have invalid dep error msg'
)
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: optional-dep@1.0.0 {CWD}/tap-testdir-ls-ls---json-unmet-optional-dep/node_modules/optional-dep', // mismatching optional deps get flagged in problems
+ // mismatching optional deps get flagged in problems
+ 'invalid: optional-dep@1.0.0 {CWD}/prefix/node_modules/optional-dep',
],
dependencies: {
'optional-dep': {
@@ -3767,8 +4024,7 @@ t.test('ls --json', t => {
invalid: '"^2.0.0" from the root project',
overridden: false,
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: optional-dep@1.0.0 {CWD}/tap-testdir-ls-ls---json-unmet-optional-dep/node_modules/optional-dep',
+ 'invalid: optional-dep@1.0.0 {CWD}/prefix/node_modules/optional-dep',
],
},
'peer-dep': {
@@ -3807,44 +4063,54 @@ t.test('ls --json', t => {
},
'missing-optional-dep': {}, // missing optional dep has an empty entry in json output
},
+ error: {
+ code: 'ELSPROBLEMS',
+ summary: 'invalid: optional-dep@1.0.0 {CWD}/prefix/node_modules/optional-dep',
+ detail: '',
+ },
},
'should output json with empty entry for missing optional deps'
)
})
t.test('cycle deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- a: '^1.0.0',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ a: '^1.0.0',
+ },
+ }),
+ },
},
},
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3871,40 +4137,45 @@ t.test('ls --json', t => {
})
t.test('using aliases', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: 'npm:b@1.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/a': {
- name: 'b',
- version: '1.0.0',
- from: 'a@npm:b',
- resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
- requested: {
- type: 'alias',
- },
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: 'npm:b@1.0.0',
},
}),
- a: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/a': {
+ name: 'b',
+ version: '1.0.0',
+ from: 'a@npm:b',
+ resolved: 'https://localhost:8080/abbrev/-/abbrev-1.1.1.tgz',
+ requested: {
+ type: 'alias',
+ },
+ },
+ },
}),
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3921,51 +4192,56 @@ t.test('ls --json', t => {
})
t.test('resolved points to git ref', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/abbrev': {
- name: 'abbrev',
- version: '1.1.1',
- id: 'abbrev@1.1.1',
- from: 'git+https://github.com/isaacs/abbrev-js.git',
- /* eslint-disable-next-line max-len */
- resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- },
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
},
}),
- abbrev: {
- 'package.json': JSON.stringify({
- name: 'abbrev',
- version: '1.1.1',
- _id: 'abbrev@1.1.1',
- _from: 'git+https://github.com/isaacs/abbrev-js.git',
- /* eslint-disable-next-line max-len */
- _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- _requested: {
- type: 'git',
- raw: 'git+https:github.com/isaacs/abbrev-js.git',
- rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
- saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
- fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
- gitCommittish: null,
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/abbrev': {
+ name: 'abbrev',
+ version: '1.1.1',
+ id: 'abbrev@1.1.1',
+ from: 'git+https://github.com/isaacs/abbrev-js.git',
+ /* eslint-disable-next-line max-len */
+ resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ },
},
}),
+ abbrev: {
+ 'package.json': JSON.stringify({
+ name: 'abbrev',
+ version: '1.1.1',
+ _id: 'abbrev@1.1.1',
+ _from: 'git+https://github.com/isaacs/abbrev-js.git',
+ /* eslint-disable-next-line max-len */
+ _resolved: 'git+https://github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ _requested: {
+ type: 'git',
+ raw: 'git+https:github.com/isaacs/abbrev-js.git',
+ rawSpec: 'git+https:github.com/isaacs/abbrev-js.git',
+ saveSpec: 'git+https://github.com/isaacs/abbrev-js.git',
+ fetchSpec: 'https://github.com/isaacs/abbrev-js.git',
+ gitCommittish: null,
+ },
+ }),
+ },
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -3983,18 +4259,45 @@ t.test('ls --json', t => {
})
t.test('from and resolved properties', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- 'simple-output': '^2.0.0',
- },
- }),
- node_modules: {
- '.package-lock.json': JSON.stringify({
- packages: {
- 'node_modules/simple-output': {
+ const { npm, result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ 'simple-output': '^2.0.0',
+ },
+ }),
+ node_modules: {
+ '.package-lock.json': JSON.stringify({
+ packages: {
+ 'node_modules/simple-output': {
+ name: 'simple-output',
+ version: '2.1.1',
+ _from: 'simple-output',
+ _id: 'simple-output@2.1.1',
+ _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
+ _requested: {
+ type: 'tag',
+ registry: true,
+ raw: 'simple-output',
+ name: 'simple-output',
+ escapedName: 'simple-output',
+ rawSpec: '',
+ saveSpec: null,
+ fetchSpec: 'latest',
+ },
+ _requiredBy: ['#USER', '/'],
+ _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
+ _spec: 'simple-output',
+ },
+ },
+ }),
+ 'simple-output': {
+ 'package.json': JSON.stringify({
name: 'simple-output',
version: '2.1.1',
_from: 'simple-output',
@@ -4013,37 +4316,15 @@ t.test('ls --json', t => {
_requiredBy: ['#USER', '/'],
_shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
_spec: 'simple-output',
- },
+ }),
},
- }),
- 'simple-output': {
- 'package.json': JSON.stringify({
- name: 'simple-output',
- version: '2.1.1',
- _from: 'simple-output',
- _id: 'simple-output@2.1.1',
- _resolved: 'https://registry.npmjs.org/simple-output/-/simple-output-2.1.1.tgz',
- _requested: {
- type: 'tag',
- registry: true,
- raw: 'simple-output',
- name: 'simple-output',
- escapedName: 'simple-output',
- rawSpec: '',
- saveSpec: null,
- fetchSpec: 'latest',
- },
- _requiredBy: ['#USER', '/'],
- _shasum: '3c07708ec9ef3e3c985cf0ddd67df09ab8ec2abc',
- _spec: 'simple-output',
- }),
},
},
})
touchHiddenPackageLock(npm.prefix)
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4060,57 +4341,64 @@ t.test('ls --json', t => {
})
t.test('node.name fallback if missing root package name', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ version: '1.0.0',
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
version: '1.0.0',
- name: 'tap-testdir-ls-ls---json-node.name-fallback-if-missing-root-package-name',
+ name: 'prefix',
},
'should use node.name as key in json result obj'
)
})
t.test('global', async t => {
- config.global = true
- const fixtures = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- node_modules: {
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...json,
+ global: true,
+ },
+ globalPrefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
+ node_modules: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ }),
+ },
},
},
},
},
})
- // mimics lib/npm.js globalDir getter but pointing to fixtures
- npm.globalDir = resolve(fixtures, 'node_modules')
-
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
- name: 'tap-testdir-ls-ls---json-global',
+ name: process.platform === 'win32' ? 'global' : 'lib',
dependencies: {
a: {
version: '1.0.0',
@@ -4130,98 +4418,99 @@ t.test('ls --json', t => {
},
'should print json output for global deps'
)
- npm.globalDir = 'MISSING_GLOBAL_DIR'
- config.global = false
})
-
- t.end()
})
t.test('show multiple invalid reasons', async t => {
- config.json = false
- config.all = true
- config.depth = Infinity
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- cat: '^2.0.0',
- dog: '^1.2.3',
- },
- }),
- node_modules: {
- cat: {
- 'package.json': JSON.stringify({
- name: 'cat',
- version: '1.0.0',
- dependencies: {
- dog: '^2.0.0',
- },
- }),
- },
- dog: {
- 'package.json': JSON.stringify({
- name: 'dog',
- version: '1.0.0',
- dependencies: {
- cat: '',
- },
- }),
- },
- chai: {
- 'package.json': JSON.stringify({
- name: 'chai',
- version: '1.0.0',
- dependencies: {
- dog: '2.x',
- },
- }),
+ const { result, ls } = await mockLs(t, {
+ config: {},
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ cat: '^2.0.0',
+ dog: '^1.2.3',
+ },
+ }),
+ node_modules: {
+ cat: {
+ 'package.json': JSON.stringify({
+ name: 'cat',
+ version: '1.0.0',
+ dependencies: {
+ dog: '^2.0.0',
+ },
+ }),
+ },
+ dog: {
+ 'package.json': JSON.stringify({
+ name: 'dog',
+ version: '1.0.0',
+ dependencies: {
+ cat: '',
+ },
+ }),
+ },
+ chai: {
+ 'package.json': JSON.stringify({
+ name: 'chai',
+ version: '1.0.0',
+ dependencies: {
+ dog: '2.x',
+ },
+ }),
+ },
},
},
})
- const cleanupPaths = str => redactCwd(str).toLowerCase().replace(/\\/g, '/')
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should list dep problems')
- t.matchSnapshot(cleanupPaths(result), 'ls result')
+ t.matchSnapshot(cleanCwd(result()), 'ls result')
})
-t.test('ls --package-lock-only', t => {
- config['package-lock-only'] = true
- t.test('ls --package-lock-only --json', t => {
- t.beforeEach(cleanUpResult)
- config.json = true
- config.parseable = false
+t.test('ls --package-lock-only', async t => {
+ const lock = { 'package-lock-only': true }
+
+ t.test('ls --package-lock-only --json', async t => {
+ const json = { json: true }
+
t.test('no args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4247,34 +4536,40 @@ t.test('ls --package-lock-only', t => {
})
t.test('extraneous deps', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4296,83 +4591,94 @@ t.test('ls --package-lock-only', t => {
})
t.test('missing deps --long', async t => {
- config.long = true
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- dog: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
- },
- chai: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ long: true,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ dog: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
},
- ipsum: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
+ ipsum: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.match(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
},
'should output json containing no problems info'
)
- config.long = false
})
t.test('with filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
- },
- chai: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- ipsum: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
+ ipsum: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec(['chai'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4385,42 +4691,48 @@ t.test('ls --package-lock-only', t => {
},
'should output json contaning only occurrences of filtered by package'
)
- t.equal(process.exitCode, 0, 'should exit with error code 0')
+ t.notOk(process.exitCode, 'should not set exit code')
})
t.test('with filter arg nested dep', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
- },
- chai: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- ipsum: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
+ ipsum: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec(['dog'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4442,39 +4754,45 @@ t.test('ls --package-lock-only', t => {
})
t.test('with multiple filter args', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- ipsum: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
- },
- chai: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
+ ipsum: '^1.0.0',
},
- ipsum: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
+ ipsum: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec(['dog@*', 'chai@1.0.0'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
version: '1.0.0',
name: 'test-npm-ls',
@@ -4501,35 +4819,41 @@ t.test('ls --package-lock-only', t => {
})
t.test('with missing filter arg', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec(['notadep'])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4537,41 +4861,45 @@ t.test('ls --package-lock-only', t => {
'should output json containing no dependencies info'
)
t.equal(process.exitCode, 1, 'should exit with error code 1')
- process.exitCode = 0
})
t.test('default --depth value should now be 0', async t => {
- config.all = false
- config.depth = undefined
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ all: false,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4588,42 +4916,46 @@ t.test('ls --package-lock-only', t => {
},
'should output json containing only top-level dependencies'
)
- config.all = true
- config.depth = Infinity
})
t.test('--depth=0', async t => {
- config.all = false
- config.depth = 0
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ depth: 0,
+ all: false,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4640,42 +4972,46 @@ t.test('ls --package-lock-only', t => {
},
'should output json containing only top-level dependencies'
)
- config.all = true
- config.depth = Infinity
})
t.test('--depth=1', async t => {
- config.all = false
- config.depth = 1
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^1.0.0',
- chai: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ all: false,
+ depth: 1,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^1.0.0',
+ chai: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4698,46 +5034,49 @@ t.test('ls --package-lock-only', t => {
},
'should output json containing top-level deps and their deps only'
)
- config.all = true
- config.depth = Infinity
})
t.test('missing/invalid/extraneous', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- foo: '^2.0.0',
- ipsum: '^1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- foo: {
- version: '1.0.0',
- requires: {
- dog: '^1.0.0',
- },
- },
- dog: {
- version: '1.0.0',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ foo: '^2.0.0',
+ ipsum: '^1.0.0',
},
- chai: {
- version: '1.0.0',
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ foo: {
+ version: '1.0.0',
+ requires: {
+ dog: '^1.0.0',
+ },
+ },
+ dog: {
+ version: '1.0.0',
+ },
+ chai: {
+ version: '1.0.0',
+ },
},
- },
- }),
+ }),
+ },
})
await t.rejects(ls.exec([]), { code: 'ELSPROBLEMS' }, 'should list dep problems')
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: foo@1.0.0 {CWD}/tap-testdir-ls-ls---package-lock-only-ls---package-lock-only---json-missing-invalid-extraneous/node_modules/foo',
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
],
dependencies: {
@@ -4746,8 +5085,7 @@ t.test('ls --package-lock-only', t => {
overridden: false,
invalid: '"^2.0.0" from the root project',
problems: [
- /* eslint-disable-next-line max-len */
- 'invalid: foo@1.0.0 {CWD}/tap-testdir-ls-ls---package-lock-only-ls---package-lock-only---json-missing-invalid-extraneous/node_modules/foo',
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
],
dependencies: {
dog: {
@@ -4762,96 +5100,110 @@ t.test('ls --package-lock-only', t => {
problems: ['missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0'],
},
},
+ error: {
+ code: 'ELSPROBLEMS',
+ summary: [
+ 'invalid: foo@1.0.0 {CWD}/prefix/node_modules/foo',
+ 'missing: ipsum@^1.0.0, required by test-npm-ls@1.0.0',
+ ].join('\n'),
+ detail: '',
+ },
},
'should output json containing top-level deps and their deps only'
)
})
t.test('from lockfile', async t => {
- npm.prefix = t.testdir({
- 'package-lock.json': JSON.stringify({
- name: 'dedupe-lockfile',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- packages: {
- '': {
- name: 'dedupe-lockfile',
- version: '1.0.0',
- dependencies: {
- '@isaacs/dedupe-tests-a': '1.0.1',
- '@isaacs/dedupe-tests-b': '1||2',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package-lock.json': JSON.stringify({
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ dependencies: {
+ '@isaacs/dedupe-tests-a': '1.0.1',
+ '@isaacs/dedupe-tests-b': '1||2',
+ },
},
- },
- 'node_modules/@isaacs/dedupe-tests-a': {
- name: '@isaacs/dedupe-tests-a',
- version: '1.0.1',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
- dependencies: {
- '@isaacs/dedupe-tests-b': '1',
+ 'node_modules/@isaacs/dedupe-tests-a': {
+ name: '@isaacs/dedupe-tests-a',
+ version: '1.0.1',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ dependencies: {
+ '@isaacs/dedupe-tests-b': '1',
+ },
},
- },
- 'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
- name: '@isaacs/dedupe-tests-b',
- version: '1.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
- },
- 'node_modules/@isaacs/dedupe-tests-b': {
- name: '@isaacs/dedupe-tests-b',
- version: '2.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
- },
- },
- dependencies: {
- '@isaacs/dedupe-tests-a': {
- version: '1.0.1',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
- requires: {
- '@isaacs/dedupe-tests-b': '1',
+ 'node_modules/@isaacs/dedupe-tests-a/node_modules/@isaacs/dedupe-tests-b': {
+ name: '@isaacs/dedupe-tests-b',
+ version: '1.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
},
- dependencies: {
- '@isaacs/dedupe-tests-b': {
- version: '1.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
+ 'node_modules/@isaacs/dedupe-tests-b': {
+ name: '@isaacs/dedupe-tests-b',
+ version: '2.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ },
+ },
+ dependencies: {
+ '@isaacs/dedupe-tests-a': {
+ version: '1.0.1',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-a/-/dedupe-tests-a-1.0.1.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-8AN9lNCcBt5Xeje7fMEEpp5K3rgcAzIpTtAjYb/YMUYu8SbIVF6wz0WqACDVKvpQOUcSfNHZQNLNmue0QSwXOQ==',
+ requires: {
+ '@isaacs/dedupe-tests-b': '1',
+ },
+ dependencies: {
+ '@isaacs/dedupe-tests-b': {
+ version: '1.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-1.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-3nmvzIb8QL8OXODzipwoV3U8h9OQD9g9RwOPuSBQqjqSg9JZR1CCFOWNsDUtOfmwY8HFUJV9EAZ124uhqVxq+w==',
+ },
},
},
+ '@isaacs/dedupe-tests-b': {
+ version: '2.0.0',
+ /* eslint-disable-next-line max-len */
+ resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
+ /* eslint-disable-next-line max-len */
+ integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ },
},
- '@isaacs/dedupe-tests-b': {
- version: '2.0.0',
- /* eslint-disable-next-line max-len */
- resolved: 'https://registry.npmjs.org/@isaacs/dedupe-tests-b/-/dedupe-tests-b-2.0.0.tgz',
- /* eslint-disable-next-line max-len */
- integrity: 'sha512-KTYkpRv9EzlmCg4Gsm/jpclWmRYFCXow8GZKJXjK08sIZBlElTZEa5Bw/UQxIvEfcKmWXczSqItD49Kr8Ax4UA==',
+ }),
+ 'package.json': JSON.stringify({
+ name: 'dedupe-lockfile',
+ version: '1.0.0',
+ dependencies: {
+ '@isaacs/dedupe-tests-a': '1.0.1',
+ '@isaacs/dedupe-tests-b': '1||2',
},
- },
- }),
- 'package.json': JSON.stringify({
- name: 'dedupe-lockfile',
- version: '1.0.0',
- dependencies: {
- '@isaacs/dedupe-tests-a': '1.0.1',
- '@isaacs/dedupe-tests-b': '1||2',
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
version: '1.0.0',
name: 'dedupe-lockfile',
@@ -4883,26 +5235,32 @@ t.test('ls --package-lock-only', t => {
})
t.test('using aliases', async t => {
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- a: 'npm:b@1.0.0',
- },
- }),
- 'package-lock.json': JSON.stringify({
- dependencies: {
- a: {
- version: 'npm:b@1.0.0',
- resolved: 'https://localhost:8080/abbrev/-/abbrev-1.0.0.tgz',
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ a: 'npm:b@1.0.0',
},
- },
- }),
+ }),
+ 'package-lock.json': JSON.stringify({
+ dependencies: {
+ a: {
+ version: 'npm:b@1.0.0',
+ resolved: 'https://localhost:8080/abbrev/-/abbrev-1.0.0.tgz',
+ },
+ },
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4919,32 +5277,38 @@ t.test('ls --package-lock-only', t => {
})
t.test('resolved points to git ref', async t => {
- config.long = false
- npm.prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- dependencies: {
- abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
- },
- }),
- 'package-lock.json': JSON.stringify({
- name: 'test-npm-ls',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- dependencies: {
- abbrev: {
+ const { result, ls } = await mockLs(t, {
+ config: {
+ ...lock,
+ ...json,
+ long: false,
+ },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ dependencies: {
+ abbrev: 'git+https://github.com/isaacs/abbrev-js.git',
+ },
+ }),
+ 'package-lock.json': JSON.stringify({
+ name: 'test-npm-ls',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ dependencies: {
+ abbrev: {
/* eslint-disable-next-line max-len */
- version: 'git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
- from: 'abbrev@git+https://github.com/isaacs/abbrev-js.git',
+ version: 'git+ssh://git@github.com/isaacs/abbrev-js.git#b8f3a2fc0c3bb8ffd8b0d0072cc6b5a3667e963c',
+ from: 'abbrev@git+https://github.com/isaacs/abbrev-js.git',
+ },
},
- },
- }),
+ }),
+ },
})
await ls.exec([])
t.same(
- jsonParse(result),
+ jsonParse(result()),
{
name: 'test-npm-ls',
version: '1.0.0',
@@ -4959,9 +5323,5 @@ t.test('ls --package-lock-only', t => {
'should output json containing git refs'
)
})
-
- t.end()
})
-
- t.end()
})
diff --git a/deps/npm/test/lib/commands/org.js b/deps/npm/test/lib/commands/org.js
index cd25fc23aa..d370030432 100644
--- a/deps/npm/test/lib/commands/org.js
+++ b/deps/npm/test/lib/commands/org.js
@@ -1,53 +1,56 @@
const t = require('tap')
const ansiTrim = require('../../../lib/utils/ansi-trim.js')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const output = []
-const npm = mockNpm({
- flatOptions: {
- json: false,
- parseable: false,
- },
- config: {
- loglevel: 'info',
- },
- output: msg => {
- output.push(msg)
- },
-})
+const mockNpm = require('../../fixtures/mock-npm')
+
+const mockOrg = async (t, { orgSize = 1, orgList = {}, ...npmOpts } = {}) => {
+ let setArgs = null
+ let rmArgs = null
+ let lsArgs = null
+
+ const libnpmorg = {
+ set: async (org, user, role, opts) => {
+ setArgs = { org, user, role, opts }
+ return {
+ org: {
+ name: org,
+ size: orgSize,
+ },
+ user,
+ role,
+ }
+ },
+ rm: async (org, user, opts) => {
+ rmArgs = { org, user, opts }
+ },
+ ls: async (org, opts) => {
+ lsArgs = { org, opts }
+ return orgList
+ },
+ }
-let orgSize = 1
-let orgSetArgs = null
-let orgRmArgs = null
-let orgLsArgs = null
-let orgList = {}
-const libnpmorg = {
- set: async (org, user, role, opts) => {
- orgSetArgs = { org, user, role, opts }
- return {
- org: {
- name: org,
- size: orgSize,
- },
- user,
- role,
- }
- },
- rm: async (org, user, opts) => {
- orgRmArgs = { org, user, opts }
- },
- ls: async (org, opts) => {
- orgLsArgs = { org, opts }
- return orgList
- },
-}
+ const mock = await mockNpm(t, {
+ ...npmOpts,
+ mocks: {
+ libnpmorg,
+ ...npmOpts.mocks,
+ },
+ })
-const Org = t.mock('../../../lib/commands/org.js', {
- libnpmorg,
-})
-const org = new Org(npm)
+ return {
+ ...mock,
+ org: {
+ exec: (args) => mock.npm.exec('org', args),
+ completion: (arg) => mock.npm.cmd('org').then(c => c.completion(arg)),
+ usage: () => mock.npm.cmd('org').then(c => c.usage),
+ },
+ setArgs: () => setArgs,
+ rmArgs: () => rmArgs,
+ lsArgs: () => lsArgs,
+ }
+}
t.test('completion', async t => {
+ const { org } = await mockOrg(t)
const completion = argv => org.completion({ conf: { argv: { remain: argv } } })
const assertions = [
@@ -73,19 +76,17 @@ t.test('completion', async t => {
})
t.test('npm org - invalid subcommand', async t => {
- await t.rejects(org.exec(['foo']), org.usage)
+ const { org } = await mockOrg(t)
+ await t.rejects(org.exec(['foo']), org.usage())
})
t.test('npm org add', async t => {
- t.teardown(() => {
- orgSetArgs = null
- output.length = 0
- })
+ const { npm, org, setArgs, outputs } = await mockOrg(t)
await org.exec(['add', 'orgname', 'username'])
t.match(
- orgSetArgs,
+ setArgs(),
{
org: 'orgname',
user: 'username',
@@ -95,17 +96,14 @@ t.test('npm org add', async t => {
'received the correct arguments'
)
t.equal(
- output[0],
+ outputs[0][0],
'Added username as developer to orgname. You now have 1 member in this org.',
'printed the correct output'
)
})
t.test('npm org add - no org', async t => {
- t.teardown(() => {
- orgSetArgs = null
- output.length = 0
- })
+ const { org } = await mockOrg(t)
await t.rejects(
org.exec(['add', '', 'username']),
@@ -115,11 +113,7 @@ t.test('npm org add - no org', async t => {
})
t.test('npm org add - no user', async t => {
- t.teardown(() => {
- orgSetArgs = null
- output.length = 0
- })
-
+ const { org } = await mockOrg(t)
await t.rejects(
org.exec(['add', 'orgname', '']),
/`username` is required/,
@@ -128,11 +122,7 @@ t.test('npm org add - no user', async t => {
})
t.test('npm org add - invalid role', async t => {
- t.teardown(() => {
- orgSetArgs = null
- output.length = 0
- })
-
+ const { org } = await mockOrg(t)
await t.rejects(
org.exec(['add', 'orgname', 'username', 'person']),
/`role` must be one of/,
@@ -141,16 +131,12 @@ t.test('npm org add - invalid role', async t => {
})
t.test('npm org add - more users', async t => {
- orgSize = 5
- t.teardown(() => {
- orgSize = 1
- orgSetArgs = null
- output.length = 0
- })
+ const orgSize = 5
+ const { npm, org, outputs, setArgs } = await mockOrg(t, { orgSize })
await org.exec(['add', 'orgname', 'username'])
t.match(
- orgSetArgs,
+ setArgs(),
{
org: 'orgname',
user: 'username',
@@ -160,24 +146,21 @@ t.test('npm org add - more users', async t => {
'received the correct arguments'
)
t.equal(
- output[0],
+ outputs[0][0],
'Added username as developer to orgname. You now have 5 members in this org.',
'printed the correct output'
)
})
t.test('npm org add - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- orgSetArgs = null
- output.length = 0
+ const { npm, org, outputs, setArgs } = await mockOrg(t, {
+ config: { json: true },
})
await org.exec(['add', 'orgname', 'username'])
t.match(
- orgSetArgs,
+ setArgs(),
{
org: 'orgname',
user: 'username',
@@ -187,7 +170,7 @@ t.test('npm org add - json output', async t => {
'received the correct arguments'
)
t.strictSame(
- JSON.parse(output[0]),
+ JSON.parse(outputs[0]),
{
org: {
name: 'orgname',
@@ -201,17 +184,15 @@ t.test('npm org add - json output', async t => {
})
t.test('npm org add - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- orgSetArgs = null
- output.length = 0
+ const config = { parseable: true }
+ const { npm, org, outputs, setArgs } = await mockOrg(t, {
+ config,
})
await org.exec(['add', 'orgname', 'username'])
t.match(
- orgSetArgs,
+ setArgs(),
{
org: 'orgname',
user: 'username',
@@ -221,7 +202,7 @@ t.test('npm org add - parseable output', async t => {
'received the correct arguments'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['org', 'orgsize', 'user', 'role'],
['orgname', '1', 'username', 'developer'],
@@ -231,17 +212,15 @@ t.test('npm org add - parseable output', async t => {
})
t.test('npm org add - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- orgSetArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, org, outputs, setArgs } = await mockOrg(t, {
+ config,
})
await org.exec(['add', 'orgname', 'username'])
t.match(
- orgSetArgs,
+ setArgs(),
{
org: 'orgname',
user: 'username',
@@ -250,20 +229,16 @@ t.test('npm org add - silent output', async t => {
},
'received the correct arguments'
)
- t.strictSame(output, [], 'prints no output')
+ t.strictSame(outputs, [], 'prints no output')
})
t.test('npm org rm', async t => {
- t.teardown(() => {
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
- })
+ const { npm, org, outputs, lsArgs, rmArgs } = await mockOrg(t)
await org.exec(['rm', 'orgname', 'username'])
t.match(
- orgRmArgs,
+ rmArgs(),
{
org: 'orgname',
user: 'username',
@@ -272,7 +247,7 @@ t.test('npm org rm', async t => {
'libnpmorg.rm received the correct args'
)
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
@@ -280,18 +255,14 @@ t.test('npm org rm', async t => {
'libnpmorg.ls received the correct args'
)
t.equal(
- output[0],
+ outputs[0][0],
'Successfully removed username from orgname. You now have 0 members in this org.',
'printed the correct output'
)
})
t.test('npm org rm - no org', async t => {
- t.teardown(() => {
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
- })
+ const { org } = await mockOrg(t)
await t.rejects(
org.exec(['rm', '', 'username']),
@@ -301,31 +272,23 @@ t.test('npm org rm - no org', async t => {
})
t.test('npm org rm - no user', async t => {
- t.teardown(() => {
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
- })
+ const { org } = await mockOrg(t)
await t.rejects(org.exec(['rm', 'orgname']), /`username` is required/, 'threw the correct error')
})
t.test('npm org rm - one user left', async t => {
- orgList = {
+ const orgList = {
one: 'developer',
}
-
- t.teardown(() => {
- orgList = {}
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs, rmArgs } = await mockOrg(t, {
+ orgList,
})
await org.exec(['rm', 'orgname', 'username'])
t.match(
- orgRmArgs,
+ rmArgs(),
{
org: 'orgname',
user: 'username',
@@ -334,7 +297,7 @@ t.test('npm org rm - one user left', async t => {
'libnpmorg.rm received the correct args'
)
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
@@ -342,25 +305,22 @@ t.test('npm org rm - one user left', async t => {
'libnpmorg.ls received the correct args'
)
t.equal(
- output[0],
+ outputs[0][0],
'Successfully removed username from orgname. You now have 1 member in this org.',
'printed the correct output'
)
})
t.test('npm org rm - json output', async t => {
- npm.flatOptions.json = true
- t.teardown(() => {
- npm.flatOptions.json = false
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
+ const config = { json: true }
+ const { npm, org, outputs, lsArgs, rmArgs } = await mockOrg(t, {
+ config,
})
await org.exec(['rm', 'orgname', 'username'])
t.match(
- orgRmArgs,
+ rmArgs(),
{
org: 'orgname',
user: 'username',
@@ -369,7 +329,7 @@ t.test('npm org rm - json output', async t => {
'libnpmorg.rm received the correct args'
)
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
@@ -377,7 +337,7 @@ t.test('npm org rm - json output', async t => {
'libnpmorg.ls received the correct args'
)
t.strictSame(
- JSON.parse(output[0]),
+ JSON.parse(outputs[0]),
{
user: 'username',
org: 'orgname',
@@ -389,18 +349,15 @@ t.test('npm org rm - json output', async t => {
})
t.test('npm org rm - parseable output', async t => {
- npm.flatOptions.parseable = true
- t.teardown(() => {
- npm.flatOptions.parseable = false
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
+ const config = { parseable: true }
+ const { npm, org, outputs, lsArgs, rmArgs } = await mockOrg(t, {
+ config,
})
await org.exec(['rm', 'orgname', 'username'])
t.match(
- orgRmArgs,
+ rmArgs(),
{
org: 'orgname',
user: 'username',
@@ -409,7 +366,7 @@ t.test('npm org rm - parseable output', async t => {
'libnpmorg.rm received the correct args'
)
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
@@ -417,7 +374,7 @@ t.test('npm org rm - parseable output', async t => {
'libnpmorg.ls received the correct args'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['user', 'org', 'userCount', 'deleted'],
['username', 'orgname', '0', 'true'],
@@ -427,18 +384,15 @@ t.test('npm org rm - parseable output', async t => {
})
t.test('npm org rm - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- orgRmArgs = null
- orgLsArgs = null
- output.length = 0
+ const config = { loglevel: 'silent' }
+ const { npm, org, outputs, lsArgs, rmArgs } = await mockOrg(t, {
+ config,
})
await org.exec(['rm', 'orgname', 'username'])
t.match(
- orgRmArgs,
+ rmArgs(),
{
org: 'orgname',
user: 'username',
@@ -447,149 +401,135 @@ t.test('npm org rm - silent output', async t => {
'libnpmorg.rm received the correct args'
)
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'libnpmorg.ls received the correct args'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
t.test('npm org ls', async t => {
- orgList = {
+ const orgList = {
one: 'developer',
two: 'admin',
three: 'owner',
}
- t.teardown(() => {
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
})
await org.exec(['ls', 'orgname'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'receieved the correct args'
)
- const out = ansiTrim(output[0])
+ const out = ansiTrim(outputs[0][0])
t.match(out, /one.*developer/, 'contains the developer member')
t.match(out, /two.*admin/, 'contains the admin member')
t.match(out, /three.*owner/, 'contains the owner member')
})
t.test('npm org ls - user filter', async t => {
- orgList = {
+ const orgList = {
username: 'admin',
missing: 'admin',
}
- t.teardown(() => {
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
})
await org.exec(['ls', 'orgname', 'username'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'receieved the correct args'
)
- const out = ansiTrim(output[0])
+ const out = ansiTrim(outputs[0][0])
t.match(out, /username.*admin/, 'contains the filtered member')
t.notMatch(out, /missing.*admin/, 'does not contain other members')
})
t.test('npm org ls - user filter, missing user', async t => {
- orgList = {
+ const orgList = {
missing: 'admin',
}
- t.teardown(() => {
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
})
await org.exec(['ls', 'orgname', 'username'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'receieved the correct args'
)
- const out = ansiTrim(output[0])
+ const out = ansiTrim(outputs[0][0])
t.notMatch(out, /username/, 'does not contain the requested member')
t.notMatch(out, /missing.*admin/, 'does not contain other members')
})
t.test('npm org ls - no org', async t => {
- t.teardown(() => {
- orgLsArgs = null
- output.length = 0
- })
-
+ const { org } = await mockOrg(t)
await t.rejects(org.exec(['ls']), /`orgname` is required/, 'throws the correct error')
})
t.test('npm org ls - json output', async t => {
- npm.flatOptions.json = true
- orgList = {
+ const config = { json: true }
+ const orgList = {
one: 'developer',
two: 'admin',
three: 'owner',
}
- t.teardown(() => {
- npm.flatOptions.json = false
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
+ config,
})
await org.exec(['ls', 'orgname'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'receieved the correct args'
)
- t.strictSame(JSON.parse(output[0]), orgList, 'prints the correct output')
+ t.strictSame(JSON.parse(outputs[0]), orgList, 'prints the correct output')
})
t.test('npm org ls - parseable output', async t => {
- npm.flatOptions.parseable = true
- orgList = {
+ const config = { parseable: true }
+ const orgList = {
one: 'developer',
two: 'admin',
three: 'owner',
}
- t.teardown(() => {
- npm.flatOptions.parseable = false
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
+ config,
})
await org.exec(['ls', 'orgname'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
@@ -597,7 +537,7 @@ t.test('npm org ls - parseable output', async t => {
'receieved the correct args'
)
t.strictSame(
- output.map(line => line.split(/\t/)),
+ outputs.map(line => line[0].split(/\t/)),
[
['user', 'role'],
['one', 'developer'],
@@ -609,28 +549,26 @@ t.test('npm org ls - parseable output', async t => {
})
t.test('npm org ls - silent output', async t => {
- npm.config.set('loglevel', 'silent')
- orgList = {
+ const config = { loglevel: 'silent' }
+ const orgList = {
one: 'developer',
two: 'admin',
three: 'owner',
}
- t.teardown(() => {
- npm.config.set('loglevel', 'info')
- orgList = {}
- orgLsArgs = null
- output.length = 0
+ const { npm, org, outputs, lsArgs } = await mockOrg(t, {
+ orgList,
+ config,
})
await org.exec(['ls', 'orgname'])
t.match(
- orgLsArgs,
+ lsArgs(),
{
org: 'orgname',
opts: npm.flatOptions,
},
'receieved the correct args'
)
- t.strictSame(output, [], 'printed no output')
+ t.strictSame(outputs, [], 'printed no output')
})
diff --git a/deps/npm/test/lib/commands/outdated.js b/deps/npm/test/lib/commands/outdated.js
index 4803c7e171..02f2067c54 100644
--- a/deps/npm/test/lib/commands/outdated.js
+++ b/deps/npm/test/lib/commands/outdated.js
@@ -1,5 +1,9 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const MockRegistry = require('@npmcli/mock-registry')
+const _mockNpm = require('../../fixtures/mock-npm')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
+t.cleanSnapshot = (str) => cleanCwd(str)
const packument = spec => {
const mocks = {
@@ -68,69 +72,18 @@ const packument = spec => {
return mocks[spec.name]
}
-let logs
-const output = (msg) => {
- logs = `${logs}\n${msg}`
-}
-
-const globalDir = t.testdir({
- node_modules: {
- cat: {
- 'package.json': JSON.stringify({
- name: 'cat',
- version: '1.0.0',
- }, null, 2),
+const fixtures = {
+ global: {
+ node_modules: {
+ cat: {
+ 'package.json': JSON.stringify({
+ name: 'cat',
+ version: '1.0.0',
+ }, null, 2),
+ },
},
},
-})
-
-const outdated = (dir, opts) => {
- logs = ''
- const Outdated = t.mock('../../../lib/commands/outdated.js', {
- pacote: {
- packument,
- },
- })
- if (opts.config && opts.config.omit) {
- opts.flatOptions = {
- omit: opts.config.omit,
- ...opts.flatOptions,
- }
- delete opts.config.omit
- }
- const npm = mockNpm({
- ...opts,
- localPrefix: dir,
- prefix: dir,
- flatOptions: {
- workspacesEnabled: true,
- omit: [],
- ...opts.flatOptions,
- },
- globalDir: `${globalDir}/node_modules`,
- output,
- })
- return new Outdated(npm)
-}
-
-t.beforeEach(() => logs = '')
-
-const { exitCode } = process
-
-t.afterEach(() => process.exitCode = exitCode)
-
-const redactCwd = (path) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
-}
-
-t.cleanSnapshot = (str) => redactCwd(str)
-
-t.test('should display outdated deps', t => {
- const testDir = t.testdir({
+ local: {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -186,145 +139,274 @@ t.test('should display outdated deps', t => {
}, null, 2),
},
},
+ },
+ workspaces: {
+ 'package.json': JSON.stringify({
+ name: 'workspaces-project',
+ version: '1.0.0',
+ workspaces: ['packages/*'],
+ dependencies: {
+ dog: '^1.0.0',
+ },
+ }),
+ node_modules: {
+ a: t.fixture('symlink', '../packages/a'),
+ b: t.fixture('symlink', '../packages/b'),
+ c: t.fixture('symlink', '../packages/c'),
+ cat: {
+ 'package.json': JSON.stringify({
+ name: 'cat',
+ version: '1.0.0',
+ dependencies: {
+ dog: '2.0.0',
+ },
+ }),
+ node_modules: {
+ dog: {
+ 'package.json': JSON.stringify({
+ name: 'dog',
+ version: '2.0.0',
+ }),
+ },
+ },
+ },
+ chai: {
+ 'package.json': JSON.stringify({
+ name: 'chai',
+ version: '1.0.0',
+ }),
+ },
+ dog: {
+ 'package.json': JSON.stringify({
+ name: 'dog',
+ version: '1.0.1',
+ }),
+ },
+ foo: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ dependencies: {
+ chai: '^1.0.0',
+ },
+ }),
+ },
+ zeta: {
+ 'package.json': JSON.stringify({
+ name: 'zeta',
+ version: '1.0.0',
+ }),
+ },
+ },
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ dependencies: {
+ b: '^1.0.0',
+ cat: '^1.0.0',
+ foo: '^1.0.0',
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ dependencies: {
+ zeta: '^1.0.0',
+ },
+ }),
+ },
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ dependencies: {
+ theta: '^1.0.0',
+ },
+ }),
+ },
+ },
+ },
+}
+
+const mockNpm = async (t, { prefixDir, ...opts } = {}) => {
+ const res = await _mockNpm(t, {
+ mocks: {
+ pacote: {
+ packument,
+ },
+ },
+ ...opts,
+ prefixDir,
+ })
+
+ // this is not currently used, but ensures that no requests are
+ // hitting the registry.
+ // XXX: the pacote mock should be replaced with mock registry calls
+ const registry = new MockRegistry({
+ tap: t,
+ registry: res.npm.config.get('registry'),
+ strict: true,
})
- t.test('outdated global', async t => {
- await outdated(null, {
+ return {
+ ...res,
+ registry,
+ exec: (args) => res.npm.exec('outdated', args),
+ }
+}
+
+t.test('should display outdated deps', async t => {
+ await t.test('outdated global', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ globalPrefixDir: fixtures.global,
config: { global: true },
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated', async t => {
- await outdated(testDir, {
+ await t.test('outdated', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
+ color: 'always',
},
- color: true,
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --omit=dev', async t => {
- await outdated(testDir, {
+ await t.test('outdated --omit=dev', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
omit: ['dev'],
+ color: 'always',
},
- color: true,
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --omit=dev --omit=peer', async t => {
- await outdated(testDir, {
+ await t.test('outdated --omit=dev --omit=peer', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
omit: ['dev', 'peer'],
+ color: 'always',
},
- color: true,
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --omit=prod', async t => {
- await outdated(testDir, {
+ await t.test('outdated --omit=prod', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
omit: ['prod'],
+ color: 'always',
},
- color: true,
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --long', async t => {
- await outdated(testDir, {
+ await t.test('outdated --long', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
long: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --json', async t => {
- await outdated(testDir, {
+ await t.test('outdated --json', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
json: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --json --long', async t => {
- await outdated(testDir, {
+ await t.test('outdated --json --long', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
json: true,
long: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --parseable', async t => {
- await outdated(testDir, {
+ await t.test('outdated --parseable', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
parseable: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --parseable --long', async t => {
- await outdated(testDir, {
+ await t.test('outdated --parseable --long', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
- global: false,
parseable: true,
long: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated --all', async t => {
- await outdated(testDir, {
+ await t.test('outdated --all', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
config: {
all: true,
},
- }).exec([])
+ })
+ await exec([])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
- t.test('outdated specific dep', async t => {
- await outdated(testDir, {
- config: {
- global: false,
- },
- }).exec(['cat'])
+ await t.test('outdated specific dep', async t => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.local,
+ })
+ await exec(['cat'])
t.equal(process.exitCode, 1)
- t.matchSnapshot(logs)
+ t.matchSnapshot(joinedOutput())
})
-
- t.end()
})
t.test('should return if no outdated deps', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -340,18 +422,18 @@ t.test('should return if no outdated deps', async t => {
}, null, 2),
},
},
- })
+ }
- await outdated(testDir, {
- config: {
- global: false,
- },
- }).exec([])
- t.equal(logs.length, 0, 'no logs')
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: testDir,
+
+ })
+ await exec([])
+ t.equal(joinedOutput(), '', 'no logs')
})
t.test('throws if error with a dep', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -367,20 +449,17 @@ t.test('throws if error with a dep', async t => {
}, null, 2),
},
},
+ }
+
+ const { exec } = await mockNpm(t, {
+ prefixDir: testDir,
})
- await t.rejects(
- outdated(testDir, {
- config: {
- global: false,
- },
- }).exec([]),
- 'There is an error with this package.'
- )
+ await t.rejects(exec([]), 'There is an error with this package.')
})
t.test('should skip missing non-prod deps', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -389,18 +468,19 @@ t.test('should skip missing non-prod deps', async t => {
},
}, null, 2),
node_modules: {},
+ }
+
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: testDir,
})
- await outdated(testDir, {
- config: {
- global: false,
- },
- }).exec([])
- t.equal(logs.length, 0, 'no logs')
+ await exec([])
+
+ t.equal(joinedOutput(), '', 'no logs')
})
t.test('should skip invalid pkg ranges', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -416,14 +496,17 @@ t.test('should skip invalid pkg ranges', async t => {
}, null, 2),
},
},
- })
+ }
- await outdated(testDir, {}).exec([])
- t.equal(logs.length, 0, 'no logs')
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: testDir,
+ })
+ await exec([])
+ t.equal(joinedOutput(), '', 'no logs')
})
t.test('should skip git specs', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'delta',
version: '1.0.0',
@@ -439,194 +522,70 @@ t.test('should skip git specs', async t => {
}, null, 2),
},
},
- })
+ }
- await outdated(testDir, {}).exec([])
- t.equal(logs.length, 0, 'no logs')
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: testDir,
+ })
+ await exec([])
+ t.equal(joinedOutput(), '', 'no logs')
})
t.test('workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify({
- name: 'workspaces-project',
- version: '1.0.0',
- workspaces: ['packages/*'],
- dependencies: {
- dog: '^1.0.0',
- },
- }),
- node_modules: {
- a: t.fixture('symlink', '../packages/a'),
- b: t.fixture('symlink', '../packages/b'),
- c: t.fixture('symlink', '../packages/c'),
- cat: {
- 'package.json': JSON.stringify({
- name: 'cat',
- version: '1.0.0',
- dependencies: {
- dog: '2.0.0',
- },
- }),
- node_modules: {
- dog: {
- 'package.json': JSON.stringify({
- name: 'dog',
- version: '2.0.0',
- }),
- },
- },
- },
- chai: {
- 'package.json': JSON.stringify({
- name: 'chai',
- version: '1.0.0',
- }),
- },
- dog: {
- 'package.json': JSON.stringify({
- name: 'dog',
- version: '1.0.1',
- }),
- },
- foo: {
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- dependencies: {
- chai: '^1.0.0',
- },
- }),
- },
- zeta: {
- 'package.json': JSON.stringify({
- name: 'zeta',
- version: '1.0.0',
- }),
- },
- },
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- dependencies: {
- b: '^1.0.0',
- cat: '^1.0.0',
- foo: '^1.0.0',
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- dependencies: {
- zeta: '^1.0.0',
- },
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- dependencies: {
- theta: '^1.0.0',
- },
- }),
- },
- },
- })
+ const mockWorkspaces = async (t, { exitCode = 1, ...config } = {}) => {
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: fixtures.workspaces,
+ config,
+ })
- await outdated(testDir, {}).exec([])
+ await exec([])
- t.matchSnapshot(logs, 'should display ws outdated deps human output')
- t.equal(process.exitCode, 1)
+ t.matchSnapshot(joinedOutput(), 'output')
+ t.equal(process.exitCode, exitCode ?? undefined)
+ }
- await outdated(testDir, {
- flatOptions: {
- workspacesEnabled: false,
- },
- }).exec([])
+ await t.test('should display ws outdated deps human output', t =>
+ mockWorkspaces(t))
// TODO: This should display dog, but doesn't because arborist filters
// workspace deps even if they're also root deps
// This will be fixed in a future arborist version
- t.matchSnapshot(logs, 'should display only root outdated when ws disabled')
-
- await outdated(testDir, {
- config: {
- json: true,
- },
- }).exec([])
- t.matchSnapshot(logs, 'should display ws outdated deps json output')
- t.equal(process.exitCode, 1)
-
- await outdated(testDir, {
- config: {
- parseable: true,
- },
- }).exec([])
+ await t.test('should display only root outdated when ws disabled', t =>
+ mockWorkspaces(t, { workspaces: false, exitCode: null }))
- t.matchSnapshot(logs, 'should display ws outdated deps parseable output')
- t.equal(process.exitCode, 1)
-
- await outdated(testDir, {
- config: {
- all: true,
- },
- }).exec([])
-
- t.matchSnapshot(logs, 'should display all dependencies')
- t.equal(process.exitCode, 1)
+ await t.test('should display ws outdated deps json output', t =>
+ mockWorkspaces(t, { json: true }))
- await outdated(testDir, {
- color: true,
- }).exec([])
+ await t.test('should display ws outdated deps parseable output', t =>
+ mockWorkspaces(t, { parseable: true }))
- t.matchSnapshot(logs, 'should highlight ws in dependend by section')
- t.equal(process.exitCode, 1)
+ await t.test('should display all dependencies', t =>
+ mockWorkspaces(t, { all: true }))
- await outdated(testDir, {}).execWorkspaces([], ['a'])
- t.matchSnapshot(logs, 'should display results filtered by ws')
- t.equal(process.exitCode, 1)
+ await t.test('should highlight ws in dependend by section', t =>
+ mockWorkspaces(t, { color: 'always' }))
- await outdated(testDir, {
- config: {
- json: true,
- },
- }).execWorkspaces([], ['a'])
- t.matchSnapshot(logs, 'should display json results filtered by ws')
- t.equal(process.exitCode, 1)
+ await t.test('should display results filtered by ws', t =>
+ mockWorkspaces(t, { workspace: 'a' }))
- await outdated(testDir, {
- config: {
- parseable: true,
- },
- }).execWorkspaces([], ['a'])
- t.matchSnapshot(logs, 'should display parseable results filtered by ws')
- t.equal(process.exitCode, 1)
+ await t.test('should display json results filtered by ws', t =>
+ mockWorkspaces(t, { json: true, workspace: 'a' }))
- await outdated(testDir, {
- config: {
- all: true,
- },
- }).execWorkspaces([], ['a'])
+ await t.test('should display parseable results filtered by ws', t =>
+ mockWorkspaces(t, { parseable: true, workspace: 'a' }))
- t.matchSnapshot(logs,
- 'should display nested deps when filtering by ws and using --all')
- t.equal(process.exitCode, 1)
+ await t.test('should display nested deps when filtering by ws and using --all', t =>
+ mockWorkspaces(t, { all: true, workspace: 'a' }))
- await outdated(testDir, {}).execWorkspaces([], ['b'])
- t.matchSnapshot(logs,
- 'should display no results if ws has no deps to display')
+ await t.test('should display no results if ws has no deps to display', t =>
+ mockWorkspaces(t, { workspace: 'b', exitCode: null }))
- await outdated(testDir, {}).execWorkspaces([], ['c'])
- t.matchSnapshot(logs,
- 'should display missing deps when filtering by ws')
+ await t.test('should display missing deps when filtering by ws', t =>
+ mockWorkspaces(t, { workspace: 'c', exitCode: 1 }))
})
t.test('aliases', async t => {
- const testDir = t.testdir({
+ const testDir = {
'package.json': JSON.stringify({
name: 'display-aliases',
version: '1.0.0',
@@ -642,10 +601,13 @@ t.test('aliases', async t => {
}),
},
},
- })
+ }
- await outdated(testDir, {}).exec([])
+ const { exec, joinedOutput } = await mockNpm(t, {
+ prefixDir: testDir,
+ })
+ await exec([])
- t.matchSnapshot(logs, 'should display aliased outdated dep output')
+ t.matchSnapshot(joinedOutput(), 'should display aliased outdated dep output')
t.equal(process.exitCode, 1)
})
diff --git a/deps/npm/test/lib/commands/owner.js b/deps/npm/test/lib/commands/owner.js
index 5b6bb44371..f9399a60cd 100644
--- a/deps/npm/test/lib/commands/owner.js
+++ b/deps/npm/test/lib/commands/owner.js
@@ -470,8 +470,10 @@ t.test('workspaces', async t => {
t.test('owner no args --workspace', async t => {
const { npm } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
+ config: {
+ workspace: 'workspace-a',
+ },
})
- npm.config.set('workspace', ['workspace-a'])
await t.rejects(
npm.exec('owner', []),
{ code: 'EUSAGE' },
@@ -482,9 +484,7 @@ t.test('workspaces', async t => {
t.test('owner ls implicit workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => path.join(prefix, 'workspace-a'),
- }),
+ chdir: ({ prefix }) => path.join(prefix, 'workspace-a'),
})
await registryPackage(t, npm.config.get('registry'), 'workspace-a')
await npm.exec('owner', ['ls'])
@@ -494,11 +494,10 @@ t.test('workspaces', async t => {
t.test('owner ls explicit workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
+ config: {
+ workspace: 'workspace-a',
+ },
})
- npm.config.set('workspace', ['workspace-a'])
await registryPackage(t, npm.config.get('registry'), 'workspace-a')
await npm.exec('owner', ['ls'])
t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n'))
@@ -507,9 +506,7 @@ t.test('workspaces', async t => {
t.test('owner ls <pkg> implicit workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => path.join(prefix, 'workspace-a'),
- }),
+ chdir: ({ prefix }) => path.join(prefix, 'workspace-a'),
})
await registryPackage(t, npm.config.get('registry'), packageName)
await npm.exec('owner', ['ls', packageName])
@@ -519,11 +516,10 @@ t.test('workspaces', async t => {
t.test('owner ls <pkg> explicit workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
+ config: {
+ workspace: 'workspace-a',
+ },
})
- npm.config.set('workspace', ['workspace-a'])
await registryPackage(t, npm.config.get('registry'), packageName)
await npm.exec('owner', ['ls', packageName])
t.match(joinedOutput(), maintainers.map(m => `${m.name} <${m.email}>`).join('\n'))
@@ -532,9 +528,7 @@ t.test('workspaces', async t => {
t.test('owner add implicit workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => path.join(prefix, 'workspace-a'),
- }),
+ chdir: ({ prefix }) => path.join(prefix, 'workspace-a'),
})
const username = 'foo'
const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') })
@@ -563,8 +557,10 @@ t.test('workspaces', async t => {
t.test('owner add --workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
+ config: {
+ workspace: 'workspace-a',
+ },
})
- npm.config.set('workspace', ['workspace-a'])
const username = 'foo'
const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') })
@@ -592,9 +588,7 @@ t.test('workspaces', async t => {
t.test('owner rm --workspace', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
prefixDir: workspaceFixture,
- globals: ({ prefix }) => ({
- 'process.cwd': () => path.join(prefix, 'workspace-a'),
- }),
+ chdir: ({ prefix }) => path.join(prefix, 'workspace-a'),
})
const registry = new MockRegistry({ tap: t, registry: npm.config.get('registry') })
diff --git a/deps/npm/test/lib/commands/pack.js b/deps/npm/test/lib/commands/pack.js
index 199afc640f..3e7c0225c3 100644
--- a/deps/npm/test/lib/commands/pack.js
+++ b/deps/npm/test/lib/commands/pack.js
@@ -3,11 +3,6 @@ const { load: loadMockNpm } = require('../../fixtures/mock-npm')
const path = require('path')
const fs = require('fs')
-const cwd = process.cwd()
-t.afterEach(t => {
- process.chdir(cwd)
-})
-
t.test('should pack current directory with no arguments', async t => {
const { npm, outputs, logs } = await loadMockNpm(t, {
prefixDir: {
@@ -17,7 +12,6 @@ t.test('should pack current directory with no arguments', async t => {
}),
},
})
- process.chdir(npm.prefix)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
t.strictSame(outputs, [[filename]])
@@ -35,7 +29,6 @@ t.test('follows pack-destination config', async t => {
'tar-destination': {},
},
})
- process.chdir(npm.prefix)
npm.config.set('pack-destination', path.join(npm.prefix, 'tar-destination'))
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
@@ -52,7 +45,6 @@ t.test('should pack given directory for scoped package', async t => {
}),
},
})
- process.chdir(npm.prefix)
await npm.exec('pack', [])
const filename = 'npm-test-package-1.0.0.tgz'
t.strictSame(outputs, [[filename]])
@@ -68,7 +60,6 @@ t.test('should log output as valid json', async t => {
}),
},
})
- process.chdir(npm.prefix)
npm.config.set('json', true)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
@@ -86,7 +77,6 @@ t.test('should log scoped package output as valid json', async t => {
}),
},
})
- process.chdir(npm.prefix)
npm.config.set('json', true)
await npm.exec('pack', [])
const filename = 'myscope-test-package-1.0.0.tgz'
@@ -105,7 +95,6 @@ t.test('dry run', async t => {
},
})
npm.config.set('dry-run', true)
- process.chdir(npm.prefix)
await npm.exec('pack', [])
const filename = 'test-package-1.0.0.tgz'
t.strictSame(outputs, [[filename]])
@@ -119,7 +108,6 @@ t.test('invalid packument', async t => {
'package.json': '{}',
},
})
- process.chdir(npm.prefix)
await t.rejects(
npm.exec('pack', []),
/Invalid package, must have name and version/
@@ -162,28 +150,24 @@ t.test('workspaces', async t => {
t.test('all workspaces', async t => {
const { npm, outputs } = await loadWorkspaces(t)
- process.chdir(npm.prefix)
await npm.exec('pack', [])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']])
})
t.test('all workspaces, `.` first arg', async t => {
const { npm, outputs } = await loadWorkspaces(t)
- process.chdir(npm.prefix)
await npm.exec('pack', ['.'])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz'], ['workspace-b-1.0.0.tgz']])
})
t.test('one workspace', async t => {
const { npm, outputs } = await loadWorkspaces(t)
- process.chdir(npm.prefix)
await npm.exec('pack', ['workspace-a'])
t.strictSame(outputs, [['workspace-a-1.0.0.tgz']])
})
t.test('specific package', async t => {
const { npm, outputs } = await loadWorkspaces(t)
- process.chdir(npm.prefix)
await npm.exec('pack', [npm.prefix])
t.strictSame(outputs, [['workspaces-test-1.0.0.tgz']])
})
diff --git a/deps/npm/test/lib/commands/pkg.js b/deps/npm/test/lib/commands/pkg.js
index 49234e4cce..ef38d53730 100644
--- a/deps/npm/test/lib/commands/pkg.js
+++ b/deps/npm/test/lib/commands/pkg.js
@@ -1,76 +1,61 @@
const { resolve } = require('path')
const { readFileSync } = require('fs')
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const redactCwd = (path) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
-}
+const _mockNpm = require('../../fixtures/mock-npm')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
-t.cleanSnapshot = (str) => redactCwd(str)
+t.cleanSnapshot = (str) => cleanCwd(str)
-let OUTPUT = ''
-const config = {
- global: false,
- force: false,
- 'pkg-cast': 'string',
-}
-const npm = mockNpm({
- localPrefix: t.testdirName,
- config,
- output: (str) => {
- OUTPUT += str
- },
-})
+const mockNpm = async (t, { ...opts } = {}) => {
+ const res = await _mockNpm(t, opts)
-const Pkg = require('../../../lib/commands/pkg.js')
-const pkg = new Pkg(npm)
+ const readPackageJson = (dir = '') =>
+ JSON.parse(readFileSync(resolve(res.prefix, dir, 'package.json'), 'utf8'))
-const readPackageJson = (path) => {
- path = path || npm.localPrefix
- return JSON.parse(readFileSync(resolve(path, 'package.json'), 'utf8'))
+ return {
+ ...res,
+ pkg: (...args) => res.npm.exec('pkg', args),
+ readPackageJson,
+ OUTPUT: () => res.joinedOutput(),
+ }
}
-t.afterEach(() => {
- config.global = false
- config.json = false
- npm.localPrefix = t.testdirName
- OUTPUT = ''
-})
-
t.test('no args', async t => {
+ const { pkg } = await mockNpm(t)
+
await t.rejects(
- pkg.exec([]),
+ pkg(),
{ code: 'EUSAGE' },
'should throw usage error'
)
})
t.test('no global mode', async t => {
- config.global = true
+ const { pkg } = await mockNpm(t, {
+ config: { global: true },
+ })
+
await t.rejects(
- pkg.exec(['get', 'foo']),
+ pkg('get', 'foo'),
{ code: 'EPKGGLOBAL' },
'should throw no global mode error'
)
})
t.test('get no args', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ }),
+ },
})
- await pkg.exec(['get'])
+ await pkg('get')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
{
name: 'foo',
version: '1.1.1',
@@ -80,37 +65,41 @@ t.test('get no args', async t => {
})
t.test('get single arg', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ }),
+ },
})
- await pkg.exec(['get', 'version'])
+ await pkg('get', 'version')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
'1.1.1',
'should print retrieved package.json field'
)
})
t.test('get nested arg', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- scripts: {
- test: 'node test.js',
- },
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ scripts: {
+ test: 'node test.js',
+ },
+ }),
+ },
})
- await pkg.exec(['get', 'scripts.test'])
+ await pkg('get', 'scripts.test')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
'node test.js',
'should print retrieved nested field'
)
@@ -121,18 +110,20 @@ t.test('get array field', async t => {
'index.js',
'cli.js',
]
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- files,
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ files,
+ }),
+ },
})
- await pkg.exec(['get', 'files'])
+ await pkg('get', 'files')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
files,
'should print retrieved array field'
)
@@ -143,18 +134,20 @@ t.test('get array item', async t => {
'index.js',
'cli.js',
]
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- files,
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ files,
+ }),
+ },
})
- await pkg.exec(['get', 'files[0]'])
+ await pkg('get', 'files[0]')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
'index.js',
'should print retrieved array field'
)
@@ -171,17 +164,19 @@ t.test('get array nested items notation', async t => {
url: 'http://example.com/gar',
},
]
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- contributors,
- }),
+ const { pkg, OUTPUT } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ contributors,
+ }),
+ },
})
- await pkg.exec(['get', 'contributors.name'])
+ await pkg('get', 'contributors.name')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
{
'contributors[0].name': 'Ruy',
'contributors[1].name': 'Gar',
@@ -191,33 +186,39 @@ t.test('get array nested items notation', async t => {
})
t.test('set no args', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
+ const { pkg } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'foo' }),
+ },
})
await t.rejects(
- pkg.exec(['set']),
+ pkg('set'),
{ code: 'EUSAGE' },
'should throw an error if no args'
)
})
t.test('set missing value', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
+ const { pkg } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'foo' }),
+ },
})
await t.rejects(
- pkg.exec(['set', 'key=']),
+ pkg('set', 'key='),
{ code: 'EUSAGE' },
'should throw an error if missing value'
)
})
t.test('set missing key', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
+ const { pkg } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'foo' }),
+ },
})
await t.rejects(
- pkg.exec(['set', '=value']),
+ pkg('set', '=value'),
{ code: 'EUSAGE' },
'should throw an error if missing key'
)
@@ -228,11 +229,13 @@ t.test('set single field', async t => {
name: 'foo',
version: '1.1.1',
}
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify(json),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(json),
+ },
})
- await pkg.exec(['set', 'description=Awesome stuff'])
+ await pkg('set', 'description=Awesome stuff')
t.strictSame(
readPackageJson(),
{
@@ -251,11 +254,13 @@ t.test('push to array syntax', async t => {
'foo',
],
}
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify(json),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(json),
+ },
})
- await pkg.exec(['set', 'keywords[]=bar', 'keywords[]=baz'])
+ await pkg('set', 'keywords[]=bar', 'keywords[]=baz')
t.strictSame(
readPackageJson(),
{
@@ -275,11 +280,13 @@ t.test('set multiple fields', async t => {
name: 'foo',
version: '1.1.1',
}
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify(json),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(json),
+ },
})
- await pkg.exec(['set', 'bin.foo=foo.js', 'scripts.test=node test.js'])
+ await pkg('set', 'bin.foo=foo.js', 'scripts.test=node test.js')
t.strictSame(
readPackageJson(),
{
@@ -300,11 +307,13 @@ t.test('set = separate value', async t => {
name: 'foo',
version: '1.1.1',
}
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify(json),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(json),
+ },
})
- await pkg.exec(['set', 'tap[test-env][0]=LC_ALL=sk'])
+ await pkg('set', 'tap[test-env][0]=LC_ALL=sk')
t.strictSame(
readPackageJson(),
{
@@ -320,15 +329,17 @@ t.test('set = separate value', async t => {
})
t.test('set --json', async t => {
- config.json = true
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.1.1',
- }),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.1.1',
+ }),
+ },
+ config: { json: true },
})
- await pkg.exec(['set', 'private=true'])
+ await pkg('set', 'private=true')
t.strictSame(
readPackageJson(),
{
@@ -339,7 +350,7 @@ t.test('set --json', async t => {
'should add boolean field to package.json'
)
- await pkg.exec(['set', 'tap.timeout=60'])
+ await pkg('set', 'tap.timeout=60')
t.strictSame(
readPackageJson(),
{
@@ -353,7 +364,7 @@ t.test('set --json', async t => {
'should add number field to package.json'
)
- await pkg.exec(['set', 'foo={ "bar": { "baz": "BAZ" } }'])
+ await pkg('set', 'foo={ "bar": { "baz": "BAZ" } }')
t.strictSame(
readPackageJson(),
{
@@ -372,7 +383,7 @@ t.test('set --json', async t => {
'should add object field to package.json'
)
- await pkg.exec(['set', 'workspaces=["packages/*"]'])
+ await pkg('set', 'workspaces=["packages/*"]')
t.strictSame(
readPackageJson(),
{
@@ -394,7 +405,7 @@ t.test('set --json', async t => {
'should add object field to package.json'
)
- await pkg.exec(['set', 'description="awesome"'])
+ await pkg('set', 'description="awesome"')
t.strictSame(
readPackageJson(),
{
@@ -419,35 +430,41 @@ t.test('set --json', async t => {
})
t.test('delete no args', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
+ const { pkg } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'foo' }),
+ },
})
await t.rejects(
- pkg.exec(['delete']),
+ pkg('delete'),
{ code: 'EUSAGE' },
'should throw an error if deleting no args'
)
})
t.test('delete invalid key', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'foo' }),
+ const { pkg } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'foo' }),
+ },
})
await t.rejects(
- pkg.exec(['delete', '']),
+ pkg('delete', ''),
{ code: 'EUSAGE' },
'should throw an error if deleting invalid args'
)
})
t.test('delete single field', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- }),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ }),
+ },
})
- await pkg.exec(['delete', 'version'])
+ await pkg('delete', 'version')
t.strictSame(
readPackageJson(),
{
@@ -458,14 +475,16 @@ t.test('delete single field', async t => {
})
t.test('delete multiple field', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- description: 'awesome',
- }),
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ description: 'awesome',
+ }),
+ },
})
- await pkg.exec(['delete', 'version', 'description'])
+ await pkg('delete', 'version', 'description')
t.strictSame(
readPackageJson(),
{
@@ -476,22 +495,24 @@ t.test('delete multiple field', async t => {
})
t.test('delete nested field', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- info: {
- foo: {
- bar: [
- {
- baz: 'deleteme',
- },
- ],
+ const { pkg, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ info: {
+ foo: {
+ bar: [
+ {
+ baz: 'deleteme',
+ },
+ ],
+ },
},
- },
- }),
+ }),
+ },
})
- await pkg.exec(['delete', 'info.foo.bar[0].baz'])
+ await pkg('delete', 'info.foo.bar[0].baz')
t.strictSame(
readPackageJson(),
{
@@ -510,34 +531,37 @@ t.test('delete nested field', async t => {
})
t.test('workspaces', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'root',
- version: '1.0.0',
- workspaces: [
- 'packages/*',
- ],
- }),
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.2.3',
- }),
+ const { pkg, OUTPUT, readPackageJson } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'root',
+ version: '1.0.0',
+ workspaces: [
+ 'packages/*',
+ ],
+ }),
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.2.3',
+ }),
+ },
},
},
+ config: { workspaces: true },
})
- await pkg.execWorkspaces(['get', 'name', 'version'], [])
+ await pkg('get', 'name', 'version')
t.strictSame(
- JSON.parse(OUTPUT),
+ JSON.parse(OUTPUT()),
{
a: {
name: 'a',
@@ -551,10 +575,10 @@ t.test('workspaces', async t => {
'should return expected result for configured workspaces'
)
- await pkg.execWorkspaces(['set', 'funding=http://example.com'], [])
+ await pkg('set', 'funding=http://example.com')
t.strictSame(
- readPackageJson(resolve(npm.localPrefix, 'packages/a')),
+ readPackageJson('packages/a'),
{
name: 'a',
version: '1.0.0',
@@ -564,7 +588,7 @@ t.test('workspaces', async t => {
)
t.strictSame(
- readPackageJson(resolve(npm.localPrefix, 'packages/b')),
+ readPackageJson('packages/b'),
{
name: 'b',
version: '1.2.3',
@@ -573,9 +597,10 @@ t.test('workspaces', async t => {
'should add field to workspace b'
)
- await pkg.execWorkspaces(['delete', 'version'], [])
+ await pkg('delete', 'version')
+
t.strictSame(
- readPackageJson(resolve(npm.localPrefix, 'packages/a')),
+ readPackageJson('packages/a'),
{
name: 'a',
funding: 'http://example.com',
@@ -584,7 +609,7 @@ t.test('workspaces', async t => {
)
t.strictSame(
- readPackageJson(resolve(npm.localPrefix, 'packages/b')),
+ readPackageJson('packages/b'),
{
name: 'b',
funding: 'http://example.com',
diff --git a/deps/npm/test/lib/commands/profile.js b/deps/npm/test/lib/commands/profile.js
index 09fd08cfc5..00ccf26075 100644
--- a/deps/npm/test/lib/commands/profile.js
+++ b/deps/npm/test/lib/commands/profile.js
@@ -1,50 +1,45 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-let result = ''
-const config = {
- otp: '',
- json: false,
- parseable: false,
- registry: 'https://registry.npmjs.org/',
-}
-const flatOptions = {
- registry: 'https://registry.npmjs.org/',
-}
-const npm = mockNpm({
- config,
- flatOptions,
- output: (...msg) => {
- result = result ? `${result}\n${msg.join('\n')}` : msg.join('\n')
- },
-})
-const mocks = {
- npmlog: {
- gauge: { show () {} },
- },
- 'proc-log': {
- info () {},
- notice () {},
- warn () {},
- },
- 'npm-profile': {
- async get () {},
- async set () {},
- async createToken () {},
- },
- 'qrcode-terminal': { generate: (url, cb) => cb() },
- 'cli-table3': class extends Array {
- toString () {
- return this.filter(Boolean)
- .map(i => [...Object.entries(i)].map(i => i.join(': ')))
- .join('\n')
- }
- },
- '../../../lib/utils/read-user-info.js': {
- async password () {},
- async otp () {},
- },
+const mockNpm = require('../../fixtures/mock-npm')
+
+const mockProfile = async (t, { npmProfile, readUserInfo, qrcode, ...opts } = {}) => {
+ const mocks = {
+ 'npm-profile': npmProfile || {
+ async get () {},
+ async set () {},
+ async createToken () {},
+ },
+ 'qrcode-terminal': qrcode || { generate: (url, cb) => cb() },
+ 'cli-table3': class extends Array {
+ toString () {
+ return this.filter(Boolean)
+ .map(i => [...Object.entries(i)].map(v => v.join(': ')))
+ .join('\n')
+ }
+ },
+ '{LIB}/utils/read-user-info.js': readUserInfo || {
+ async password () {},
+ async otp () {},
+ },
+ }
+
+ const mock = await mockNpm(t, {
+ ...opts,
+ mocks: {
+ ...mocks,
+ ...opts.mocks,
+ },
+ })
+
+ return {
+ ...mock,
+ result: () => mock.joinedOutput(),
+ profile: {
+ exec: (args) => mock.npm.exec('profile', args),
+ usage: () => mock.npm.cmd('profile').then(c => c.usage),
+ },
+ }
}
+
const userProfile = {
tfa: { pending: false, mode: 'auth-and-writes' },
name: 'foo',
@@ -60,53 +55,44 @@ const userProfile = {
github: 'https://github.com/npm',
}
-t.afterEach(() => {
- result = ''
- flatOptions.otp = ''
- config.json = false
- config.parseable = false
- config.registry = 'https://registry.npmjs.org/'
-})
-
-const Profile = t.mock('../../../lib/commands/profile.js', mocks)
-const profile = new Profile(npm)
-
t.test('no args', async t => {
- await t.rejects(profile.exec([]), profile.usage)
+ const { profile } = await mockProfile(t)
+ await t.rejects(profile.exec([]), await profile.usage())
})
-t.test('profile get no args', t => {
- const npmProfile = {
+t.test('profile get no args', async t => {
+ const defaultNpmProfile = {
async get () {
return userProfile
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
-
t.test('default output', async t => {
+ const { profile, result } = await mockProfile(t, { npmProfile: defaultNpmProfile })
await profile.exec(['get'])
- t.matchSnapshot(result, 'should output table with contents')
+ t.matchSnapshot(result(), 'should output table with contents')
})
t.test('--json', async t => {
- config.json = true
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: defaultNpmProfile,
+ config: { json: true },
+ })
await profile.exec(['get'])
- t.same(JSON.parse(result), userProfile, 'should output json profile result')
+ t.same(JSON.parse(result()), userProfile, 'should output json profile result')
})
t.test('--parseable', async t => {
- config.parseable = true
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: defaultNpmProfile,
+ config: { parseable: true },
+ })
await profile.exec(['get'])
- t.matchSnapshot(result, 'should output all profile info as parseable result')
+ t.matchSnapshot(result(), 'should output all profile info as parseable result')
})
t.test('no tfa enabled', async t => {
@@ -118,15 +104,10 @@ t.test('profile get no args', t => {
}
},
}
-
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
+ const { profile, result } = await mockProfile(t, { npmProfile })
await profile.exec(['get'])
- t.matchSnapshot(result, 'should output expected profile values')
+ t.matchSnapshot(result(), 'should output expected profile values')
})
t.test('unverified email', async t => {
@@ -139,15 +120,11 @@ t.test('profile get no args', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
+ const { profile, result } = await mockProfile(t, { npmProfile })
await profile.exec(['get'])
- t.matchSnapshot(result, 'should output table with contents')
+ t.matchSnapshot(result(), 'should output table with contents')
})
t.test('profile has cidr_whitelist item', async t => {
@@ -160,127 +137,111 @@ t.test('profile get no args', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
+ const { profile, result } = await mockProfile(t, { npmProfile })
await profile.exec(['get'])
- t.matchSnapshot(result, 'should output table with contents')
+ t.matchSnapshot(result(), 'should output table with contents')
})
-
- t.end()
})
-t.test('profile get <key>', t => {
+t.test('profile get <key>', async t => {
const npmProfile = {
async get () {
return userProfile
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
-
t.test('default output', async t => {
+ const { profile, result } = await mockProfile(t, { npmProfile })
+
await profile.exec(['get', 'name'])
- t.equal(result, 'foo', 'should output value result')
+ t.equal(result(), 'foo', 'should output value result')
})
t.test('--json', async t => {
- config.json = true
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ config: { json: true },
+ })
await profile.exec(['get', 'name'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
userProfile,
'should output json profile result ignoring args filter'
)
})
t.test('--parseable', async t => {
- config.parseable = true
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ config: { parseable: true },
+ })
await profile.exec(['get', 'name'])
- t.matchSnapshot(result, 'should output parseable result value')
+ t.matchSnapshot(result(), 'should output parseable result value')
})
-
- t.end()
})
-t.test('profile get multiple args', t => {
+t.test('profile get multiple args', async t => {
const npmProfile = {
async get () {
return userProfile
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- })
- const profile = new Profile(npm)
-
t.test('default output', async t => {
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ })
await profile.exec(['get', 'name', 'email', 'github'])
- t.matchSnapshot(result, 'should output all keys')
+ t.matchSnapshot(result(), 'should output all keys')
})
t.test('--json', async t => {
- config.json = true
+ const config = { json: true }
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ config,
+ })
await profile.exec(['get', 'name', 'email', 'github'])
- t.same(JSON.parse(result), userProfile, 'should output json profile result and ignore args')
+ t.same(JSON.parse(result()), userProfile, 'should output json profile result and ignore args')
})
t.test('--parseable', async t => {
- config.parseable = true
+ const config = { parseable: true }
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ config,
+ })
await profile.exec(['get', 'name', 'email', 'github'])
- t.matchSnapshot(result, 'should output parseable profile value results')
+ t.matchSnapshot(result(), 'should output parseable profile value results')
})
t.test('comma separated', async t => {
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ })
+
await profile.exec(['get', 'name,email,github'])
- t.matchSnapshot(result, 'should output all keys')
+ t.matchSnapshot(result(), 'should output all keys')
})
-
- t.end()
})
-t.test('profile set <key> <value>', t => {
- const npmProfile = t => ({
- async get () {
- return userProfile
- },
- async set (newUser, conf) {
- t.match(
- newUser,
- {
- fullname: 'Lorem Ipsum',
- },
- 'should set new value to key'
- )
- return {
- ...userProfile,
- ...newUser,
- }
- },
- })
-
+t.test('profile set <key> <value>', async t => {
t.test('no key', async t => {
+ const { profile } = await mockProfile(t)
+
await t.rejects(
profile.exec(['set']),
/npm profile set <prop> <value>/,
@@ -289,6 +250,7 @@ t.test('profile set <key> <value>', t => {
})
t.test('no value', async t => {
+ const { profile } = await mockProfile(t)
await t.rejects(
profile.exec(['set', 'email']),
/npm profile set <prop> <value>/,
@@ -297,6 +259,7 @@ t.test('profile set <key> <value>', t => {
})
t.test('set password', async t => {
+ const { profile } = await mockProfile(t)
await t.rejects(
profile.exec(['set', 'password', '1234']),
/Do not include your current or new passwords on the command line./,
@@ -305,6 +268,7 @@ t.test('profile set <key> <value>', t => {
})
t.test('unwritable key', async t => {
+ const { profile } = await mockProfile(t)
await await t.rejects(
profile.exec(['set', 'name', 'foo']),
/"name" is not a property we can set./,
@@ -312,35 +276,51 @@ t.test('profile set <key> <value>', t => {
)
})
- t.test('writable key', t => {
+ const defaultNpmProfile = t => ({
+ async get () {
+ return userProfile
+ },
+ async set (newUser) {
+ t.match(
+ newUser,
+ {
+ fullname: 'Lorem Ipsum',
+ },
+ 'should set new value to key'
+ )
+ return {
+ ...userProfile,
+ ...newUser,
+ }
+ },
+ })
+
+ t.test('writable key', async t => {
t.test('default output', async t => {
t.plan(2)
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: defaultNpmProfile(t),
})
- const profile = new Profile(npm)
await profile.exec(['set', 'fullname', 'Lorem Ipsum'])
- t.equal(result, 'Set\nfullname\nto\nLorem Ipsum', 'should output set key success msg')
+ t.equal(result(), 'Set fullname to Lorem Ipsum', 'should output set key success msg')
})
t.test('--json', async t => {
t.plan(2)
- config.json = true
+ const config = { json: true }
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: defaultNpmProfile(t),
+ config,
})
- const profile = new Profile(npm)
await profile.exec(['set', 'fullname', 'Lorem Ipsum'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
{
fullname: 'Lorem Ipsum',
},
@@ -351,30 +331,26 @@ t.test('profile set <key> <value>', t => {
t.test('--parseable', async t => {
t.plan(2)
- config.parseable = true
-
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
+ const config = { parseable: true }
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: defaultNpmProfile(t),
+ config,
})
- const profile = new Profile(npm)
await profile.exec(['set', 'fullname', 'Lorem Ipsum'])
- t.matchSnapshot(result, 'should output parseable set key success msg')
+ t.matchSnapshot(result(), 'should output parseable set key success msg')
})
-
- t.end()
})
t.test('write new email', async t => {
- t.plan(3)
+ t.plan(2)
const npmProfile = {
async get () {
return userProfile
},
- async set (newUser, conf) {
+ async set (newUser) {
t.match(
newUser,
{
@@ -382,7 +358,6 @@ t.test('profile set <key> <value>', t => {
},
'should set new value to email'
)
- t.match(conf, npm.flatOptions, 'should forward flatOptions config')
return {
...userProfile,
...newUser,
@@ -390,24 +365,22 @@ t.test('profile set <key> <value>', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
})
- const profile = new Profile(npm)
await profile.exec(['set', 'email', 'foo@npmjs.com'])
- t.equal(result, 'Set\nemail\nto\nfoo@npmjs.com', 'should output set key success msg')
+ t.equal(result(), 'Set email to foo@npmjs.com', 'should output set key success msg')
})
t.test('change password', async t => {
- t.plan(6)
+ t.plan(5)
const npmProfile = {
async get () {
return userProfile
},
- async set (newUser, conf) {
+ async set (newUser) {
t.match(
newUser,
{
@@ -418,7 +391,6 @@ t.test('profile set <key> <value>', t => {
},
'should set new password'
)
- t.match(conf, npm.flatOptions, 'should forward flatOptions config')
return {
...userProfile,
}
@@ -441,30 +413,27 @@ t.test('profile set <key> <value>', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
})
- const profile = new Profile(npm)
await profile.exec(['set', 'password'])
- t.equal(result, 'Set\npassword', 'should output set password success msg')
+ t.equal(result(), 'Set password', 'should output set password success msg')
})
t.test('password confirmation mismatch', async t => {
- t.plan(3)
+ t.plan(2)
+
let passwordPromptCount = 0
const npmProfile = {
async get () {
return userProfile
},
- async set (newUser, conf) {
- return {
- ...userProfile,
- }
+ async set () {
+ return { ...userProfile }
},
}
@@ -485,38 +454,26 @@ t.test('profile set <key> <value>', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- npmlog: {
- gauge: {
- show () {},
- },
- },
- 'proc-log': {
- warn (title, msg) {
- t.equal(title, 'profile', 'should use expected profile')
- t.equal(
- msg,
- 'Passwords do not match, please try again.',
- 'should log password mismatch message'
- )
- },
- },
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { profile, result, logs } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
})
- const profile = new Profile(npm)
await profile.exec(['set', 'password'])
- t.equal(result, 'Set\npassword', 'should output set password success msg')
- })
+ t.equal(
+ logs.warn[0][1],
+ 'Passwords do not match, please try again.',
+ 'should log password mismatch message'
+ )
- t.end()
+ t.equal(result(), 'Set password', 'should output set password success msg')
+ })
})
-t.test('enable-2fa', t => {
+t.test('enable-2fa', async t => {
t.test('invalid args', async t => {
+ const { profile } = await mockProfile(t)
await t.rejects(
profile.exec(['enable-2fa', 'foo', 'bar']),
/npm profile enable-2fa \[auth-and-writes|auth-only\]/,
@@ -525,6 +482,7 @@ t.test('enable-2fa', t => {
})
t.test('invalid two factor auth mode', async t => {
+ const { profile } = await mockProfile(t)
await t.rejects(
profile.exec(['enable-2fa', 'foo']),
/Invalid two-factor authentication mode "foo"/,
@@ -533,7 +491,8 @@ t.test('enable-2fa', t => {
})
t.test('no support for --json output', async t => {
- config.json = true
+ const config = { json: true }
+ const { profile } = await mockProfile(t, { config })
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -544,7 +503,8 @@ t.test('enable-2fa', t => {
})
t.test('no support for --parseable output', async t => {
- config.parseable = true
+ const config = { parseable: true }
+ const { profile } = await mockProfile(t, { config })
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -557,12 +517,6 @@ t.test('enable-2fa', t => {
t.test('no bearer tokens returned by registry', async t => {
t.plan(3)
- // mock legacy basic auth style
- npm.config.getCredentialsByURI = reg => {
- t.equal(reg, flatOptions.registry, 'should use expected registry')
- return { auth: Buffer.from('foo:bar').toString('base64') }
- }
-
const npmProfile = {
async createToken (pass) {
t.match(pass, 'bar', 'should use password for basic auth')
@@ -570,11 +524,16 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
+ const { npm, profile } = await mockProfile(t, {
+ npmProfile,
})
- const profile = new Profile(npm)
+
+ // mock legacy basic auth style
+ // XXX: use mock registry
+ npm.config.getCredentialsByURI = reg => {
+ t.equal(reg, npm.flatOptions.registry, 'should use expected registry')
+ return { auth: Buffer.from('foo:bar').toString('base64') }
+ }
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -586,22 +545,21 @@ t.test('enable-2fa', t => {
})
t.test('from basic username/password auth', async t => {
- // mock legacy basic auth style with user/pass
- npm.config.getCredentialsByURI = () => {
- return { username: 'foo', password: 'bar' }
- }
-
const npmProfile = {
async createToken (pass) {
return {}
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
+ const { npm, profile } = await mockProfile(t, {
+ npmProfile,
})
- const profile = new Profile(npm)
+
+ // mock legacy basic auth style with user/pass
+ // XXX: use mock registry
+ npm.config.getCredentialsByURI = () => {
+ return { username: 'foo', password: 'bar' }
+ }
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -613,12 +571,10 @@ t.test('enable-2fa', t => {
})
t.test('no auth found', async t => {
- npm.config.getCredentialsByURI = () => ({})
+ const { npm, profile } = await mockProfile(t)
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- })
- const profile = new Profile(npm)
+ // XXX: use mock registry
+ npm.config.getCredentialsByURI = () => ({})
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -627,20 +583,7 @@ t.test('enable-2fa', t => {
})
t.test('from basic auth, asks for otp', async t => {
- t.plan(10)
-
- // mock legacy basic auth style
- npm.config.getCredentialsByURI = reg => {
- t.equal(reg, flatOptions.registry, 'should use expected registry')
- return { auth: Buffer.from('foo:bar').toString('base64') }
- }
- npm.config.setCredentialsByURI = (registry, { token }) => {
- t.equal(registry, flatOptions.registry, 'should set expected registry')
- t.equal(token, 'token', 'should set expected token')
- }
- npm.config.save = type => {
- t.equal(type, 'user', 'should save to user config')
- }
+ t.plan(9)
const npmProfile = {
async createToken (pass) {
@@ -660,14 +603,6 @@ t.test('enable-2fa', t => {
},
'should set tfa mode'
)
- t.match(
- conf,
- {
- ...npm.flatOptions,
- otp: '123456',
- },
- 'should forward flatOptions config'
- )
return {
...userProfile,
tfa: null,
@@ -690,16 +625,28 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
})
- const profile = new Profile(npm)
+
+ // mock legacy basic auth style
+ // XXX: use mock registry
+ npm.config.getCredentialsByURI = reg => {
+ t.equal(reg, npm.flatOptions.registry, 'should use expected registry')
+ return { auth: Buffer.from('foo:bar').toString('base64') }
+ }
+ npm.config.setCredentialsByURI = (registry, { token }) => {
+ t.equal(registry, npm.flatOptions.registry, 'should set expected registry')
+ t.equal(token, 'token', 'should set expected token')
+ }
+ npm.config.save = type => {
+ t.equal(type, 'user', 'should save to user config')
+ }
await profile.exec(['enable-2fa', 'auth-only'])
t.equal(
- result,
+ result(),
'Two factor authentication mode changed to: auth-only',
'should output success msg'
)
@@ -708,12 +655,6 @@ t.test('enable-2fa', t => {
t.test('from token and set otp, retries on pending and verifies with qrcode', async t => {
t.plan(4)
- flatOptions.otp = '1234'
-
- npm.config.getCredentialsByURI = () => {
- return { token: 'token' }
- }
-
let setCount = 0
const npmProfile = {
async get () {
@@ -775,7 +716,7 @@ t.test('enable-2fa', t => {
async password () {
return 'password1234'
},
- async otp (label) {
+ async otp () {
return '123456'
},
}
@@ -785,26 +726,24 @@ t.test('enable-2fa', t => {
generate: (url, cb) => cb('qrcode'),
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- 'qrcode-terminal': qrcode,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile, result } = await mockProfile(t, {
+ npmProfile,
+ qrcode,
+ readUserInfo,
+ config: { otp: '1234' },
})
- const profile = new Profile(npm)
+
+ // XXX: use mock registry
+ npm.config.getCredentialsByURI = () => {
+ return { token: 'token' }
+ }
await profile.exec(['enable-2fa', 'auth-only'])
- t.matchSnapshot(result, 'should output 2fa enablement success msgs')
+ t.matchSnapshot(result(), 'should output 2fa enablement success msgs')
})
t.test('from token and set otp, retrieves invalid otp', async t => {
- flatOptions.otp = '1234'
-
- npm.config.getCredentialsByURI = () => {
- return { token: 'token' }
- }
-
const npmProfile = {
async get () {
return {
@@ -831,12 +770,15 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
+ config: { otp: '1234' },
})
- const profile = new Profile(npm)
+
+ npm.config.getCredentialsByURI = () => {
+ return { token: 'token' }
+ }
await t.rejects(
profile.exec(['enable-2fa', 'auth-only']),
@@ -846,13 +788,6 @@ t.test('enable-2fa', t => {
})
t.test('from token auth provides --otp config arg', async t => {
- flatOptions.otp = '123456'
- flatOptions.otp = '123456'
-
- npm.config.getCredentialsByURI = reg => {
- return { token: 'token' }
- }
-
const npmProfile = {
async get () {
return userProfile
@@ -874,27 +809,26 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
+ config: { otp: '123456' },
})
- const profile = new Profile(npm)
+
+ npm.config.getCredentialsByURI = reg => {
+ return { token: 'token' }
+ }
await profile.exec(['enable-2fa', 'auth-and-writes'])
t.equal(
- result,
+ result(),
'Two factor authentication mode changed to: auth-and-writes',
'should output success msg'
)
})
t.test('missing tfa from user profile', async t => {
- npm.config.getCredentialsByURI = reg => {
- return { token: 'token' }
- }
-
const npmProfile = {
async get () {
return {
@@ -919,27 +853,25 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
})
- const profile = new Profile(npm)
+
+ npm.config.getCredentialsByURI = reg => {
+ return { token: 'token' }
+ }
await profile.exec(['enable-2fa', 'auth-only'])
t.equal(
- result,
+ result(),
'Two factor authentication mode changed to: auth-only',
'should output success msg'
)
})
t.test('defaults to auth-and-writes permission if no mode specified', async t => {
- npm.config.getCredentialsByURI = reg => {
- return { token: 'token' }
- }
-
const npmProfile = {
async get () {
return {
@@ -964,25 +896,25 @@ t.test('enable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { npm, profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
})
- const profile = new Profile(npm)
+
+ npm.config.getCredentialsByURI = reg => {
+ return { token: 'token' }
+ }
await profile.exec(['enable-2fa'])
t.equal(
- result,
+ result(),
'Two factor authentication mode changed to: auth-and-writes',
'should enable 2fa with auth-and-writes permission'
)
})
-
- t.end()
})
-t.test('disable-2fa', t => {
+t.test('disable-2fa', async t => {
t.test('no tfa enabled', async t => {
const npmProfile = {
async get () {
@@ -993,17 +925,16 @@ t.test('disable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
})
- const profile = new Profile(npm)
await profile.exec(['disable-2fa'])
- t.equal(result, 'Two factor authentication not enabled.', 'should output already disalbed msg')
+ t.equal(result(), 'Two factor authentication not enabled.',
+ 'should output already disalbed msg')
})
- t.test('requests otp', t => {
+ t.test('requests otp', async t => {
const npmProfile = t => ({
async get () {
return userProfile
@@ -1019,14 +950,6 @@ t.test('disable-2fa', t => {
},
'should send the new info for setting in profile'
)
- t.match(
- conf,
- {
- ...npm.flatOptions,
- otp: '1234',
- },
- 'should forward flatOptions config'
- )
},
})
@@ -1046,54 +969,52 @@ t.test('disable-2fa', t => {
})
t.test('default output', async t => {
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
- '../../../lib/utils/read-user-info.js': readUserInfo(t),
+ t.plan(4)
+
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: npmProfile(t),
+ readUserInfo: readUserInfo(t),
})
- const profile = new Profile(npm)
await profile.exec(['disable-2fa'])
- t.equal(result, 'Two factor authentication disabled.', 'should output already disabled msg')
+ t.equal(result(), 'Two factor authentication disabled.', 'should output already disabled msg')
})
t.test('--json', async t => {
- config.json = true
+ t.plan(4)
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
- '../../../lib/utils/read-user-info.js': readUserInfo(t),
+ const config = { json: true }
+
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: npmProfile(t),
+ readUserInfo: readUserInfo(t),
+ config,
})
- const profile = new Profile(npm)
await profile.exec(['disable-2fa'])
- t.same(JSON.parse(result), { tfa: false }, 'should output json already disabled msg')
+ t.same(JSON.parse(result()), { tfa: false }, 'should output json already disabled msg')
})
t.test('--parseable', async t => {
- config.parseable = true
+ t.plan(4)
+
+ const config = { parseable: true }
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile(t),
- '../../../lib/utils/read-user-info.js': readUserInfo(t),
+ const { profile, result } = await mockProfile(t, {
+ npmProfile: npmProfile(t),
+ readUserInfo: readUserInfo(t),
+ config,
})
- const profile = new Profile(npm)
await profile.exec(['disable-2fa'])
- t.equal(result, 'tfa\tfalse', 'should output parseable already disabled msg')
+ t.equal(result(), 'tfa\tfalse', 'should output parseable already disabled msg')
})
-
- t.end()
})
t.test('--otp config already set', async t => {
- t.plan(3)
-
- flatOptions.otp = '123456'
+ t.plan(2)
const npmProfile = {
async get () {
@@ -1110,14 +1031,6 @@ t.test('disable-2fa', t => {
},
'should send the new info for setting in profile'
)
- t.match(
- conf,
- {
- ...npm.flatOptions,
- otp: '123456',
- },
- 'should forward flatOptions config'
- )
},
}
@@ -1130,22 +1043,21 @@ t.test('disable-2fa', t => {
},
}
- const Profile = t.mock('../../../lib/commands/profile.js', {
- ...mocks,
- 'npm-profile': npmProfile,
- '../../../lib/utils/read-user-info.js': readUserInfo,
+ const { profile, result } = await mockProfile(t, {
+ npmProfile,
+ readUserInfo,
+ config: { otp: '123456' },
})
- const profile = new Profile(npm)
await profile.exec(['disable-2fa'])
- t.equal(result, 'Two factor authentication disabled.', 'should output already disalbed msg')
+ t.equal(result(), 'Two factor authentication disabled.', 'should output already disalbed msg')
})
-
- t.end()
})
t.test('unknown subcommand', async t => {
+ const { profile } = await mockProfile(t)
+
await t.rejects(
profile.exec(['asfd']),
/Unknown profile command: asfd/,
@@ -1153,55 +1065,47 @@ t.test('unknown subcommand', async t => {
)
})
-t.test('completion', t => {
- const testComp = async ({ t, argv, expect, title }) => {
+t.test('completion', async t => {
+ const testComp = async (t, { argv, expect, title } = {}) => {
+ const { npm } = await mockProfile(t)
+ const profile = await npm.cmd('profile')
t.resolveMatch(profile.completion({ conf: { argv: { remain: argv } } }), expect, title)
}
t.test('npm profile autocomplete', async t => {
- await testComp({
- t,
+ await testComp(t, {
argv: ['npm', 'profile'],
expect: ['enable-2fa', 'disable-2fa', 'get', 'set'],
title: 'should auto complete with subcommands',
})
-
- t.end()
})
t.test('npm profile enable autocomplete', async t => {
- await testComp({
- t,
+ await testComp(t, {
argv: ['npm', 'profile', 'enable-2fa'],
expect: ['auth-and-writes', 'auth-only'],
title: 'should auto complete with auth types',
})
-
- t.end()
})
t.test('npm profile <subcmd> no autocomplete', async t => {
const noAutocompleteCmds = ['disable-2fa', 'disable-tfa', 'get', 'set']
for (const subcmd of noAutocompleteCmds) {
- await testComp({
- t,
+ await t.test(subcmd, t => testComp(t, {
argv: ['npm', 'profile', subcmd],
expect: [],
title: `${subcmd} should have no autocomplete`,
- })
+ }))
}
-
- t.end()
})
t.test('npm profile unknown subcommand autocomplete', async t => {
+ const { npm } = await mockProfile(t)
+ const profile = await npm.cmd('profile')
t.rejects(
profile.completion({ conf: { argv: { remain: ['npm', 'profile', 'asdf'] } } }),
{ message: 'asdf not recognized' },
'should throw unknown cmd error'
)
- t.end()
})
-
- t.end()
})
diff --git a/deps/npm/test/lib/commands/prune.js b/deps/npm/test/lib/commands/prune.js
index a7f56547b1..81245bcfca 100644
--- a/deps/npm/test/lib/commands/prune.js
+++ b/deps/npm/test/lib/commands/prune.js
@@ -13,7 +13,7 @@ t.test('should prune using Arborist', async (t) => {
t.ok(true, 'prune is called')
}
},
- '../../lib/utils/reify-finish.js': (arb) => {
+ '{LIB}/utils/reify-finish.js': (arb) => {
t.ok(arb, 'gets arborist tree')
},
},
diff --git a/deps/npm/test/lib/commands/publish.js b/deps/npm/test/lib/commands/publish.js
index 496c02394e..3969606613 100644
--- a/deps/npm/test/lib/commands/publish.js
+++ b/deps/npm/test/lib/commands/publish.js
@@ -44,9 +44,6 @@ t.test('respects publishConfig.registry, runs appropriate scripts', async t => {
publishConfig: { registry: alternateRegistry },
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -103,9 +100,6 @@ t.test('re-loads publishConfig.registry if added during script process', async t
publishConfig: { registry: alternateRegistry },
}),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -150,9 +144,6 @@ t.test('json', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -174,9 +165,6 @@ t.test('dry-run', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await npm.exec('publish', [])
t.equal(joinedOutput(), `+ ${pkg}@1.0.0`)
@@ -184,10 +172,8 @@ t.test('dry-run', async t => {
})
t.test('shows usage with wrong set of arguments', async t => {
- t.plan(1)
- const Publish = t.mock('../../../lib/commands/publish.js')
- const publish = new Publish({ config: { validate: () => {} } })
-
+ const { npm } = await loadMockNpm(t)
+ const publish = await npm.cmd('publish')
await t.rejects(publish.exec(['a', 'b', 'c']), publish.usage)
})
@@ -199,9 +185,6 @@ t.test('throws when invalid tag', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await t.rejects(
npm.exec('publish', []),
@@ -247,9 +230,6 @@ t.test('no auth default registry', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await t.rejects(
npm.exec('publish', []),
@@ -268,9 +248,6 @@ t.test('no auth dry-run', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await npm.exec('publish', [])
t.matchSnapshot(joinedOutput())
@@ -286,9 +263,6 @@ t.test('no auth for configured registry', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await t.rejects(
npm.exec('publish', []),
@@ -302,7 +276,8 @@ t.test('no auth for configured registry', async t => {
t.test('no auth for scope configured registry', async t => {
const { npm } = await loadMockNpm(t, {
config: {
- '@npm:registry': alternateRegistry,
+ scope: '@npm',
+ registry: alternateRegistry,
...auth,
},
prefixDir: {
@@ -311,9 +286,6 @@ t.test('no auth for scope configured registry', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await t.rejects(
npm.exec('publish', []),
@@ -328,7 +300,8 @@ t.test('has token auth for scope configured registry', async t => {
const spec = npa('@npm/test-package')
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
- '@npm:registry': alternateRegistry,
+ scope: '@npm',
+ registry: alternateRegistry,
[`${alternateRegistry.slice(6)}/:_authToken`]: 'test-scope-token',
},
prefixDir: {
@@ -337,9 +310,6 @@ t.test('has token auth for scope configured registry', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -357,7 +327,8 @@ t.test('has mTLS auth for scope configured registry', async t => {
const spec = npa('@npm/test-package')
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
- '@npm:registry': alternateRegistry,
+ scope: '@npm',
+ registry: alternateRegistry,
[`${alternateRegistry.slice(6)}/:certfile`]: '/some.cert',
[`${alternateRegistry.slice(6)}/:keyfile`]: '/some.key',
},
@@ -367,9 +338,6 @@ t.test('has mTLS auth for scope configured registry', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -425,9 +393,6 @@ t.test('workspaces', t => {
...auth,
workspaces: true,
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
const registry = new MockRegistry({
@@ -457,9 +422,6 @@ t.test('workspaces', t => {
color: 'always',
workspaces: true,
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
const registry = new MockRegistry({
@@ -488,9 +450,6 @@ t.test('workspaces', t => {
...auth,
workspace: ['workspace-a'],
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
const registry = new MockRegistry({
@@ -512,9 +471,6 @@ t.test('workspaces', t => {
...auth,
workspace: ['workspace-a'],
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
const registry = new MockRegistry({
@@ -535,9 +491,6 @@ t.test('workspaces', t => {
...auth,
workspace: ['workspace-x'],
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
await t.rejects(
@@ -553,9 +506,6 @@ t.test('workspaces', t => {
workspaces: true,
json: true,
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
prefixDir: dir,
})
const registry = new MockRegistry({
@@ -596,9 +546,6 @@ t.test('ignore-scripts', async t => {
},
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -638,9 +585,6 @@ t.test('_auth config default registry', async t => {
prefixDir: {
'package.json': JSON.stringify(pkgJson),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -665,9 +609,6 @@ t.test('bare _auth and registry config', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -682,7 +623,8 @@ t.test('bare _auth and registry config', async t => {
t.test('bare _auth config scoped registry', async t => {
const { npm } = await loadMockNpm(t, {
config: {
- '@npm:registry': alternateRegistry,
+ scope: '@npm',
+ registry: alternateRegistry,
_auth: basic,
},
prefixDir: {
@@ -691,9 +633,6 @@ t.test('bare _auth config scoped registry', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
await t.rejects(
npm.exec('publish', []),
@@ -705,7 +644,8 @@ t.test('scoped _auth config scoped registry', async t => {
const spec = npa('@npm/test-package')
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
- '@npm:registry': alternateRegistry,
+ scope: '@npm',
+ registry: alternateRegistry,
[`${alternateRegistry.slice(6)}/:_auth`]: basic,
},
prefixDir: {
@@ -714,9 +654,6 @@ t.test('scoped _auth config scoped registry', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -741,9 +678,6 @@ t.test('restricted access', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
@@ -772,9 +706,6 @@ t.test('public access', async t => {
version: '1.0.0',
}, null, 2),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => prefix,
- }),
})
const registry = new MockRegistry({
tap: t,
diff --git a/deps/npm/test/lib/commands/query.js b/deps/npm/test/lib/commands/query.js
index fb5b4843c3..2b9a5b4976 100644
--- a/deps/npm/test/lib/commands/query.js
+++ b/deps/npm/test/lib/commands/query.js
@@ -1,15 +1,8 @@
const t = require('tap')
const { load: loadMockNpm } = require('../../fixtures/mock-npm')
+const { cleanCwd } = require('../../fixtures/clean-snapshot.js')
-t.cleanSnapshot = (str) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(str)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
- // normalize between windows and posix
- .replace(new RegExp('lib/node_modules', 'g'), 'node_modules')
-}
+t.cleanSnapshot = (str) => cleanCwd(str)
t.test('simple query', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
@@ -71,7 +64,7 @@ t.test('recursive tree', async t => {
t.test('workspace query', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
- workspaces: ['c'],
+ workspace: ['c'],
},
prefixDir: {
node_modules: {
@@ -101,7 +94,7 @@ t.test('workspace query', async t => {
}),
},
})
- await npm.exec('query', [':scope'], ['c'])
+ await npm.exec('query', [':scope'])
t.matchSnapshot(joinedOutput(), 'should return workspace object')
})
@@ -109,7 +102,7 @@ t.test('include-workspace-root', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
'include-workspace-root': true,
- workspaces: ['c'],
+ workspace: ['c'],
},
prefixDir: {
node_modules: {
@@ -139,7 +132,7 @@ t.test('include-workspace-root', async t => {
}),
},
})
- await npm.exec('query', [':scope'], ['c'])
+ await npm.exec('query', [':scope'])
t.matchSnapshot(joinedOutput(), 'should return workspace object and root object')
})
t.test('linked node', async t => {
@@ -171,8 +164,6 @@ t.test('global', async t => {
config: {
global: true,
},
- // This is a global dir that works in both windows and non-windows, that's
- // why it has two node_modules folders
globalPrefixDir: {
node_modules: {
lorem: {
@@ -182,16 +173,7 @@ t.test('global', async t => {
}),
},
},
- lib: {
- node_modules: {
- lorem: {
- 'package.json': JSON.stringify({
- name: 'lorem',
- version: '2.0.0',
- }),
- },
- },
- },
+
},
})
await npm.exec('query', ['[name=lorem]'])
diff --git a/deps/npm/test/lib/commands/rebuild.js b/deps/npm/test/lib/commands/rebuild.js
index 3bfd3707f5..bda161772d 100644
--- a/deps/npm/test/lib/commands/rebuild.js
+++ b/deps/npm/test/lib/commands/rebuild.js
@@ -1,53 +1,32 @@
const t = require('tap')
const fs = require('fs')
const { resolve } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-let result = ''
-
-const config = {
- global: false,
-}
-const npm = mockNpm({
- globalDir: '',
- config,
- prefix: '',
- output: (...msg) => {
- result += msg.join('\n')
- },
-})
-const Rebuild = require('../../../lib/commands/rebuild.js')
-const rebuild = new Rebuild(npm)
-
-t.afterEach(() => {
- npm.prefix = ''
- config.global = false
- npm.globalDir = ''
- result = ''
-})
+const setupMockNpm = require('../../fixtures/mock-npm')
t.test('no args', async t => {
- const path = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- bin: 'cwd',
- scripts: {
- preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
- },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- bin: 'cwd',
- scripts: {
- preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
- },
- }),
+ const { npm, joinedOutput, prefix: path } = await setupMockNpm(t, {
+ prefixDir: {
+ node_modules: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'cwd',
+ scripts: {
+ preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
+ },
+ }),
+ },
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ bin: 'cwd',
+ scripts: {
+ preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
+ },
+ }),
+ },
},
},
})
@@ -61,9 +40,7 @@ t.test('no args', async t => {
t.throws(() => fs.statSync(aBinFile))
t.throws(() => fs.statSync(bBinFile))
- npm.prefix = path
-
- await rebuild.exec([])
+ await npm.exec('rebuild', [])
t.ok(() => fs.statSync(aBuildFile))
t.ok(() => fs.statSync(bBuildFile))
@@ -71,136 +48,141 @@ t.test('no args', async t => {
t.ok(() => fs.statSync(bBinFile))
t.equal(
- result,
+ joinedOutput(),
'rebuilt dependencies successfully',
'should output success msg'
)
})
t.test('filter by pkg name', async t => {
- const path = t.testdir({
- node_modules: {
- a: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- bin: 'index.js',
- }),
- },
- b: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- bin: 'index.js',
- }),
+ const { npm, prefix: path } = await setupMockNpm(t, {
+ prefixDir: {
+ node_modules: {
+ a: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
+ b: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
},
},
})
- npm.prefix = path
-
const aBinFile = resolve(path, 'node_modules/.bin/a')
const bBinFile = resolve(path, 'node_modules/.bin/b')
t.throws(() => fs.statSync(aBinFile))
t.throws(() => fs.statSync(bBinFile))
- await rebuild.exec(['b'])
+ await npm.exec('rebuild', ['b'])
t.throws(() => fs.statSync(aBinFile), 'should not link a bin')
t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin')
})
t.test('filter by pkg@<range>', async t => {
- const path = t.testdir({
- node_modules: {
- a: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- bin: 'index.js',
- }),
- node_modules: {
- b: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'b',
- version: '2.0.0',
- bin: 'index.js',
- }),
+ const { npm, prefix: path } = await setupMockNpm(t, {
+ prefixDir: {
+ node_modules: {
+ a: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ node_modules: {
+ b: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '2.0.0',
+ bin: 'index.js',
+ }),
+ },
},
},
- },
- b: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- bin: 'index.js',
- }),
+ b: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
},
},
})
- npm.prefix = path
-
const bBinFile = resolve(path, 'node_modules/.bin/b')
const nestedBinFile = resolve(path, 'node_modules/a/node_modules/.bin/b')
- await rebuild.exec(['b@2'])
+ await npm.exec('rebuild', ['b@2'])
t.throws(() => fs.statSync(bBinFile), 'should not link b bin')
t.ok(() => fs.statSync(nestedBinFile), 'should link filtered pkg bin')
})
t.test('filter by directory', async t => {
- const path = t.testdir({
- node_modules: {
- a: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- bin: 'index.js',
- }),
- },
- b: {
- 'index.js': '',
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- bin: 'index.js',
- }),
+ const { npm, prefix: path } = await setupMockNpm(t, {
+ prefixDir: {
+ node_modules: {
+ a: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
+ b: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
},
},
})
- npm.prefix = path
-
const aBinFile = resolve(path, 'node_modules/.bin/a')
const bBinFile = resolve(path, 'node_modules/.bin/b')
t.throws(() => fs.statSync(aBinFile))
t.throws(() => fs.statSync(bBinFile))
- await rebuild.exec(['file:node_modules/b'])
+ await npm.exec('rebuild', ['file:node_modules/b'])
t.throws(() => fs.statSync(aBinFile), 'should not link a bin')
t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin')
})
t.test('filter must be a semver version/range, or directory', async t => {
+ const { npm } = await setupMockNpm(t)
+
await t.rejects(
- rebuild.exec(['git+ssh://github.com/npm/arborist']),
+ npm.exec('rebuild', ['git+ssh://github.com/npm/arborist']),
/`npm rebuild` only supports SemVer version\/range specifiers/,
'should throw type error'
)
})
t.test('global prefix', async t => {
- const globalPath = t.testdir({
- lib: {
+ const { npm, globalPrefix, joinedOutput } = await setupMockNpm(t, {
+ config: {
+ global: true,
+ },
+ globalPrefixDir: {
node_modules: {
a: {
'index.js': '',
@@ -214,14 +196,11 @@ t.test('global prefix', async t => {
},
})
- config.global = true
- npm.globalDir = resolve(globalPath, 'lib', 'node_modules')
-
- await rebuild.exec([])
- t.ok(() => fs.statSync(resolve(globalPath, 'lib/node_modules/.bin/a')))
+ await npm.exec('rebuild', [])
+ t.ok(() => fs.statSync(resolve(globalPrefix, 'lib/node_modules/.bin/a')))
t.equal(
- result,
+ joinedOutput(),
'rebuilt dependencies successfully',
'should output success msg'
)
diff --git a/deps/npm/test/lib/commands/repo.js b/deps/npm/test/lib/commands/repo.js
index 86f1b8e274..114cdf9195 100644
--- a/deps/npm/test/lib/commands/repo.js
+++ b/deps/npm/test/lib/commands/repo.js
@@ -1,5 +1,5 @@
const t = require('tap')
-const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js')
+const mockNpm = require('../../fixtures/mock-npm.js')
const { sep } = require('path')
const fixture = {
@@ -180,24 +180,30 @@ const workspaceFixture = {
}),
}
-// keep a tally of which urls got opened
-let opened = {}
-const openUrl = async (npm, url, errMsg) => {
- opened[url] = opened[url] || 0
- opened[url]++
-}
-t.afterEach(() => opened = {})
+const loadMockNpm = async (t, prefixDir, config = {}) => {
+ // keep a tally of which urls got opened
+ const opened = {}
-const loadMockNpm = async (t, prefixDir) => {
- const res = await _loadMockNpm(t, {
- mocks: { '../../lib/utils/open-url.js': openUrl },
+ const mock = await mockNpm(t, {
+ command: 'repo',
+ mocks: {
+ '{LIB}/utils/open-url.js': async (_, url) => {
+ opened[url] = opened[url] || 0
+ opened[url]++
+ },
+ },
+ config,
prefixDir,
})
- return res
+
+ return {
+ ...mock,
+ opened,
+ }
}
t.test('open repo urls', async t => {
- const { npm } = await loadMockNpm(t, fixture)
+ const { repo, opened } = await loadMockNpm(t, fixture)
const expect = {
hostedgit: 'https://github.com/foo/hostedgit',
hostedgitat: 'https://github.com/foo/hostedgitat',
@@ -224,22 +230,14 @@ t.test('open repo urls', async t => {
directory: 'https://github.com/foo/test-repo-with-directory/tree/HEAD/some/directory',
'.': 'https://example.com/thispkg',
}
- const keys = Object.keys(expect)
- t.plan(keys.length)
- keys.forEach(pkg => {
- t.test(pkg, async t => {
- await npm.exec('repo', [['.', pkg].join(sep)])
- const url = expect[pkg]
- t.match({
- [url]: 1,
- }, opened, `opened ${url}`, { opened })
- t.end()
- })
- })
+ for (const [pkg, url] of Object.entries(expect)) {
+ await repo.exec([['.', pkg].join(sep)])
+ t.equal(opened[url], 1, `opened ${url}`)
+ }
})
t.test('fail if cannot figure out repo url', async t => {
- const { npm } = await loadMockNpm(t, fixture)
+ const { repo } = await loadMockNpm(t, fixture)
const cases = [
'norepo',
@@ -248,37 +246,29 @@ t.test('fail if cannot figure out repo url', async t => {
'unhostedgitatobj',
]
- t.plan(cases.length)
-
- cases.forEach(pkg => {
- t.test(pkg, async t => {
- t.rejects(
- npm.exec('repo', [['.', pkg].join(sep)]),
- { pkgid: pkg }
- )
- })
- })
+ for (const pkg of cases) {
+ await t.rejects(
+ repo.exec([['.', pkg].join(sep)]),
+ { pkgid: pkg }
+ )
+ }
})
t.test('open default package if none specified', async t => {
- const { npm } = await loadMockNpm(t, fixture)
- await npm.exec('repo', [])
+ const { repo, opened } = await loadMockNpm(t, fixture)
+ await repo.exec([])
t.equal(opened['https://example.com/thispkg'], 1, 'opened expected url', { opened })
})
t.test('workspaces', async t => {
- const { npm } = await loadMockNpm(t, workspaceFixture)
-
- t.afterEach(() => {
- npm.config.set('workspaces', null)
- npm.config.set('workspace', [])
- npm.config.set('include-workspace-root', false)
- })
+ const mockWorkspaces = (t, config) => loadMockNpm(t, workspaceFixture, config)
t.test('include workspace root', async (t) => {
- npm.config.set('workspaces', true)
- npm.config.set('include-workspace-root', true)
- await npm.exec('repo', [])
+ const { opened, repo } = await mockWorkspaces(t, {
+ workspaces: true,
+ 'include-workspace-root': true,
+ })
+ await repo.exec([])
t.match({
'https://github.com/npm/workspaces-test': 1,
'https://repo.workspace-a/': 1, // Gets translated to https!
@@ -287,8 +277,10 @@ t.test('workspaces', async t => {
})
t.test('all workspaces', async (t) => {
- npm.config.set('workspaces', true)
- await npm.exec('repo', [])
+ const { opened, repo } = await mockWorkspaces(t, {
+ workspaces: true,
+ })
+ await repo.exec([])
t.match({
'https://repo.workspace-a/': 1, // Gets translated to https!
'https://github.com/npm/workspace-b': 1,
@@ -296,25 +288,31 @@ t.test('workspaces', async t => {
})
t.test('one workspace', async (t) => {
- npm.config.set('workspace', ['workspace-a'])
- await npm.exec('repo', [])
+ const { opened, repo } = await mockWorkspaces(t, {
+ workspace: ['workspace-a'],
+ })
+ await repo.exec([])
t.match({
'https://repo.workspace-a/': 1,
}, opened, 'opened one requested repo urls')
})
t.test('invalid workspace', async (t) => {
- npm.config.set('workspace', ['workspace-x'])
+ const { opened, repo } = await mockWorkspaces(t, {
+ workspace: ['workspace-x'],
+ })
await t.rejects(
- npm.exec('repo', []),
+ repo.exec([]),
/workspace-x/
)
t.match({}, opened, 'opened no repo urls')
})
t.test('package arg and workspace', async (t) => {
- npm.config.set('workspace', ['workspace-a'])
- await npm.exec('repo', ['.'])
+ const { opened, repo } = await mockWorkspaces(t, {
+ workspace: ['workspace-x'],
+ })
+ await repo.exec(['.'])
t.match({
'https://github.com/npm/workspaces-test': 1,
}, opened, 'opened url for package arg, not workspace')
diff --git a/deps/npm/test/lib/commands/restart.js b/deps/npm/test/lib/commands/restart.js
index f9745acdd1..b8b760675f 100644
--- a/deps/npm/test/lib/commands/restart.js
+++ b/deps/npm/test/lib/commands/restart.js
@@ -19,11 +19,11 @@ t.test('should run restart script from package.json', async t => {
},
config: {
loglevel: 'silent',
- scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
+ 'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
},
})
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'node ./test-restart.js foo']
: ['-c', 'node ./test-restart.js foo']
diff --git a/deps/npm/test/lib/commands/run-script.js b/deps/npm/test/lib/commands/run-script.js
index 8aafebcaf8..a265db3cc0 100644
--- a/deps/npm/test/lib/commands/run-script.js
+++ b/deps/npm/test/lib/commands/run-script.js
@@ -1,125 +1,84 @@
const t = require('tap')
const { resolve } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const normalizePath = p => p.replace(/\\+/g, '/').replace(/\r\n/g, '\n')
-
-const cleanOutput = str => normalizePath(str).replace(normalizePath(process.cwd()), '{CWD}')
-
-const RUN_SCRIPTS = []
-const flatOptions = {
- scriptShell: undefined,
-}
-const defaultLoglevel = 'info'
-const config = {
- json: false,
- parseable: false,
- 'if-present': false,
- loglevel: defaultLoglevel,
-}
-
-const npm = mockNpm({
- localPrefix: __dirname,
- flatOptions,
- config,
- cmd: c => {
- return { description: `test ${c} description` }
- },
- output: (...msg) => output.push(msg),
-})
-
-const setLoglevel = (t, level) => {
- npm.config.set('loglevel', level)
- t.teardown(() => {
- npm.config.set('loglevel', defaultLoglevel)
+const realRunScript = require('@npmcli/run-script')
+const mockNpm = require('../../fixtures/mock-npm')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
+const mockRs = async (t, { windows = false, runScript, ...opts } = {}) => {
+ let RUN_SCRIPTS = []
+
+ t.afterEach(() => RUN_SCRIPTS = [])
+
+ const mock = await mockNpm(t, {
+ ...opts,
+ mocks: {
+ '@npmcli/run-script': Object.assign(
+ async rs => {
+ if (runScript) {
+ await runScript(rs)
+ }
+ RUN_SCRIPTS.push(rs)
+ },
+ realRunScript
+ ),
+ '{LIB}/utils/is-windows.js': { isWindowsShell: windows },
+ },
})
-}
-
-const output = []
-
-const log = {
- error: () => null,
-}
-
-t.afterEach(() => {
- npm.color = false
- log.error = () => null
- output.length = 0
- RUN_SCRIPTS.length = 0
- config['if-present'] = false
- config.json = false
- config.parseable = false
-})
-const getRS = windows => {
- const RunScript = t.mock('../../../lib/commands/run-script.js', {
- '@npmcli/run-script': Object.assign(
- async opts => {
- RUN_SCRIPTS.push(opts)
- },
- {
- isServerPackage: require('@npmcli/run-script').isServerPackage,
- }
- ),
- 'proc-log': log,
- '../../../lib/utils/is-windows.js': { isWindowsShell: windows },
- })
- return new RunScript(npm)
+ return {
+ ...mock,
+ RUN_SCRIPTS: () => RUN_SCRIPTS,
+ runScript: { exec: (args) => mock.npm.exec('run-script', args) },
+ cleanLogs: () => mock.logs.error.flat().map(v => v.toString()).map(cleanCwd),
+ }
}
-const runScript = getRS(false)
-const runScriptWin = getRS(true)
+t.test('completion', async t => {
+ const completion = async (t, remain, pkg) => {
+ const { npm } = await mockRs(t,
+ pkg ? { prefixDir: { 'package.json': JSON.stringify(pkg) } } : {}
+ )
+ const cmd = await npm.cmd('run-script')
+ return cmd.completion({ conf: { argv: { remain } } })
+ }
-const { writeFileSync } = require('fs')
-t.test('completion', t => {
- const dir = t.testdir()
- npm.localPrefix = dir
t.test('already have a script name', async t => {
- const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run', 'x'] } } })
+ const res = await completion(t, ['npm', 'run', 'x'])
t.equal(res, undefined)
- t.end()
})
t.test('no package.json', async t => {
- const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run'] } } })
+ const res = await completion(t, ['npm', 'run'])
t.strictSame(res, [])
- t.end()
})
t.test('has package.json, no scripts', async t => {
- writeFileSync(`${dir}/package.json`, JSON.stringify({}))
- const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run'] } } })
+ const res = await completion(t, ['npm', 'run'], {})
t.strictSame(res, [])
- t.end()
})
t.test('has package.json, with scripts', async t => {
- writeFileSync(
- `${dir}/package.json`,
- JSON.stringify({
- scripts: { hello: 'echo hello', world: 'echo world' },
- })
- )
- const res = await runScript.completion({ conf: { argv: { remain: ['npm', 'run'] } } })
+ const res = await completion(t, ['npm', 'run'], {
+ scripts: { hello: 'echo hello', world: 'echo world' },
+ })
t.strictSame(res, ['hello', 'world'])
- t.end()
})
- t.end()
})
t.test('fail if no package.json', async t => {
- t.plan(2)
- npm.localPrefix = t.testdir()
+ const { runScript } = await mockRs(t)
await t.rejects(runScript.exec([]), { code: 'ENOENT' })
await t.rejects(runScript.exec(['test']), { code: 'ENOENT' })
})
-t.test('default env, start, and restart scripts', t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({ name: 'x', version: '1.2.3' }),
- 'server.js': 'console.log("hello, world")',
+t.test('default env, start, and restart scripts', async t => {
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'x', version: '1.2.3' }),
+ 'server.js': 'console.log("hello, world")',
+ },
})
t.test('start', async t => {
await runScript.exec(['start'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
path: npm.localPrefix,
args: [],
@@ -133,7 +92,7 @@ t.test('default env, start, and restart scripts', t => {
t.test('env', async t => {
await runScript.exec(['env'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
path: npm.localPrefix,
args: [],
@@ -152,31 +111,10 @@ t.test('default env, start, and restart scripts', t => {
])
})
- t.test('windows env', async t => {
- await runScriptWin.exec(['env'])
- t.match(RUN_SCRIPTS, [
- {
- path: npm.localPrefix,
- args: [],
- scriptShell: undefined,
- stdio: 'inherit',
- pkg: {
- name: 'x',
- version: '1.2.3',
- _id: 'x@1.2.3',
- scripts: {
- env: 'SET',
- },
- },
- event: 'env',
- },
- ])
- })
-
t.test('restart', async t => {
await runScript.exec(['restart'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
path: npm.localPrefix,
args: [],
@@ -194,23 +132,52 @@ t.test('default env, start, and restart scripts', t => {
},
])
})
- t.end()
})
-t.test('non-default env script', t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- env: 'hello',
+t.test('default windows env', async t => {
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ windows: true,
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: 'x', version: '1.2.3' }),
+ 'server.js': 'console.log("hello, world")',
+ },
+ })
+ await runScript.exec(['env'])
+ t.match(RUN_SCRIPTS(), [
+ {
+ path: npm.localPrefix,
+ args: [],
+ scriptShell: undefined,
+ stdio: 'inherit',
+ pkg: {
+ name: 'x',
+ version: '1.2.3',
+ _id: 'x@1.2.3',
+ scripts: {
+ env: 'SET',
+ },
},
- }),
+ event: 'env',
+ },
+ ])
+})
+
+t.test('non-default env script', async t => {
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ env: 'hello',
+ },
+ }),
+ },
})
t.test('env', async t => {
await runScript.exec(['env'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
path: npm.localPrefix,
args: [],
@@ -228,71 +195,98 @@ t.test('non-default env script', t => {
},
])
})
+})
- t.test('env windows', async t => {
- await runScriptWin.exec(['env'])
- t.match(RUN_SCRIPTS, [
- {
- path: npm.localPrefix,
- args: [],
- scriptShell: undefined,
- stdio: 'inherit',
- pkg: {
- name: 'x',
- version: '1.2.3',
- _id: 'x@1.2.3',
- scripts: {
- env: 'hello',
- },
+t.test('non-default env script windows', async t => {
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ windows: true,
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ env: 'hello',
},
- event: 'env',
- },
- ])
+ }),
+ },
})
- t.end()
+
+ await runScript.exec(['env'])
+
+ t.match(RUN_SCRIPTS(), [
+ {
+ path: npm.localPrefix,
+ args: [],
+ scriptShell: undefined,
+ stdio: 'inherit',
+ pkg: {
+ name: 'x',
+ version: '1.2.3',
+ _id: 'x@1.2.3',
+ scripts: {
+ env: 'hello',
+ },
+ },
+ event: 'env',
+ },
+ ])
})
-t.test('try to run missing script', t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- scripts: { hello: 'world' },
- bin: { goodnight: 'moon' },
- }),
- })
- t.test('no suggestions', async t => {
- await t.rejects(runScript.exec(['notevenclose']), 'Missing script: "notevenclose"')
- })
- t.test('script suggestions', async t => {
- await t.rejects(runScript.exec(['helo']), /Missing script: "helo"/)
- await t.rejects(runScript.exec(['helo']), /npm run hello/)
- })
- t.test('bin suggestions', async t => {
- await t.rejects(runScript.exec(['goodneght']), /Missing script: "goodneght"/)
- await t.rejects(runScript.exec(['goodneght']), /npm exec goodnight/)
+t.test('try to run missing script', async t => {
+ t.test('errors', async t => {
+ const { runScript } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ scripts: { hello: 'world' },
+ bin: { goodnight: 'moon' },
+ }),
+ },
+ })
+ t.test('no suggestions', async t => {
+ await t.rejects(runScript.exec(['notevenclose']), 'Missing script: "notevenclose"')
+ })
+ t.test('script suggestions', async t => {
+ await t.rejects(runScript.exec(['helo']), /Missing script: "helo"/)
+ await t.rejects(runScript.exec(['helo']), /npm run hello/)
+ })
+ t.test('bin suggestions', async t => {
+ await t.rejects(runScript.exec(['goodneght']), /Missing script: "goodneght"/)
+ await t.rejects(runScript.exec(['goodneght']), /npm exec goodnight/)
+ })
})
+
t.test('with --if-present', async t => {
- config['if-present'] = true
+ const { runScript, RUN_SCRIPTS } = await mockRs(t, {
+ config: { 'if-present': true },
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ scripts: { hello: 'world' },
+ bin: { goodnight: 'moon' },
+ }),
+ },
+ })
await runScript.exec(['goodbye'])
- t.strictSame(RUN_SCRIPTS, [], 'did not try to run anything')
+ t.strictSame(RUN_SCRIPTS(), [], 'did not try to run anything')
})
- t.end()
})
t.test('run pre/post hooks', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- preenv: 'echo before the env',
- postenv: 'echo after the env',
- },
- }),
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ preenv: 'echo before the env',
+ postenv: 'echo after the env',
+ },
+ }),
+ },
})
await runScript.exec(['env'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{ event: 'preenv' },
{
path: npm.localPrefix,
@@ -314,22 +308,23 @@ t.test('run pre/post hooks', async t => {
})
t.test('skip pre/post hooks when using ignoreScripts', async t => {
- config['ignore-scripts'] = true
-
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- preenv: 'echo before the env',
- postenv: 'echo after the env',
- },
- }),
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ preenv: 'echo before the env',
+ postenv: 'echo after the env',
+ },
+ }),
+ },
+ config: { 'ignore-scripts': true },
})
await runScript.exec(['env'])
- t.same(RUN_SCRIPTS, [
+ t.same(RUN_SCRIPTS(), [
{
path: npm.localPrefix,
args: [],
@@ -349,25 +344,25 @@ t.test('skip pre/post hooks when using ignoreScripts', async t => {
event: 'env',
},
])
- delete config['ignore-scripts']
})
t.test('run silent', async t => {
- setLoglevel(t, 'silent')
-
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: {
- preenv: 'echo before the env',
- postenv: 'echo after the env',
- },
- }),
+ const { npm, runScript, RUN_SCRIPTS } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: {
+ preenv: 'echo before the env',
+ postenv: 'echo after the env',
+ },
+ }),
+ },
+ config: { silent: true },
})
await runScript.exec(['env'])
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
event: 'preenv',
stdio: 'inherit',
@@ -395,7 +390,7 @@ t.test('run silent', async t => {
])
})
-t.test('list scripts', t => {
+t.test('list scripts', async t => {
const scripts = {
test: 'exit 2',
start: 'node server.js',
@@ -403,16 +398,26 @@ t.test('list scripts', t => {
preenv: 'echo before the env',
postenv: 'echo after the env',
}
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts,
- }),
- })
+
+ const mockList = async (t, config = {}) => {
+ const mock = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts,
+ }),
+ },
+ config,
+ })
+
+ await mock.runScript.exec([])
+
+ return mock.outputs
+ }
t.test('no args', async t => {
- await runScript.exec([])
+ const output = await mockList(t)
t.strictSame(
output,
[
@@ -430,20 +435,17 @@ t.test('list scripts', t => {
})
t.test('silent', async t => {
- setLoglevel(t, 'silent')
- await runScript.exec([])
- t.strictSame(output, [])
+ const outputs = await mockList(t, { silent: true })
+ t.strictSame(outputs, [])
})
t.test('warn json', async t => {
- config.json = true
- await runScript.exec([])
- t.strictSame(output, [[JSON.stringify(scripts, 0, 2)]], 'json report')
+ const outputs = await mockList(t, { json: true })
+ t.strictSame(outputs, [[JSON.stringify(scripts, 0, 2)]], 'json report')
})
t.test('parseable', async t => {
- config.parseable = true
- await runScript.exec([])
- t.strictSame(output, [
+ const outputs = await mockList(t, { parseable: true })
+ t.strictSame(outputs, [
['test:exit 2'],
['start:node server.js'],
['stop:node kill-server.js'],
@@ -451,32 +453,35 @@ t.test('list scripts', t => {
['postenv:echo after the env'],
])
})
- t.end()
})
t.test('list scripts when no scripts', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- }),
+ const { runScript, outputs } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ }),
+ },
})
await runScript.exec([])
- t.strictSame(output, [], 'nothing to report')
+ t.strictSame(outputs, [], 'nothing to report')
})
t.test('list scripts, only commands', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: { preversion: 'echo doing the version dance' },
- }),
+ const { runScript, outputs } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: { preversion: 'echo doing the version dance' },
+ }),
+ },
})
await runScript.exec([])
- t.strictSame(output, [
+ t.strictSame(outputs, [
['Lifecycle scripts included in x@1.2.3:'],
[' preversion\n echo doing the version dance'],
[''],
@@ -484,83 +489,104 @@ t.test('list scripts, only commands', async t => {
})
t.test('list scripts, only non-commands', async t => {
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- scripts: { glorp: 'echo doing the glerp glop' },
- }),
+ const { runScript, outputs } = await mockRs(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'x',
+ version: '1.2.3',
+ scripts: { glorp: 'echo doing the glerp glop' },
+ }),
+ },
})
await runScript.exec([])
- t.strictSame(output, [
+ t.strictSame(outputs, [
['Scripts available in x@1.2.3 via `npm run-script`:'],
[' glorp\n echo doing the glerp glop'],
[''],
])
})
-t.test('workspaces', t => {
- npm.localPrefix = t.testdir({
- packages: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- scripts: { glorp: 'echo a doing the glerp glop' },
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '2.0.0',
- scripts: { glorp: 'echo b doing the glerp glop' },
- }),
- },
- c: {
- 'package.json': JSON.stringify({
- name: 'c',
- version: '1.0.0',
- scripts: {
- test: 'exit 0',
- posttest: 'echo posttest',
- lorem: 'echo c lorem',
+t.test('workspaces', async t => {
+ const mockWorkspaces = async (t, {
+ runScript,
+ prefixDir,
+ workspaces = true,
+ exec = [],
+ ...config
+ } = {}) => {
+ const mock = await mockRs(t, {
+ prefixDir: prefixDir || {
+ packages: {
+ a: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ scripts: { glorp: 'echo a doing the glerp glop' },
+ }),
},
- }),
- },
- d: {
- 'package.json': JSON.stringify({
- name: 'd',
- version: '1.0.0',
- scripts: {
- test: 'exit 0',
- posttest: 'echo posttest',
+ b: {
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '2.0.0',
+ scripts: { glorp: 'echo b doing the glerp glop' },
+ }),
},
- }),
- },
- e: {
+ c: {
+ 'package.json': JSON.stringify({
+ name: 'c',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ lorem: 'echo c lorem',
+ },
+ }),
+ },
+ d: {
+ 'package.json': JSON.stringify({
+ name: 'd',
+ version: '1.0.0',
+ scripts: {
+ test: 'exit 0',
+ posttest: 'echo posttest',
+ },
+ }),
+ },
+ e: {
+ 'package.json': JSON.stringify({
+ name: 'e',
+ scripts: { test: 'exit 0', start: 'echo start something' },
+ }),
+ },
+ noscripts: {
+ 'package.json': JSON.stringify({
+ name: 'noscripts',
+ version: '1.0.0',
+ }),
+ },
+ },
'package.json': JSON.stringify({
- name: 'e',
- scripts: { test: 'exit 0', start: 'echo start something' },
+ name: 'x',
+ version: '1.2.3',
+ workspaces: ['packages/*'],
}),
},
- noscripts: {
- 'package.json': JSON.stringify({
- name: 'noscripts',
- version: '1.0.0',
- }),
+ config: {
+ ...Array.isArray(workspaces) ? { workspace: workspaces } : { workspaces },
+ ...config,
},
- },
- 'package.json': JSON.stringify({
- name: 'x',
- version: '1.2.3',
- workspaces: ['packages/*'],
- }),
- })
+ runScript,
+ })
+ if (exec) {
+ await mock.runScript.exec(exec)
+ }
+ return mock
+ }
t.test('list all scripts', async t => {
- await runScript.execWorkspaces([], [])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t)
+ t.strictSame(outputs, [
['Scripts available in a@1.0.0 via `npm run-script`:'],
[' glorp\n echo a doing the glerp glop'],
[''],
@@ -585,8 +611,8 @@ t.test('workspaces', t => {
})
t.test('list regular scripts, filtered by name', async t => {
- await runScript.execWorkspaces([], ['a', 'b'])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { workspaces: ['a', 'b'] })
+ t.strictSame(outputs, [
['Scripts available in a@1.0.0 via `npm run-script`:'],
[' glorp\n echo a doing the glerp glop'],
[''],
@@ -597,8 +623,8 @@ t.test('workspaces', t => {
})
t.test('list regular scripts, filtered by path', async t => {
- await runScript.execWorkspaces([], ['./packages/a'])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages/a'] })
+ t.strictSame(outputs, [
['Scripts available in a@1.0.0 via `npm run-script`:'],
[' glorp\n echo a doing the glerp glop'],
[''],
@@ -606,8 +632,8 @@ t.test('workspaces', t => {
})
t.test('list regular scripts, filtered by parent folder', async t => {
- await runScript.execWorkspaces([], ['./packages'])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { workspaces: ['./packages'] })
+ t.strictSame(outputs, [
['Scripts available in a@1.0.0 via `npm run-script`:'],
[' glorp\n echo a doing the glerp glop'],
[''],
@@ -632,9 +658,8 @@ t.test('workspaces', t => {
})
t.test('list all scripts with colors', async t => {
- npm.color = true
- await runScript.execWorkspaces([], [])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { color: 'always' })
+ t.strictSame(outputs, [
[
/* eslint-disable-next-line max-len */
'\u001b[1mScripts\u001b[22m available in \x1B[32ma@1.0.0\x1B[39m via `\x1B[34mnpm run-script\x1B[39m`:',
@@ -665,9 +690,8 @@ t.test('workspaces', t => {
})
t.test('list all scripts --json', async t => {
- config.json = true
- await runScript.execWorkspaces([], [])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { json: true })
+ t.strictSame(outputs, [
[
'{\n' +
' "a": {\n' +
@@ -696,9 +720,8 @@ t.test('workspaces', t => {
})
t.test('list all scripts --parseable', async t => {
- config.parseable = true
- await runScript.execWorkspaces([], [])
- t.strictSame(output, [
+ const { outputs } = await mockWorkspaces(t, { parseable: true })
+ t.strictSame(outputs, [
['a:glorp:echo a doing the glerp glop'],
['b:glorp:echo b doing the glerp glop'],
['c:test:exit 0'],
@@ -712,15 +735,14 @@ t.test('workspaces', t => {
})
t.test('list no scripts --loglevel=silent', async t => {
- setLoglevel(t, 'silent')
- await runScript.execWorkspaces([], [])
- t.strictSame(output, [])
+ const { outputs } = await mockWorkspaces(t, { silent: true })
+ t.strictSame(outputs, [])
})
t.test('run scripts across all workspaces', async t => {
- await runScript.execWorkspaces(['test'], [])
+ const { npm, RUN_SCRIPTS } = await mockWorkspaces(t, { exec: ['test'] })
- t.match(RUN_SCRIPTS, [
+ t.match(RUN_SCRIPTS(), [
{
path: resolve(npm.localPrefix, 'packages/c'),
pkg: { name: 'c', version: '1.0.0' },
@@ -750,70 +772,65 @@ t.test('workspaces', t => {
})
t.test('missing scripts in all workspaces', async t => {
- const LOG = []
- log.error = err => {
- LOG.push(String(err))
- }
+ const { runScript, RUN_SCRIPTS, cleanLogs } = await mockWorkspaces(t, { exec: null })
+
await t.rejects(
- runScript.execWorkspaces(['missing-script'], []),
+ runScript.exec(['missing-script']),
/Missing script: missing-script/,
'should throw missing script error'
)
- process.exitCode = 0 // clean exit code
-
- t.match(RUN_SCRIPTS, [])
+ t.match(RUN_SCRIPTS(), [])
t.strictSame(
- LOG.map(cleanOutput),
+ cleanLogs(),
[
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: a@1.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/a',
+ ' at location: {CWD}/prefix/packages/a',
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: b@2.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/b',
+ ' at location: {CWD}/prefix/packages/b',
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: c@1.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/c',
+ ' at location: {CWD}/prefix/packages/c',
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: d@1.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/d',
+ ' at location: {CWD}/prefix/packages/d',
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: e',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/e',
+ ' at location: {CWD}/prefix/packages/e',
'Lifecycle script `missing-script` failed with error:',
'Error: Missing script: "missing-script"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: noscripts@1.0.0',
- /* eslint-disable-next-line max-len */
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/noscripts',
+ ' at location: {CWD}/prefix/packages/noscripts',
],
'should log error msgs for each workspace script'
)
})
t.test('missing scripts in some workspaces', async t => {
- const LOG = []
- log.error = err => {
- LOG.push(String(err))
- }
- await runScript.execWorkspaces(['test'], ['a', 'b', 'c', 'd'])
- t.match(RUN_SCRIPTS, [])
+ const { RUN_SCRIPTS, cleanLogs } = await mockWorkspaces(t, {
+ exec: ['test'],
+ workspaces: ['a', 'b', 'c', 'd'],
+ })
+
+ t.match(RUN_SCRIPTS(), [])
t.strictSame(
- LOG.map(cleanOutput),
+ cleanLogs(),
[
'Lifecycle script `test` failed with error:',
'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: a@1.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/a',
+ ' at location: {CWD}/prefix/packages/a',
'Lifecycle script `test` failed with error:',
'Error: Missing script: "test"\n\nTo see a list of scripts, run:\n npm run',
' in workspace: b@2.0.0',
- ' at location: {CWD}/test/lib/commands/tap-testdir-run-script-workspaces/packages/b',
+ ' at location: {CWD}/prefix/packages/b',
],
'should log error msgs for each workspace script'
)
@@ -821,68 +838,76 @@ t.test('workspaces', t => {
t.test('no workspaces when filtering by user args', async t => {
await t.rejects(
- runScript.execWorkspaces([], ['foo', 'bar']),
+ mockWorkspaces(t, { workspaces: ['foo', 'bar'] }),
'No workspaces found:\n --workspace=foo --workspace=bar',
'should throw error msg'
)
})
t.test('no workspaces', async t => {
- const _prevPrefix = npm.localPrefix
- npm.localPrefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'foo',
- version: '1.0.0',
- }),
- })
-
await t.rejects(
- runScript.execWorkspaces([], []),
+ mockWorkspaces(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'foo',
+ version: '1.0.0',
+ }),
+ },
+ }),
/No workspaces found!/,
'should throw error msg'
)
- npm.localPrefix = _prevPrefix
})
t.test('single failed workspace run', async t => {
- const RunScript = t.mock('../../../lib/commands/run-script.js', {
- '@npmcli/run-script': () => {
+ const { cleanLogs } = await mockWorkspaces(t, {
+ runScript: () => {
throw new Error('err')
},
- 'proc-log': log,
- '../../../lib/utils/is-windows.js': { isWindowsShell: false },
+ exec: ['test'],
+ workspaces: ['c'],
})
- const runScript = new RunScript(npm)
- await runScript.execWorkspaces(['test'], ['c'])
- process.exitCode = 0 // clean up exit code
+ t.strictSame(
+ cleanLogs(),
+ [
+ 'Lifecycle script `test` failed with error:',
+ 'Error: err',
+ ' in workspace: c@1.0.0',
+ ' at location: {CWD}/prefix/packages/c',
+ ],
+ 'should log error msgs for each workspace script'
+ )
})
t.test('failed workspace run with succeeded runs', async t => {
- const RunScript = t.mock('../../../lib/commands/run-script.js', {
- '@npmcli/run-script': async opts => {
+ const { cleanLogs, RUN_SCRIPTS, prefix } = await mockWorkspaces(t, {
+ runScript: (opts) => {
if (opts.pkg.name === 'a') {
throw new Error('ERR')
}
-
- RUN_SCRIPTS.push(opts)
},
- 'proc-log': log,
- '../../../lib/utils/is-windows.js': { isWindowsShell: false },
+ exec: ['glorp'],
+ workspaces: ['a', 'b'],
})
- const runScript = new RunScript(npm)
- await runScript.execWorkspaces(['glorp'], ['a', 'b'])
- t.match(RUN_SCRIPTS, [
+ t.strictSame(
+ cleanLogs(),
+ [
+ 'Lifecycle script `glorp` failed with error:',
+ 'Error: ERR',
+ ' in workspace: a@1.0.0',
+ ' at location: {CWD}/prefix/packages/a',
+ ],
+ 'should log error msgs for each workspace script'
+ )
+
+ t.match(RUN_SCRIPTS(), [
{
- path: resolve(npm.localPrefix, 'packages/b'),
+ path: resolve(prefix, 'packages/b'),
pkg: { name: 'b', version: '2.0.0' },
event: 'glorp',
},
])
-
- process.exitCode = 0 // clean up exit code
})
-
- t.end()
})
diff --git a/deps/npm/test/lib/commands/set.js b/deps/npm/test/lib/commands/set.js
index ce59870e2f..69c4dd8705 100644
--- a/deps/npm/test/lib/commands/set.js
+++ b/deps/npm/test/lib/commands/set.js
@@ -1,60 +1,49 @@
const t = require('tap')
-
-// can't run this until npm set can save to project level npmrc
-t.skip('npm set', async t => {
- // XXX: convert to loadMockNpm
- const { real: mockNpm } = require('../../fixtures/mock-npm')
- const { joinedOutput, Npm } = mockNpm(t)
- const npm = new Npm()
- await npm.load()
-
- t.test('no args', async t => {
- t.rejects(npm.exec('set', []), /Usage:/, 'prints usage')
- })
-
- t.test('test-config-item', async t => {
- npm.localPrefix = t.testdir({})
- t.not(
- npm.config.get('test-config-item', 'project'),
- 'test config value',
- 'config is not already new value'
- )
- // This will write to ~/.npmrc!
- // Don't unskip until we can write to project level
- await npm.exec('set', ['test-config-item=test config value'])
- t.equal(joinedOutput(), '', 'outputs nothing')
- t.equal(
- npm.config.get('test-config-item', 'project'),
- 'test config value',
- 'config is set to new value'
- )
- })
+const fs = require('fs/promises')
+const mockNpm = require('../../fixtures/mock-npm')
+const { join } = require('path')
+const { cleanNewlines } = require('../../fixtures/clean-snapshot')
+
+t.test('no args', async t => {
+ const { npm } = await mockNpm(t)
+ t.rejects(npm.exec('set', []), /Usage:/, 'prints usage')
})
-// Everything after this can go away once the above test is unskipped
-
-let configArgs = null
-const npm = {
- exec: async (cmd, args) => {
- if (cmd === 'config') {
- configArgs = args
- }
- },
- config: {
- validate: () => {},
- isDefault: () => {},
- },
-}
-
-const Set = t.mock('../../../lib/commands/set.js')
-const set = new Set(npm)
-
-t.test('npm set - no args', async t => {
- await t.rejects(set.exec([]), set.usage)
-})
-
-t.test('npm set', async t => {
- await set.exec(['email', 'me@me.me'])
+t.test('test-config-item', async t => {
+ const { npm, home, joinedOutput } = await mockNpm(t, {
+ homeDir: {
+ '.npmrc': 'original-config-test=original value',
+ },
+ })
- t.strictSame(configArgs, ['set', 'email', 'me@me.me'], 'passed the correct arguments to config')
+ t.equal(
+ npm.config.get('original-config-test'),
+ 'original value',
+ 'original config is set from npmrc'
+ )
+
+ t.not(
+ npm.config.get('fund'),
+ false,
+ 'config is not already new value'
+ )
+
+ await npm.exec('set', ['fund=true'])
+ t.equal(joinedOutput(), '', 'outputs nothing')
+
+ t.equal(
+ npm.config.get('fund'),
+ true,
+ 'config is set to new value'
+ )
+
+ t.equal(
+ cleanNewlines(await fs.readFile(join(home, '.npmrc'), 'utf-8')),
+ [
+ 'original-config-test=original value',
+ 'fund=true',
+ '',
+ ].join('\n'),
+ 'npmrc is written with new value'
+ )
})
diff --git a/deps/npm/test/lib/commands/stars.js b/deps/npm/test/lib/commands/stars.js
index 44de6ba1fb..124d2d344d 100644
--- a/deps/npm/test/lib/commands/stars.js
+++ b/deps/npm/test/lib/commands/stars.js
@@ -1,34 +1,36 @@
const t = require('tap')
+const realFetch = require('npm-registry-fetch')
+const mockNpm = require('../../fixtures/mock-npm')
-let result = ''
+const noop = () => {}
-const noop = () => null
-const npm = {
- config: { get () {}, validate: () => {} },
- flatOptions: {},
- output: (...msg) => {
- result = [result, ...msg].join('\n')
- },
-}
-const npmFetch = { json: noop }
-const log = { warn: noop }
-const mocks = {
- 'proc-log': log,
- 'npm-registry-fetch': npmFetch,
- '../../../lib/utils/get-identity.js': async () => 'foo',
-}
+const mockStars = async (t, { npmFetch = noop, exec = true, ...opts }) => {
+ const mock = await mockNpm(t, {
+ mocks: {
+ 'npm-registry-fetch': Object.assign(noop, realFetch, { json: npmFetch }),
+ '{LIB}/utils/get-identity.js': async () => 'foo',
+ },
+ ...opts,
+ })
-const Stars = t.mock('../../../lib/commands/stars.js', mocks)
-const stars = new Stars(npm)
+ const stars = { exec: (args) => mock.npm.exec('stars', args) }
-t.afterEach(() => {
- npm.config = { get () {} }
- log.warn = noop
- result = ''
-})
+ if (exec) {
+ await stars.exec(Array.isArray(exec) ? exec : [])
+ mock.result = mock.joinedOutput()
+ }
+
+ return {
+ ...mock,
+ stars,
+ logs: () => mock.logs.filter(l => l[1] === 'stars').map(l => l[2]),
+ }
+}
t.test('no args', async t => {
- npmFetch.json = async (uri, opts) => {
+ t.plan(3)
+
+ const npmFetch = async (uri, opts) => {
t.equal(uri, '/-/_view/starredByUser', 'should fetch from expected uri')
t.equal(opts.query.key, '"foo"', 'should match logged in username')
@@ -43,7 +45,7 @@ t.test('no args', async t => {
}
}
- await stars.exec([])
+ const { result } = await mockStars(t, { npmFetch, exec: true })
t.matchSnapshot(
result,
@@ -53,7 +55,8 @@ t.test('no args', async t => {
t.test('npm star <user>', async t => {
t.plan(3)
- npmFetch.json = async (uri, opts) => {
+
+ const npmFetch = async (uri, opts) => {
t.equal(uri, '/-/_view/starredByUser', 'should fetch from expected uri')
t.equal(opts.query.key, '"ruyadorno"', 'should match username')
@@ -62,7 +65,7 @@ t.test('npm star <user>', async t => {
}
}
- await stars.exec(['ruyadorno'])
+ const { result } = await mockStars(t, { npmFetch, exec: ['ruyadorno'] })
t.match(
result,
@@ -72,22 +75,14 @@ t.test('npm star <user>', async t => {
})
t.test('unauthorized request', async t => {
- t.plan(4)
- npmFetch.json = async () => {
+ const npmFetch = async () => {
throw Object.assign(
new Error('Not logged in'),
{ code: 'ENEEDAUTH' }
)
}
- log.warn = (title, msg) => {
- t.equal(title, 'stars', 'should use expected title')
- t.equal(
- msg,
- 'auth is required to look up your username',
- 'should warn auth required msg'
- )
- }
+ const { joinedOutput, stars, logs } = await mockStars(t, { npmFetch, exec: false })
await t.rejects(
stars.exec([]),
@@ -95,41 +90,43 @@ t.test('unauthorized request', async t => {
'should throw unauthorized request msg'
)
+ t.strictSame(
+ logs(),
+ ['auth is required to look up your username'],
+ 'should warn auth required msg'
+ )
+
t.equal(
- result,
+ joinedOutput(),
'',
'should have empty output'
)
})
t.test('unexpected error', async t => {
- npmFetch.json = async () => {
+ const npmFetch = async () => {
throw new Error('ERROR')
}
- log.warn = (title, msg) => {
- throw new Error('Should not output extra warning msgs')
- }
+ const { stars, logs } = await mockStars(t, { npmFetch, exec: false })
await t.rejects(
stars.exec([]),
/ERROR/,
'should throw unexpected error message'
)
+
+ t.strictSame(logs(), [], 'no logs')
})
t.test('no pkg starred', async t => {
- t.plan(2)
- npmFetch.json = async (uri, opts) => ({ rows: [] })
-
- log.warn = (title, msg) => {
- t.equal(title, 'stars', 'should use expected title')
- t.equal(
- msg,
- 'user has not starred any packages',
- 'should warn no starred packages msg'
- )
- }
+ const npmFetch = async () => ({ rows: [] })
- await stars.exec([])
+ const { logs } = await mockStars(t, { npmFetch, exec: true })
+
+ t.strictSame(
+ logs(),
+ ['user has not starred any packages'],
+ 'should warn no starred packages msg'
+ )
})
diff --git a/deps/npm/test/lib/commands/start.js b/deps/npm/test/lib/commands/start.js
index 47f7f1a6e0..b0e908b6ae 100644
--- a/deps/npm/test/lib/commands/start.js
+++ b/deps/npm/test/lib/commands/start.js
@@ -19,11 +19,11 @@ t.test('should run start script from package.json', async t => {
},
config: {
loglevel: 'silent',
- scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
+ 'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
},
})
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'node ./test-start.js foo']
: ['-c', 'node ./test-start.js foo']
diff --git a/deps/npm/test/lib/commands/stop.js b/deps/npm/test/lib/commands/stop.js
index 9ca7742884..560f7deb75 100644
--- a/deps/npm/test/lib/commands/stop.js
+++ b/deps/npm/test/lib/commands/stop.js
@@ -19,11 +19,11 @@ t.test('should run stop script from package.json', async t => {
},
config: {
loglevel: 'silent',
- scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
+ 'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
},
})
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'node ./test-stop.js foo']
: ['-c', 'node ./test-stop.js foo']
diff --git a/deps/npm/test/lib/commands/team.js b/deps/npm/test/lib/commands/team.js
index 792418788b..a13a56d986 100644
--- a/deps/npm/test/lib/commands/team.js
+++ b/deps/npm/test/lib/commands/team.js
@@ -1,39 +1,33 @@
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-let result = ''
-const libnpmteam = {
- async add () {},
- async create () {},
- async destroy () {},
- async lsTeams () {},
- async lsUsers () {},
- async rm () {},
-}
-const npm = mockNpm({
- flatOptions: {},
- config: {
- loglevel: 'info',
- },
- output: (...msg) => {
- result += msg.join('\n')
- },
-})
-const mocks = {
- libnpmteam,
- 'cli-columns': a => a.join(' '),
-}
-
-t.afterEach(() => {
- result = ''
- npm.flatOptions = {}
- npm.config.set('loglevel', 'info')
-})
+const mockNpm = require('../../fixtures/mock-npm')
+
+t.cleanSnapshot = s => s.trim().replace(/\n+/g, '\n')
+
+const mockTeam = async (t, { libnpmteam, ...opts } = {}) => {
+ const mock = await mockNpm(t, {
+ ...opts,
+ mocks: {
+ // XXX: this should be refactored to use the mock registry
+ libnpmteam: libnpmteam || {
+ async add () {},
+ async create () {},
+ async destroy () {},
+ async lsTeams () {},
+ async lsUsers () {},
+ async rm () {},
+ },
+ },
+ })
-const Team = t.mock('../../../lib/commands/team.js', mocks)
-const team = new Team(npm)
+ return {
+ ...mock,
+ team: { exec: (args) => mock.npm.exec('team', args) },
+ result: () => mock.joinedOutput(),
+ }
+}
t.test('no args', async t => {
+ const { team } = await mockTeam(t)
await t.rejects(
team.exec([]),
'usage instructions',
@@ -43,29 +37,35 @@ t.test('no args', async t => {
t.test('team add <scope:team> <user>', async t => {
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t)
+
await team.exec(['add', '@npmcli:developers', 'foo'])
- t.matchSnapshot(result, 'should output success result for add user')
+ t.matchSnapshot(result(), 'should output success result for add user')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ config: { parseable: true },
+ })
await team.exec(['add', '@npmcli:developers', 'foo'])
t.matchSnapshot(
- result,
+ result(),
'should output success result for parseable add user'
)
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ config: { json: true },
+ })
await team.exec(['add', '@npmcli:developers', 'foo'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
{
added: true,
team: 'npmcli:developers',
@@ -76,39 +76,47 @@ t.test('team add <scope:team> <user>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ config: { silent: true },
+ })
await team.exec(['add', '@npmcli:developers', 'foo'])
- t.same(result, '', 'should not output success if silent')
+ t.same(result(), '', 'should not output success if silent')
})
})
t.test('team create <scope:team>', async t => {
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t)
+
await team.exec(['create', '@npmcli:newteam'])
- t.matchSnapshot(result, 'should output success result for create team')
+ t.matchSnapshot(result(), 'should output success result for create team')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ config: { parseable: true },
+ })
await team.exec(['create', '@npmcli:newteam'])
t.matchSnapshot(
- result,
+ result(),
'should output parseable success result for create team'
)
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ config: { json: true },
+ })
await team.exec(['create', '@npmcli:newteam'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
{
created: true,
team: 'npmcli:newteam',
@@ -118,31 +126,38 @@ t.test('team create <scope:team>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ config: { silent: true },
+ })
await team.exec(['create', '@npmcli:newteam'])
- t.same(result, '', 'should not output create success if silent')
+ t.same(result(), '', 'should not output create success if silent')
})
})
t.test('team destroy <scope:team>', async t => {
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t)
await team.exec(['destroy', '@npmcli:newteam'])
- t.matchSnapshot(result, 'should output success result for destroy team')
+ t.matchSnapshot(result(), 'should output success result for destroy team')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ config: { parseable: true },
+ })
await team.exec(['destroy', '@npmcli:newteam'])
- t.matchSnapshot(result, 'should output parseable result for destroy team')
+ t.matchSnapshot(result(), 'should output parseable result for destroy team')
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ config: { json: true },
+ })
await team.exec(['destroy', '@npmcli:newteam'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
{
deleted: true,
team: 'npmcli:newteam',
@@ -152,14 +167,16 @@ t.test('team destroy <scope:team>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ config: { silent: true },
+ })
await team.exec(['destroy', '@npmcli:newteam'])
- t.same(result, '', 'should not output destroy if silent')
+ t.same(result(), '', 'should not output destroy if silent')
})
})
t.test('team ls <scope>', async t => {
- const libnpmteam = {
+ const teams = {
async lsTeams () {
return [
'npmcli:developers',
@@ -169,28 +186,43 @@ t.test('team ls <scope>', async t => {
},
}
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
- })
- const team = new Team(npm)
+ const noTeam = {
+ async lsTeams () {
+ return []
+ },
+ }
+
+ const singleTeam = {
+ async lsTeams () {
+ return ['npmcli:developers']
+ },
+ }
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: teams,
+ })
await team.exec(['ls', '@npmcli'])
- t.matchSnapshot(result, 'should list teams for a given scope')
+ t.matchSnapshot(result(), 'should list teams for a given scope')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: teams,
+ config: { parseable: true },
+ })
await team.exec(['ls', '@npmcli'])
- t.matchSnapshot(result, 'should list teams for a parseable scope')
+ t.matchSnapshot(result(), 'should list teams for a parseable scope')
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: teams,
+ config: { json: true },
+ })
await team.exec(['ls', '@npmcli'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
[
'npmcli:designers',
'npmcli:developers',
@@ -201,75 +233,78 @@ t.test('team ls <scope>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: teams,
+ config: { silent: true },
+ })
await team.exec(['ls', '@npmcli'])
- t.same(result, '', 'should not list teams if silent')
+ t.same(result(), '', 'should not list teams if silent')
})
t.test('no teams', async t => {
- const libnpmteam = {
- async lsTeams () {
- return []
- },
- }
-
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: noTeam,
})
- const team = new Team(npm)
await team.exec(['ls', '@npmcli'])
- t.matchSnapshot(result, 'should list no teams for a given scope')
+ t.matchSnapshot(result(), 'should list no teams for a given scope')
})
t.test('single team', async t => {
- const libnpmteam = {
- async lsTeams () {
- return ['npmcli:developers']
- },
- }
-
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: singleTeam,
})
- const team = new Team(npm)
await team.exec(['ls', '@npmcli'])
- t.matchSnapshot(result, 'should list single team for a given scope')
+ t.matchSnapshot(result(), 'should list single team for a given scope')
})
})
t.test('team ls <scope:team>', async t => {
- const libnpmteam = {
+ const users = {
async lsUsers () {
return ['nlf', 'ruyadorno', 'darcyclarke', 'isaacs']
},
}
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
- })
- const team = new Team(npm)
+
+ const singleUser = {
+ async lsUsers () {
+ return ['foo']
+ },
+ }
+
+ const noUsers = {
+ async lsUsers () {
+ return []
+ },
+ }
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: users,
+ })
await team.exec(['ls', '@npmcli:developers'])
- t.matchSnapshot(result, 'should list users for a given scope:team')
+ t.matchSnapshot(result(), 'should list users for a given scope:team')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: users,
+ config: { parseable: true },
+ })
await team.exec(['ls', '@npmcli:developers'])
- t.matchSnapshot(result, 'should list users for a parseable scope:team')
+ t.matchSnapshot(result(), 'should list users for a parseable scope:team')
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: users,
+ config: { json: true },
+ })
await team.exec(['ls', '@npmcli:developers'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
[
'darcyclarke',
'isaacs',
@@ -281,63 +316,55 @@ t.test('team ls <scope:team>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: users,
+ config: { silent: true },
+ })
await team.exec(['ls', '@npmcli:developers'])
- t.same(result, '', 'should not output users if silent')
+ t.same(result(), '', 'should not output users if silent')
})
t.test('no users', async t => {
- const libnpmteam = {
- async lsUsers () {
- return []
- },
- }
-
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: noUsers,
})
- const team = new Team(npm)
await team.exec(['ls', '@npmcli:developers'])
- t.matchSnapshot(result, 'should list no users for a given scope')
+ t.matchSnapshot(result(), 'should list no users for a given scope')
})
t.test('single user', async t => {
- const libnpmteam = {
- async lsUsers () {
- return ['foo']
- },
- }
-
- const Team = t.mock('../../../lib/commands/team.js', {
- ...mocks,
- libnpmteam,
+ const { team, result } = await mockTeam(t, {
+ libnpmteam: singleUser,
})
- const team = new Team(npm)
await team.exec(['ls', '@npmcli:developers'])
- t.matchSnapshot(result, 'should list single user for a given scope')
+ t.matchSnapshot(result(), 'should list single user for a given scope')
})
})
t.test('team rm <scope:team> <user>', async t => {
t.test('default output', async t => {
+ const { team, result } = await mockTeam(t)
await team.exec(['rm', '@npmcli:newteam', 'foo'])
- t.matchSnapshot(result, 'should output success result for remove user')
+ t.matchSnapshot(result(), 'should output success result for remove user')
})
t.test('--parseable', async t => {
- npm.flatOptions.parseable = true
+ const { team, result } = await mockTeam(t, {
+ config: { parseable: true },
+ })
await team.exec(['rm', '@npmcli:newteam', 'foo'])
- t.matchSnapshot(result, 'should output parseable result for remove user')
+ t.matchSnapshot(result(), 'should output parseable result for remove user')
})
t.test('--json', async t => {
- npm.flatOptions.json = true
+ const { team, result } = await mockTeam(t, {
+ config: { json: true },
+ })
await team.exec(['rm', '@npmcli:newteam', 'foo'])
t.same(
- JSON.parse(result),
+ JSON.parse(result()),
{
removed: true,
team: 'npmcli:newteam',
@@ -348,14 +375,17 @@ t.test('team rm <scope:team> <user>', async t => {
})
t.test('--silent', async t => {
- npm.config.set('loglevel', 'silent')
+ const { team, result } = await mockTeam(t, {
+ config: { silent: true },
+ })
await team.exec(['rm', '@npmcli:newteam', 'foo'])
- t.same(result, '', 'should not output rm result if silent')
+ t.same(result(), '', 'should not output rm result if silent')
})
})
-t.test('completion', t => {
- const { completion } = team
+t.test('completion', async t => {
+ const { npm } = await mockTeam(t)
+ const { completion } = await npm.cmd('team')
t.test('npm team autocomplete', async t => {
const res = await completion({
diff --git a/deps/npm/test/lib/commands/test.js b/deps/npm/test/lib/commands/test.js
index 3a62b6a2d3..4786d72de2 100644
--- a/deps/npm/test/lib/commands/test.js
+++ b/deps/npm/test/lib/commands/test.js
@@ -19,11 +19,11 @@ t.test('should run test script from package.json', async t => {
},
config: {
loglevel: 'silent',
- scriptShell: process.platform === 'win32' ? process.env.COMSPEC : 'sh',
+ 'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
},
})
- const scriptShell = npm.config.get('scriptShell')
+ const scriptShell = npm.config.get('script-shell')
const scriptArgs = isCmdRe.test(scriptShell)
? ['/d', '/s', '/c', 'node ./test-test.js foo']
: ['-c', 'node ./test-test.js foo']
diff --git a/deps/npm/test/lib/commands/token.js b/deps/npm/test/lib/commands/token.js
index af53f49a13..1fd686a442 100644
--- a/deps/npm/test/lib/commands/token.js
+++ b/deps/npm/test/lib/commands/token.js
@@ -1,73 +1,43 @@
const t = require('tap')
+const mockNpm = require('../../fixtures/mock-npm')
-const mocks = {
- profile: {},
- output: () => {},
- readUserInfo: {},
-}
-const npm = {
- output: (...args) => mocks.output(...args),
- config: { validate: () => {} },
-}
+const mockToken = async (t, { profile, getCredentialsByURI, readUserInfo, ...opts } = {}) => {
+ const mocks = {}
-const mockToken = (otherMocks) => t.mock('../../../lib/commands/token.js', {
- '../../../lib/utils/read-user-info.js': mocks.readUserInfo,
- 'npm-profile': mocks.profile,
- ...otherMocks,
-})
+ if (profile) {
+ mocks['npm-profile'] = profile
+ }
-const tokenWithMocks = (options = {}) => {
- const { log, ...mockRequests } = options
-
- for (const mod in mockRequests) {
- if (mod === 'npm') {
- mockRequests.npm = { ...npm, ...mockRequests.npm }
- mockRequests.npm.config.validate = () => {}
- } else {
- if (typeof mockRequests[mod] === 'function') {
- mocks[mod] = mockRequests[mod]
- } else {
- for (const key in mockRequests[mod]) {
- mocks[mod][key] = mockRequests[mod][key]
- }
- }
- }
+ if (readUserInfo) {
+ mocks['{LIB}/utils/read-user-info.js'] = readUserInfo
}
- const reset = () => {
- for (const mod in mockRequests) {
- if (mod !== 'npm') {
- if (typeof mockRequests[mod] === 'function') {
- mocks[mod] = () => {}
- } else {
- for (const key in mockRequests[mod]) {
- delete mocks[mod][key]
- }
- }
- }
- }
+ const mock = await mockNpm(t, {
+ ...opts,
+ mocks,
+ })
+
+ // XXX: replace with mock registry
+ if (getCredentialsByURI) {
+ mock.npm.config.getCredentialsByURI = getCredentialsByURI
}
- const MockedToken = mockToken(log ? {
- 'proc-log': {
- info: log.info,
- },
- npmlog: {
- gauge: log.gauge,
- newItem: log.newItem,
- },
- } : {})
- const token = new MockedToken(mockRequests.npm || npm)
- return [token, reset]
-}
+ const token = {
+ exec: (args) => mock.npm.exec('token', args),
+ }
-t.test('completion', t => {
- t.plan(5)
+ return {
+ ...mock,
+ token,
+ }
+}
- const [token] = tokenWithMocks()
+t.test('completion', async t => {
+ const { npm } = await mockToken(t)
+ const { completion } = await npm.cmd('token')
const testComp = (argv, expect) => {
- t.resolveMatch(token.completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' '))
+ t.resolveMatch(completion({ conf: { argv: { remain: argv } } }), expect, argv.join(' '))
}
testComp(['npm', 'token'], ['list', 'revoke', 'create'])
@@ -75,32 +45,18 @@ t.test('completion', t => {
testComp(['npm', 'token', 'revoke'], [])
testComp(['npm', 'token', 'create'], [])
- t.rejects(token.completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), {
+ t.rejects(completion({ conf: { argv: { remain: ['npm', 'token', 'foobar'] } } }), {
message: 'foobar not recognize',
})
})
t.test('token foobar', async t => {
- t.plan(2)
-
- const [token, reset] = tokenWithMocks({
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'shows a gauge')
- },
- },
- },
- })
-
- t.teardown(reset)
+ const { token } = await mockToken(t)
await t.rejects(token.exec(['foobar']), /foobar is not a recognized subcommand/)
})
t.test('token list', async t => {
- t.plan(14)
-
const now = new Date().toISOString()
const tokens = [
{
@@ -121,15 +77,11 @@ t.test('token list', async t => {
},
]
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', otp: '123456' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', otp: '123456' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: conf => {
@@ -137,39 +89,23 @@ t.test('token list', async t => {
return tokens
},
},
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token')
- },
- },
- info: (type, msg) => {
- t.equal(type, 'token')
- t.equal(msg, 'getting list')
- },
- },
- output: spec => {
- const lines = spec.split(/\r?\n/)
- t.match(lines[3], ' abcd123 ', 'includes the trimmed key')
- t.match(lines[3], ' efgh56… ', 'includes the trimmed token')
- t.match(lines[3], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
- t.match(lines[3], ' no ', 'includes the "no" string for readonly state')
- t.match(lines[5], ' abcd125 ', 'includes the trimmed key')
- t.match(lines[5], ' hgfe87… ', 'includes the trimmed token')
- t.match(lines[5], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
- t.match(lines[5], ' yes ', 'includes the "no" string for readonly state')
- t.match(lines[5], ` ${tokens[1].cidr_whitelist.join(',')} `, 'includes the cidr whitelist')
- },
})
- t.teardown(reset)
-
await token.exec([])
+
+ const lines = joinedOutput().split(/\r?\n/)
+ t.match(lines[3], ' abcd123 ', 'includes the trimmed key')
+ t.match(lines[3], ' efgh56… ', 'includes the trimmed token')
+ t.match(lines[3], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
+ t.match(lines[3], ' no ', 'includes the "no" string for readonly state')
+ t.match(lines[5], ' abcd125 ', 'includes the trimmed key')
+ t.match(lines[5], ' hgfe87… ', 'includes the trimmed token')
+ t.match(lines[5], ` ${now.slice(0, 10)} `, 'includes the trimmed creation timestamp')
+ t.match(lines[5], ' yes ', 'includes the "no" string for readonly state')
+ t.match(lines[5], ` ${tokens[1].cidr_whitelist.join(',')} `, 'includes the cidr whitelist')
})
t.test('token list json output', async t => {
- t.plan(7)
-
const now = new Date().toISOString()
const tokens = [
{
@@ -182,15 +118,11 @@ t.test('token list json output', async t => {
},
]
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', json: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { username: 'foo', password: 'bar' }
- },
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', json: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { username: 'foo', password: 'bar' }
},
profile: {
listTokens: conf => {
@@ -202,32 +134,16 @@ t.test('token list json output', async t => {
return tokens
},
},
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token')
- },
- },
- info: (type, msg) => {
- t.equal(type, 'token')
- t.equal(msg, 'getting list')
- },
- },
- output: spec => {
- t.type(spec, 'string', 'is called with a string')
- const parsed = JSON.parse(spec)
- t.match(parsed, tokens, 'prints the json parsed tokens')
- },
- })
- t.teardown(reset)
+ })
await token.exec(['list'])
+
+ const parsed = JSON.parse(joinedOutput())
+ t.match(parsed, tokens, 'prints the json parsed tokens')
})
t.test('token list parseable output', async t => {
- t.plan(11)
-
const now = new Date().toISOString()
const tokens = [
{
@@ -248,17 +164,11 @@ t.test('token list parseable output', async t => {
},
]
- let callCount = 0
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', parseable: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { auth: Buffer.from('foo:bar').toString('base64') }
- },
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', parseable: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { auth: Buffer.from('foo:bar').toString('base64') }
},
profile: {
listTokens: conf => {
@@ -270,82 +180,43 @@ t.test('token list parseable output', async t => {
return tokens
},
},
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token')
- },
- },
- info: (type, msg) => {
- t.equal(type, 'token')
- t.equal(msg, 'getting list')
- },
- },
- output: spec => {
- ++callCount
- t.type(spec, 'string', 'is called with a string')
- if (callCount === 1) {
- t.equal(
- spec,
- ['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t'),
- 'prints header'
- )
- } else if (callCount === 2) {
- t.equal(
- spec,
- [tokens[0].key, tokens[0].token, tokens[0].created, tokens[0].readonly, ''].join('\t'),
- 'prints token info'
- )
- } else {
- t.equal(
- spec,
- [
- tokens[1].key,
- tokens[1].token,
- tokens[1].created,
- tokens[1].readonly,
- tokens[1].cidr_whitelist.join(','),
- ].join('\t'),
- 'prints token info'
- )
- }
- },
})
- t.teardown(reset)
-
await token.exec(['list'])
+
+ const lines = joinedOutput().split(/\r?\n/)
+
+ t.equal(
+ lines[0],
+ ['key', 'token', 'created', 'readonly', 'CIDR whitelist'].join('\t'),
+ 'prints header'
+ )
+
+ t.equal(
+ lines[1],
+ [tokens[0].key, tokens[0].token, tokens[0].created, tokens[0].readonly, ''].join('\t'),
+ 'prints token info'
+ )
+
+ t.equal(
+ lines[2],
+ [
+ tokens[1].key,
+ tokens[1].token,
+ tokens[1].created,
+ tokens[1].readonly,
+ tokens[1].cidr_whitelist.join(','),
+ ].join('\t'),
+ 'prints token info'
+ )
})
t.test('token revoke', async t => {
- t.plan(9)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return {}
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return {}
},
profile: {
listTokens: conf => {
@@ -356,45 +227,19 @@ t.test('token revoke', async t => {
t.equal(key, 'abcd1234', 'deletes the correct token')
},
},
- output: spec => {
- t.equal(spec, 'Removed 1 token')
- },
})
- t.teardown(reset)
-
await token.exec(['rm', 'abcd'])
+
+ t.equal(joinedOutput(), 'Removed 1 token')
})
t.test('token revoke multiple tokens', async t => {
- t.plan(9)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'efgh5678' }]),
@@ -403,45 +248,19 @@ t.test('token revoke multiple tokens', async t => {
t.ok(['abcd1234', 'efgh5678'].includes(key), 'deletes the correct token')
},
},
- output: spec => {
- t.equal(spec, 'Removed 2 tokens')
- },
})
- t.teardown(reset)
-
await token.exec(['revoke', 'abcd', 'efgh'])
+
+ t.equal(joinedOutput(), 'Removed 2 tokens')
})
t.test('token revoke json output', async t => {
- t.plan(9)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', json: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', json: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
@@ -449,47 +268,21 @@ t.test('token revoke json output', async t => {
t.equal(key, 'abcd1234', 'deletes the correct token')
},
},
- output: spec => {
- t.type(spec, 'string', 'is given a string')
- const parsed = JSON.parse(spec)
- t.same(parsed, ['abcd1234'], 'logs the token as json')
- },
- })
- t.teardown(reset)
+ })
await token.exec(['delete', 'abcd'])
+
+ const parsed = JSON.parse(joinedOutput())
+ t.same(parsed, ['abcd1234'], 'logs the token as json')
})
t.test('token revoke parseable output', async t => {
- t.plan(8)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', parseable: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', parseable: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
@@ -497,45 +290,19 @@ t.test('token revoke parseable output', async t => {
t.equal(key, 'abcd1234', 'deletes the correct token')
},
},
- output: spec => {
- t.equal(spec, 'abcd1234', 'logs the token as a string')
- },
})
- t.teardown(reset)
-
await token.exec(['remove', 'abcd'])
+
+ t.equal(joinedOutput(), 'abcd1234', 'logs the token as a string')
})
t.test('token revoke by token', async t => {
- t.plan(8)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234', token: 'efgh5678' }]),
@@ -543,143 +310,60 @@ t.test('token revoke by token', async t => {
t.equal(key, 'efgh5678', 'passes through user input')
},
},
- output: spec => {
- t.equal(spec, 'Removed 1 token')
- },
})
- t.teardown(reset)
-
await token.exec(['rm', 'efgh5678'])
+ t.equal(joinedOutput(), 'Removed 1 token')
})
t.test('token revoke requires an id', async t => {
- t.plan(2)
-
- const [token, reset] = tokenWithMocks({
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token')
- },
- },
- },
- })
-
- t.teardown(reset)
+ const { token } = await mockToken(t)
await t.rejects(token.exec(['rm']), /`<tokenKey>` argument is required/)
})
t.test('token revoke ambiguous id errors', async t => {
- t.plan(7)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234' }, { key: 'abcd5678' }]),
},
})
- t.teardown(reset)
-
await t.rejects(token.exec(['rm', 'abcd']), /Token ID "abcd" was ambiguous/)
})
t.test('token revoke unknown id errors', async t => {
- t.plan(7)
-
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- newItem: (action, len) => {
- t.equal(action, 'removing tokens')
- t.equal(len, 0)
- return {
- info: (name, progress) => {
- t.equal(name, 'token')
- t.equal(progress, 'getting existing list')
- },
- }
- },
+ const { token } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
profile: {
listTokens: () => Promise.resolve([{ key: 'abcd1234' }]),
},
})
- t.teardown(reset)
-
await t.rejects(token.exec(['rm', 'efgh']), /Unknown token id or value "efgh"./)
})
t.test('token create', async t => {
- t.plan(14)
-
const now = new Date().toISOString()
const password = 'thisisnotreallyapassword'
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: {
- registry: 'https://registry.npmjs.org',
- cidr: ['10.0.0.0/8', '192.168.1.0/24'],
- },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: {
+ registry: 'https://registry.npmjs.org',
+ cidr: ['10.0.0.0/8', '192.168.1.0/24'],
},
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- info: (name, message) => {
- t.equal(name, 'token')
- t.equal(message, 'creating')
- },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
readUserInfo: {
password: () => Promise.resolve(password),
@@ -687,7 +371,7 @@ t.test('token create', async t => {
profile: {
createToken: (pw, readonly, cidr) => {
t.equal(pw, password)
- t.equal(readonly, undefined)
+ t.equal(readonly, false)
t.same(cidr, ['10.0.0.0/8', '192.168.1.0/24'], 'defaults to empty array')
return {
key: 'abcd1234',
@@ -699,49 +383,30 @@ t.test('token create', async t => {
}
},
},
- output: spec => {
- const lines = spec.split(/\r?\n/)
- t.match(lines[1], 'token')
- t.match(lines[1], 'efgh5678', 'prints the whole token')
- t.match(lines[3], 'created')
- t.match(lines[3], now, 'prints the correct timestamp')
- t.match(lines[5], 'readonly')
- t.match(lines[5], 'false', 'prints the readonly flag')
- t.match(lines[7], 'cidr_whitelist')
- },
- })
- t.teardown(reset)
+ })
await token.exec(['create'])
+
+ const lines = joinedOutput().split(/\r?\n/)
+ t.match(lines[1], 'token')
+ t.match(lines[1], 'efgh5678', 'prints the whole token')
+ t.match(lines[3], 'created')
+ t.match(lines[3], now, 'prints the correct timestamp')
+ t.match(lines[5], 'readonly')
+ t.match(lines[5], 'false', 'prints the readonly flag')
+ t.match(lines[7], 'cidr_whitelist')
})
t.test('token create json output', async t => {
- t.plan(9)
-
const now = new Date().toISOString()
const password = 'thisisnotreallyapassword'
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', json: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- info: (name, message) => {
- t.equal(name, 'token')
- t.equal(message, 'creating')
- },
+ const { token } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', json: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
readUserInfo: {
password: () => Promise.resolve(password),
@@ -749,7 +414,7 @@ t.test('token create json output', async t => {
profile: {
createToken: (pw, readonly, cidr) => {
t.equal(pw, password)
- t.equal(readonly, undefined)
+ t.equal(readonly, false)
t.same(cidr, [], 'defaults to empty array')
return {
key: 'abcd1234',
@@ -772,38 +437,18 @@ t.test('token create json output', async t => {
},
})
- t.teardown(reset)
-
await token.exec(['create'])
})
t.test('token create parseable output', async t => {
- t.plan(11)
-
const now = new Date().toISOString()
const password = 'thisisnotreallyapassword'
- let callCount = 0
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', parseable: true },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
- info: (name, message) => {
- t.equal(name, 'token')
- t.equal(message, 'creating')
- },
+ const { token, joinedOutput } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', parseable: true },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
readUserInfo: {
password: () => Promise.resolve(password),
@@ -811,7 +456,7 @@ t.test('token create parseable output', async t => {
profile: {
createToken: (pw, readonly, cidr) => {
t.equal(pw, password)
- t.equal(readonly, undefined)
+ t.equal(readonly, false)
t.same(cidr, [], 'defaults to empty array')
return {
key: 'abcd1234',
@@ -823,54 +468,32 @@ t.test('token create parseable output', async t => {
}
},
},
- output: spec => {
- ++callCount
- if (callCount === 1) {
- t.match(spec, 'token\tefgh5678', 'prints the token')
- } else if (callCount === 2) {
- t.match(spec, `created\t${now}`, 'prints the created timestamp')
- } else if (callCount === 3) {
- t.match(spec, 'readonly\tfalse', 'prints the readonly flag')
- } else {
- t.match(spec, 'cidr_whitelist\t', 'prints the cidr whitelist')
- }
- },
})
- t.teardown(reset)
-
await token.exec(['create'])
+
+ const spec = joinedOutput().split(/\r?\n/)
+
+ t.match(spec[0], 'token\tefgh5678', 'prints the token')
+ t.match(spec[1], `created\t${now}`, 'prints the created timestamp')
+ t.match(spec[2], 'readonly\tfalse', 'prints the readonly flag')
+ t.match(spec[3], 'cidr_whitelist\t', 'prints the cidr whitelist')
})
t.test('token create ipv6 cidr', async t => {
- t.plan(3)
-
const password = 'thisisnotreallyapassword'
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', cidr: '::1/128' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
+ const { token } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', cidr: '::1/128' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
readUserInfo: {
password: () => Promise.resolve(password),
},
})
- t.teardown(reset)
-
await t.rejects(
token.exec(['create']),
{
@@ -882,34 +505,19 @@ t.test('token create ipv6 cidr', async t => {
})
t.test('token create invalid cidr', async t => {
- t.plan(3)
-
const password = 'thisisnotreallyapassword'
- const [token, reset] = tokenWithMocks({
- npm: {
- flatOptions: { registry: 'https://registry.npmjs.org', cidr: 'apple/cider' },
- config: {
- getCredentialsByURI: uri => {
- t.equal(uri, 'https://registry.npmjs.org', 'requests correct registry')
- return { token: 'thisisnotarealtoken' }
- },
- },
- },
- log: {
- gauge: {
- show: name => {
- t.equal(name, 'token', 'starts a gauge')
- },
- },
+ const { token } = await mockToken(t, {
+ config: { registry: 'https://registry.npmjs.org', cidr: 'apple/cider' },
+ getCredentialsByURI: uri => {
+ t.equal(uri, 'https://registry.npmjs.org/', 'requests correct registry')
+ return { token: 'thisisnotarealtoken' }
},
readUserInfo: {
password: () => Promise.resolve(password),
},
})
- t.teardown(reset)
-
await t.rejects(
token.exec(['create']),
{ code: 'EINVALIDCIDR', message: /CIDR whitelist contains invalid CIDR entry: apple\/cider/ },
diff --git a/deps/npm/test/lib/commands/uninstall.js b/deps/npm/test/lib/commands/uninstall.js
index ec7961f9c9..59a517d144 100644
--- a/deps/npm/test/lib/commands/uninstall.js
+++ b/deps/npm/test/lib/commands/uninstall.js
@@ -1,225 +1,205 @@
const t = require('tap')
const fs = require('fs')
const { resolve } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-
-const npm = mockNpm({
- globalDir: '',
- config: {
- global: false,
- prefix: '',
- },
- localPrefix: '',
-})
-const mocks = {
- '../../../lib/utils/reify-finish.js': () => Promise.resolve(),
-}
-
-const Uninstall = t.mock('../../../lib/commands/uninstall.js', mocks)
-const uninstall = new Uninstall(npm)
+const _mockNpm = require('../../fixtures/mock-npm')
+
+const mockNpm = async (t, opts = {}) => {
+ const res = await _mockNpm(t, {
+ ...opts,
+ mocks: {
+ ...opts.mocks,
+ '{LIB}/utils/reify-finish.js': async () => {},
+ },
+ })
-t.afterEach(() => {
- npm.globalDir = ''
- npm.prefix = ''
- npm.localPrefix = ''
- npm.flatOptions.global = false
- npm.flatOptions.prefix = ''
-})
+ return {
+ ...res,
+ uninstall: (args) => res.npm.exec('uninstall', args),
+ }
+}
t.test('remove single installed lib', async t => {
- const path = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-rm-single-lib',
- version: '1.0.0',
- dependencies: {
- a: '*',
- b: '*',
- },
- }),
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- },
- },
- 'package-lock.json': JSON.stringify({
- name: 'test-rm-single-lib',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- packages: {
- '': {
- name: 'test-rm-single-lib',
- version: '1.0.0',
- dependencies: {
- a: '*',
- },
- },
- 'node_modules/a': {
- version: '1.0.0',
- },
- 'node_modules/b': {
- version: '1.0.0',
+ const { uninstall, prefix } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-rm-single-lib',
+ version: '1.0.0',
+ dependencies: {
+ a: '*',
+ b: '*',
},
- },
- dependencies: {
+ }),
+ node_modules: {
a: {
- version: '1.0.0',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
b: {
- version: '1.0.0',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
},
},
- }),
+ 'package-lock.json': JSON.stringify({
+ name: 'test-rm-single-lib',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'test-rm-single-lib',
+ version: '1.0.0',
+ dependencies: {
+ a: '*',
+ },
+ },
+ 'node_modules/a': {
+ version: '1.0.0',
+ },
+ 'node_modules/b': {
+ version: '1.0.0',
+ },
+ },
+ dependencies: {
+ a: {
+ version: '1.0.0',
+ },
+ b: {
+ version: '1.0.0',
+ },
+ },
+ }),
+ },
})
- const b = resolve(path, 'node_modules/b')
- t.ok(() => fs.statSync(b))
+ const b = resolve(prefix, 'node_modules/b')
+ t.ok(fs.statSync(b))
- npm.localPrefix = path
-
- await uninstall.exec(['b'])
+ await uninstall(['b'])
t.throws(() => fs.statSync(b), 'should have removed package from npm')
})
t.test('remove multiple installed libs', async t => {
- const path = t.testdir({
- node_modules: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
- },
- b: {
- 'package.json': JSON.stringify({
- name: 'b',
- version: '1.0.0',
- }),
- },
- },
- 'package-lock.json': JSON.stringify({
- name: 'test-rm-single-lib',
- version: '1.0.0',
- lockfileVersion: 2,
- requires: true,
- packages: {
- '': {
- name: 'test-rm-single-lib',
- version: '1.0.0',
- dependencies: {
- a: '*',
- },
- },
- 'node_modules/a': {
- version: '1.0.0',
- },
- 'node_modules/b': {
- version: '1.0.0',
- },
- },
- dependencies: {
+ const { uninstall, prefix } = await mockNpm(t, {
+ prefixDir: {
+ node_modules: {
a: {
- version: '1.0.0',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
b: {
- version: '1.0.0',
+ 'package.json': JSON.stringify({
+ name: 'b',
+ version: '1.0.0',
+ }),
},
},
- }),
+ 'package-lock.json': JSON.stringify({
+ name: 'test-rm-single-lib',
+ version: '1.0.0',
+ lockfileVersion: 2,
+ requires: true,
+ packages: {
+ '': {
+ name: 'test-rm-single-lib',
+ version: '1.0.0',
+ dependencies: {
+ a: '*',
+ },
+ },
+ 'node_modules/a': {
+ version: '1.0.0',
+ },
+ 'node_modules/b': {
+ version: '1.0.0',
+ },
+ },
+ dependencies: {
+ a: {
+ version: '1.0.0',
+ },
+ b: {
+ version: '1.0.0',
+ },
+ },
+ }),
+ },
})
- const a = resolve(path, 'node_modules/a')
- const b = resolve(path, 'node_modules/b')
- t.ok(() => fs.statSync(a))
- t.ok(() => fs.statSync(b))
-
- npm.localPrefix = path
+ const a = resolve(prefix, 'node_modules/a')
+ const b = resolve(prefix, 'node_modules/b')
+ t.ok(fs.statSync(a))
+ t.ok(fs.statSync(b))
- await uninstall.exec(['b'])
+ await uninstall(['b'])
t.throws(() => fs.statSync(a), 'should have removed a package from nm')
t.throws(() => fs.statSync(b), 'should have removed b package from nm')
})
t.test('no args local', async t => {
- const path = t.testdir()
-
- npm.flatOptions.prefix = path
+ const { uninstall } = await mockNpm(t)
await t.rejects(
- uninstall.exec([]),
+ uninstall([]),
/Must provide a package name to remove/,
'should throw package name required error'
)
})
t.test('no args global', async t => {
- const path = t.testdir({
- lib: {
- node_modules: {
- a: t.fixture('symlink', '../../projects/a'),
- },
+ const { uninstall, npm } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ }),
},
- projects: {
- a: {
- 'package.json': JSON.stringify({
- name: 'a',
- version: '1.0.0',
- }),
+ globalPrefixDir: {
+ node_modules: {
+ a: t.fixture('symlink', '../../prefix'),
},
},
+ config: { global: true },
})
- npm.localPrefix = resolve(path, 'projects', 'a')
- npm.globalDir = resolve(path, 'lib', 'node_modules')
- npm.config.set('global', true)
-
- const a = resolve(path, 'lib/node_modules/a')
- t.ok(() => fs.statSync(a))
+ const a = resolve(npm.globalDir, 'a')
+ t.ok(fs.statSync(a))
- await uninstall.exec([])
+ await uninstall([])
t.throws(() => fs.statSync(a), 'should have removed global nm symlink')
})
t.test('no args global but no package.json', async t => {
- const path = t.testdir({})
-
- npm.prefix = path
- npm.localPrefix = path
- npm.flatOptions.global = true
+ const { uninstall } = await mockNpm(t, {
+ config: { global: true },
+ })
await t.rejects(
- uninstall.exec([]),
+ uninstall([]),
/npm uninstall/
)
})
t.test('unknown error reading from localPrefix package.json', async t => {
- const path = t.testdir({})
-
- const Uninstall = t.mock('../../../lib/commands/uninstall.js', {
- ...mocks,
- 'read-package-json-fast': () => Promise.reject(new Error('ERR')),
+ const { uninstall } = await mockNpm(t, {
+ config: { global: true },
+ mocks: {
+ 'read-package-json-fast': async () => {
+ throw new Error('ERR')
+ },
+ },
})
- const uninstall = new Uninstall(npm)
-
- npm.prefix = path
- npm.localPrefix = path
- npm.flatOptions.global = true
await t.rejects(
- uninstall.exec([]),
+ uninstall([]),
/ERR/,
'should throw unknown error'
)
diff --git a/deps/npm/test/lib/commands/update.js b/deps/npm/test/lib/commands/update.js
index fe52554c95..f42fb8a414 100644
--- a/deps/npm/test/lib/commands/update.js
+++ b/deps/npm/test/lib/commands/update.js
@@ -1,166 +1,83 @@
const t = require('tap')
-const { resolve } = require('path')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const _mockNpm = require('../../fixtures/mock-npm')
+
+// XXX: this test has been refactored to use the new mockNpm
+// but it still only asserts the options passed to arborist.
+// TODO: make this really test npm update scenarios
+const mockUpdate = async (t, { exec = [], ...opts } = {}) => {
+ let ctor = null
+ let reify = null
+ let finish = null
+
+ const res = await _mockNpm(t, {
+ ...opts,
+ mocks: {
+ '@npmcli/arborist': class Arborist {
+ constructor (o) {
+ ctor = o
+ }
+
+ reify (o) {
+ reify = o
+ }
+ },
+ '{LIB}/utils/reify-finish.js': (_, o) => {
+ finish = o
+ },
+ },
+ })
-const config = {
- depth: 0,
- global: false,
-}
-const noop = () => null
-const npm = mockNpm({
- globalDir: '',
- config,
- prefix: '',
-})
-const mocks = {
- '@npmcli/arborist': class {
- reify () {}
- },
- '../../../lib/utils/reify-finish.js': noop,
-}
+ await res.npm.exec('update', exec)
-t.afterEach(() => {
- npm.prefix = ''
- config.global = false
- npm.globalDir = ''
-})
+ return {
+ ...res,
+ ctor,
+ reify,
+ finish,
+ }
+}
t.test('no args', async t => {
- t.plan(4)
-
- npm.prefix = '/project/a'
-
- class Arborist {
- constructor (args) {
- const { log, ...rest } = args
- t.same(
- rest,
- {
- ...npm.flatOptions,
- path: npm.prefix,
- save: false,
- workspaces: null,
- },
- 'should call arborist contructor with expected args'
- )
- }
+ const { ctor, reify, finish, prefix } = await mockUpdate(t)
- reify ({ save, update }) {
- t.equal(save, false, 'should default to save=false')
- t.equal(update, true, 'should update all deps')
- }
- }
+ t.equal(ctor.path, prefix, 'path')
+ t.equal(ctor.save, false, 'should default to save=false')
+ t.equal(ctor.workspaces, undefined, 'workspaces')
- const Update = t.mock('../../../lib/commands/update.js', {
- ...mocks,
- '../../../lib/utils/reify-finish.js': (npm, arb) => {
- t.match(arb, Arborist, 'should reify-finish with arborist instance')
- },
- '@npmcli/arborist': Arborist,
- })
- const update = new Update(npm)
+ t.equal(reify.update, true, 'should update all deps')
- await update.exec([])
+ t.equal(finish.constructor.name, 'Arborist')
})
t.test('with args', async t => {
- t.plan(4)
-
- npm.prefix = '/project/a'
- config.save = true
-
- class Arborist {
- constructor (args) {
- const { log, ...rest } = args
- t.same(
- rest,
- {
- ...npm.flatOptions,
- path: npm.prefix,
- save: true,
- workspaces: null,
- },
- 'should call arborist contructor with expected args'
- )
- }
-
- reify ({ save, update }) {
- t.equal(save, true, 'should pass save if manually set')
- t.same(update, ['ipt'], 'should update listed deps')
- }
- }
-
- const Update = t.mock('../../../lib/commands/update.js', {
- ...mocks,
- '../../../lib/utils/reify-finish.js': (npm, arb) => {
- t.match(arb, Arborist, 'should reify-finish with arborist instance')
- },
- '@npmcli/arborist': Arborist,
+ const { ctor, reify } = await mockUpdate(t, {
+ config: { save: true },
+ exec: ['ipt'],
})
- const update = new Update(npm)
- await update.exec(['ipt'])
+ t.equal(ctor.save, true, 'save')
+ t.strictSame(reify.update, ['ipt'], 'ipt')
})
t.test('update --depth=<number>', async t => {
- t.plan(2)
-
- npm.prefix = '/project/a'
- config.depth = 1
-
- const Update = t.mock('../../../lib/commands/update.js', {
- ...mocks,
- 'proc-log': {
- warn: (title, msg) => {
- t.equal(title, 'update', 'should print expected title')
- t.match(
- msg,
- /The --depth option no longer has any effect/,
- 'should print expected warning message'
- )
- },
- },
+ const { logs } = await mockUpdate(t, {
+ config: { depth: 1 },
})
- const update = new Update(npm)
- await update.exec([])
+ const [title, msg] = logs.warn[0]
+ t.equal(title, 'update', 'should print expected title')
+ t.match(
+ msg,
+ /The --depth option no longer has any effect/,
+ 'should print expected warning message'
+ )
})
t.test('update --global', async t => {
- t.plan(2)
-
- const normalizePath = p => p.replace(/\\+/g, '/')
- const redactCwd = (path) => normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
-
- npm.prefix = '/project/a'
- npm.globalDir = resolve(process.cwd(), 'global/lib/node_modules')
- config.global = true
-
- class Arborist {
- constructor (args) {
- const { path, log, ...rest } = args
- t.same(
- rest,
- { ...npm.flatOptions, save: true, workspaces: undefined },
- 'should call arborist contructor with expected options'
- )
-
- t.equal(
- redactCwd(path),
- '{CWD}/global/lib',
- 'should run with expected prefix'
- )
- }
-
- reify () {}
- }
-
- const Update = t.mock('../../../lib/commands/update.js', {
- ...mocks,
- '@npmcli/arborist': Arborist,
+ const { ctor, globalPrefix } = await mockUpdate(t, {
+ config: { global: true },
})
- const update = new Update(npm)
- await update.exec([])
+ t.match(ctor.path, globalPrefix)
+ t.ok(ctor.path.startsWith(globalPrefix))
})
diff --git a/deps/npm/test/lib/commands/version.js b/deps/npm/test/lib/commands/version.js
index 154f6a6f83..c48ff827fa 100644
--- a/deps/npm/test/lib/commands/version.js
+++ b/deps/npm/test/lib/commands/version.js
@@ -1,75 +1,52 @@
const { readFileSync, statSync } = require('fs')
const { resolve } = require('path')
const t = require('tap')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
+const _mockNpm = require('../../fixtures/mock-npm')
const mockGlobals = require('../../fixtures/mock-globals.js')
-let result = []
-
-const noop = () => null
-const config = {
- 'git-tag-version': true,
- 'tag-version-prefix': 'v',
- json: false,
-}
-const flatOptions = {
- workspacesUpdate: true,
-}
-const npm = mockNpm({
- config,
- flatOptions,
- localPrefix: '',
- prefix: '',
- version: '1.0.0',
- output: (...msg) => {
- for (const m of msg) {
- result.push(m)
- }
- },
-})
-const mocks = {
- '../../../lib/utils/reify-finish.js': noop,
+const mockNpm = async (t, opts = {}) => {
+ const res = await _mockNpm(t, {
+ ...opts,
+ mocks: {
+ ...opts.mocks,
+ '{ROOT}/package.json': { version: '1.0.0' },
+ },
+ })
+ return {
+ ...res,
+ version: { exec: (args) => res.npm.exec('version', args) },
+ result: () => res.outputs[0],
+ }
}
-const Version = t.mock('../../../lib/commands/version.js', mocks)
-const version = new Version(npm)
-
-t.afterEach(() => {
- flatOptions.workspacesUpdate = true
- config.json = false
- npm.localPrefix = ''
- npm.prefix = ''
- result = []
-})
-
-t.test('node@1', t => {
+t.test('node@1', async t => {
mockGlobals(t, { 'process.versions': { node: '1.0.0' } }, { replace: true })
t.test('no args', async t => {
- const prefix = t.testdir({
- 'package.json': JSON.stringify({
- name: 'test-version-no-args',
- version: '3.2.1',
- }),
+ const { version, result } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({
+ name: 'test-version-no-args',
+ version: '3.2.1',
+ }),
+ },
})
- npm.prefix = prefix
await version.exec([])
- t.same(
- result,
- [
- {
- 'test-version-no-args': '3.2.1',
- node: '1.0.0',
- npm: '1.0.0',
- },
- ],
+ t.strictSame(
+ result(),
+ [{
+ 'test-version-no-args': '3.2.1',
+ node: '1.0.0',
+ npm: '1.0.0',
+ }],
'should output expected values for various versions in npm'
)
})
t.test('too many args', async t => {
+ const { version } = await mockNpm(t)
await t.rejects(
version.exec(['foo', 'bar']),
/npm version/,
@@ -78,6 +55,8 @@ t.test('node@1', t => {
})
t.test('completion', async t => {
+ const { npm } = await mockNpm(t)
+ const version = await npm.cmd('version')
const testComp = async (argv, expect) => {
const res = await version.completion({ conf: { argv: { remain: argv } } })
t.strictSame(res, expect, argv.join(' '))
@@ -88,99 +67,79 @@ t.test('node@1', t => {
['major', 'minor', 'patch', 'premajor', 'preminor', 'prepatch', 'prerelease', 'from-git']
)
await testComp(['npm', 'version', 'major'], [])
-
- t.end()
})
t.test('failure reading package.json', async t => {
- const prefix = t.testdir({})
- npm.prefix = prefix
+ const { version, result } = await mockNpm(t)
await version.exec([])
- t.same(
- result,
- [
- {
- npm: '1.0.0',
- node: '1.0.0',
- },
- ],
+ t.strictSame(
+ result(),
+ [{
+ npm: '1.0.0',
+ node: '1.0.0',
+ }],
'should not have package name on returning object'
)
})
- t.end()
})
-t.test('empty versions', t => {
+t.test('empty versions', async t => {
mockGlobals(t, { 'process.versions': {} }, { replace: true })
t.test('--json option', async t => {
- const prefix = t.testdir({})
- config.json = true
- npm.prefix = prefix
+ const { version, result } = await mockNpm(t, {
+ config: { json: true },
+ })
await version.exec([])
- t.same(result, ['{\n "npm": "1.0.0"\n}'], 'should return json stringified result')
+ t.same(result(), ['{\n "npm": "1.0.0"\n}'], 'should return json stringified result')
})
t.test('with one arg', async t => {
- const Version = t.mock('../../../lib/commands/version.js', {
- ...mocks,
- libnpmversion: (arg, opts) => {
- t.equal(arg, 'major', 'should forward expected value')
- t.match(
- opts,
- {
- path: '',
- },
- 'should forward expected options'
- )
- return '4.0.0'
+ const { version, result } = await mockNpm(t, {
+ mocks: {
+ libnpmversion: () => '4.0.0',
},
})
- const version = new Version(npm)
await version.exec(['major'])
- t.same(result, ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix')
+ t.same(result(), ['v4.0.0'], 'outputs the new version prefixed by the tagVersionPrefix')
})
t.test('workspaces', async t => {
- t.teardown(() => {
- npm.localPrefix = ''
- npm.prefix = ''
- })
-
t.test('no args, all workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
+ const { version, result } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
},
+ config: { workspaces: true },
})
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], [])
+
+ await version.exec([])
t.same(
- result,
+ result(),
[
{
'workspaces-test': '1.0.0',
@@ -194,35 +153,38 @@ t.test('empty versions', t => {
})
t.test('no args, single workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
+ const { version, result } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
},
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
+ config: {
+ workspace: 'workspace-a',
},
})
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], ['workspace-a'])
+
+ await version.exec([])
t.same(
- result,
+ result(),
[
{
'workspaces-test': '1.0.0',
@@ -235,39 +197,40 @@ t.test('empty versions', t => {
})
t.test('no args, all workspaces, workspace with missing name or version', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
+ const { version, result } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b', 'workspace-c'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ }),
+ },
+ 'workspace-c': {
+ 'package.json': JSON.stringify({
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- }),
- },
- 'workspace-c': {
- 'package.json': JSON.stringify({
- version: '1.0.0',
- }),
},
+ config: { workspaces: true },
})
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces([], [])
+
+ await version.exec([])
t.same(
- result,
+ result(),
[
{
'workspaces-test': '1.0.0',
@@ -280,151 +243,145 @@ t.test('empty versions', t => {
})
t.test('with one arg, all workspaces', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
+ const { version, outputs, prefix } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
- },
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
},
+ config: { workspaces: true },
})
- const Version = t.mock('../../../lib/commands/version.js', {
- '../../../lib/utils/reify-finish.js': noop,
- })
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces(['major'], [])
+ await version.exec(['major'])
t.same(
- result,
+ outputs.map(o => o[0]).slice(0, 4),
['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'],
'outputs the new version for only the workspaces prefixed by the tagVersionPrefix'
)
- t.matchSnapshot(readFileSync(resolve(testDir, 'package-lock.json'), 'utf8'))
+ t.matchSnapshot(readFileSync(resolve(prefix, 'package-lock.json'), 'utf8'))
})
t.test('with one arg, all workspaces, saves package.json', async t => {
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
- dependencies: {
- 'workspace-a': '^1.0.0',
- 'workspace-b': '^1.0.0',
+ const { version, outputs, prefix } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ dependencies: {
+ 'workspace-a': '^1.0.0',
+ 'workspace-b': '^1.0.0',
+ },
},
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
},
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
+ config: {
+ save: true,
+ workspaces: true,
},
})
- const Version = t.mock('../../../lib/commands/version.js', {
- '../../../lib/utils/reify-finish.js': noop,
- })
- config.save = true
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces(['major'], [])
+ await version.exec(['major'])
t.same(
- result,
+ outputs.map(o => o[0]).slice(0, 4),
['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'],
'outputs the new version for only the workspaces prefixed by the tagVersionPrefix'
)
- t.matchSnapshot(readFileSync(resolve(testDir, 'package-lock.json'), 'utf8'))
+ t.matchSnapshot(readFileSync(resolve(prefix, 'package-lock.json'), 'utf8'))
})
t.test('too many args', async t => {
+ const { version } = await mockNpm(t, { config: { workspaces: true } })
+
await t.rejects(
- version.execWorkspaces(['foo', 'bar'], []),
+ version.exec(['foo', 'bar']),
/npm version/,
'should throw usage instructions error'
)
})
t.test('no workspaces-update', async t => {
- flatOptions.workspacesUpdate = false
-
- const libNpmVersionArgs = []
- const testDir = t.testdir({
- 'package.json': JSON.stringify(
- {
- name: 'workspaces-test',
- version: '1.0.0',
- workspaces: ['workspace-a', 'workspace-b'],
+ const { version, outputs, prefix } = await mockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify(
+ {
+ name: 'workspaces-test',
+ version: '1.0.0',
+ workspaces: ['workspace-a', 'workspace-b'],
+ },
+ null,
+ 2
+ ),
+ 'workspace-a': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-a',
+ version: '1.0.0',
+ }),
+ },
+ 'workspace-b': {
+ 'package.json': JSON.stringify({
+ name: 'workspace-b',
+ version: '1.0.0',
+ }),
},
- null,
- 2
- ),
- 'workspace-a': {
- 'package.json': JSON.stringify({
- name: 'workspace-a',
- version: '1.0.0',
- }),
},
- 'workspace-b': {
- 'package.json': JSON.stringify({
- name: 'workspace-b',
- version: '1.0.0',
- }),
+ mocks: {
+ libnpmversion: (arg, opts) => {
+ return '2.0.0'
+ },
},
- })
- const Version = t.mock('../../../lib/commands/version.js', {
- ...mocks,
- libnpmversion: (arg, opts) => {
- libNpmVersionArgs.push([arg, opts])
- return '2.0.0'
+ config: {
+ workspaces: true,
+ 'workspaces-update': false,
},
})
- npm.localPrefix = testDir
- npm.prefix = testDir
- const version = new Version(npm)
- await version.execWorkspaces(['major'], [])
+ await version.exec(['major'])
t.same(
- result,
+ outputs.map(o => o[0]).slice(0, 4),
['workspace-a', 'v2.0.0', 'workspace-b', 'v2.0.0'],
'outputs the new version for only the workspaces prefixed by the tagVersionPrefix'
)
t.throws(
- () => statSync(resolve(testDir, 'package-lock.json')),
+ () => statSync(resolve(prefix, 'package-lock.json')),
'should not have a lockfile since have not reified'
)
})
})
-
- t.end()
})
diff --git a/deps/npm/test/lib/commands/view.js b/deps/npm/test/lib/commands/view.js
index d347bc9230..c6a4bf8fb7 100644
--- a/deps/npm/test/lib/commands/view.js
+++ b/deps/npm/test/lib/commands/view.js
@@ -262,93 +262,88 @@ const packument = (nv, opts) => {
}
const loadMockNpm = async function (t, opts = {}) {
- const consoleLogs = []
const mockNpm = await _loadMockNpm(t, {
+ command: 'view',
mocks: {
pacote: {
packument,
},
},
- globals: {
- 'console.log': (...args) => {
- consoleLogs.push(args)
- },
- },
...opts,
})
- return { ...mockNpm, consoleLogs }
+ return mockNpm
}
t.test('package from git', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['https://github.com/npm/green'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['https://github.com/npm/green'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('deprecated package with license, bugs, repository and other fields', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['green@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['green@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('deprecated package with unicode', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: true } })
- await npm.exec('view', ['green@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: true } })
+ await view.exec(['green@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with more than 25 deps', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['black@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['black@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with maintainers info as object', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['pink@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['pink@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with homepage', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['orange@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['orange@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with no versions', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['brown'])
- t.equal(consoleLogs.join('\n'), '', 'no info to display')
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['brown'])
+ t.equal(outputs.join('\n'), '', 'no info to display')
})
t.test('package with no repo or homepage', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['blue@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['blue@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with semver range', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['blue@^1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['blue@^1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with no modified time', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { unicode: false } })
- await npm.exec('view', ['cyan@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { unicode: false } })
+ await view.exec(['cyan@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with --json and semver range', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { json: true } })
- await npm.exec('view', ['cyan@^1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { config: { json: true } })
+ await view.exec(['cyan@^1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('package with --json and no versions', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { config: { json: true } })
- await npm.exec('view', ['brown'])
- t.equal(consoleLogs.join('\n'), '', 'no info to display')
+ const { view, outputs } = await loadMockNpm(t, { config: { json: true } })
+ await view.exec(['brown'])
+ t.equal(outputs.join('\n'), '', 'no info to display')
})
t.test('package in cwd', async t => {
@@ -360,72 +355,71 @@ t.test('package in cwd', async t => {
}
t.test('specific version', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir })
- await npm.exec('view', ['.@1.0.0'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { prefixDir })
+ await view.exec(['.@1.0.0'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('non-specific version', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir })
- await npm.exec('view', ['.'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { prefixDir })
+ await view.exec(['.'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('directory', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, { prefixDir })
- await npm.exec('view', ['./blue'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ const { view, outputs } = await loadMockNpm(t, { prefixDir })
+ await view.exec(['./blue'])
+ t.matchSnapshot(outputs.join('\n'))
})
})
t.test('specific field names', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t)
- t.afterEach(() => {
- consoleLogs.length = 0
- })
+ const { view, outputs } = await loadMockNpm(t)
+ t.afterEach(() => outputs.length = 0)
+
t.test('readme', async t => {
- await npm.exec('view', ['yellow@1.0.0', 'readme'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['yellow@1.0.0', 'readme'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('several fields', async t => {
- await npm.exec('view', ['yellow@1.0.0', 'name', 'version', 'foo[bar]'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['yellow@1.0.0', 'name', 'version', 'foo[bar]'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('several fields with several versions', async t => {
- await npm.exec('view', ['yellow@1.x.x', 'author'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['yellow@1.x.x', 'author'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('nested field with brackets', async t => {
- await npm.exec('view', ['orange@1.0.0', 'dist[shasum]'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['orange@1.0.0', 'dist[shasum]'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('maintainers with email', async t => {
- await npm.exec('view', ['yellow@1.0.0', 'maintainers', 'name'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['yellow@1.0.0', 'maintainers', 'name'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('maintainers with url', async t => {
- await npm.exec('view', ['pink@1.0.0', 'maintainers'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['pink@1.0.0', 'maintainers'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('unknown nested field ', async t => {
- await npm.exec('view', ['yellow@1.0.0', 'dist.foobar'])
- t.equal(consoleLogs.join('\n'), '', 'no info to display')
+ await view.exec(['yellow@1.0.0', 'dist.foobar'])
+ t.equal(outputs.join('\n'), '', 'no info to display')
})
t.test('array field - 1 element', async t => {
- await npm.exec('view', ['purple@1.0.0', 'maintainers.name'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['purple@1.0.0', 'maintainers.name'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('array field - 2 elements', async t => {
- await npm.exec('view', ['yellow@1.x.x', 'maintainers.name'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['yellow@1.x.x', 'maintainers.name'])
+ t.matchSnapshot(outputs.join('\n'))
})
})
@@ -495,84 +489,84 @@ t.test('workspaces', async t => {
}
t.test('all workspaces', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true },
})
- await npm.exec('view', [])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec([])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('one specific workspace', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspace: ['green'] },
})
- await npm.exec('view', [])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec([])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('all workspaces --json', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true, json: true },
})
- await npm.exec('view', [])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec([])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('all workspaces single field', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true },
})
- await npm.exec('view', ['.', 'name'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['.', 'name'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('all workspaces nonexistent field', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true },
})
- await npm.exec('view', ['.', 'foo'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['.', 'foo'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('all workspaces nonexistent field --json', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true, json: true },
})
- await npm.exec('view', ['.', 'foo'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['.', 'foo'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('all workspaces single field --json', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true, json: true },
})
- await npm.exec('view', ['.', 'name'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['.', 'name'])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('single workspace --json', async t => {
- const { npm, consoleLogs } = await loadMockNpm(t, {
+ const { view, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspace: ['green'], json: true },
})
- await npm.exec('view', [])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec([])
+ t.matchSnapshot(outputs.join('\n'))
})
t.test('remote package name', async t => {
- const { npm, logs, consoleLogs } = await loadMockNpm(t, {
+ const { view, logs, outputs } = await loadMockNpm(t, {
prefixDir,
config: { unicode: false, workspaces: true },
})
- await npm.exec('view', ['pink'])
- t.matchSnapshot(consoleLogs.join('\n'))
+ await view.exec(['pink'])
+ t.matchSnapshot(outputs.join('\n'))
t.matchSnapshot(logs.warn, 'should have warning of ignoring workspaces')
})
})
diff --git a/deps/npm/test/lib/docs.js b/deps/npm/test/lib/docs.js
index 166651f602..e8a188b6ad 100644
--- a/deps/npm/test/lib/docs.js
+++ b/deps/npm/test/lib/docs.js
@@ -41,7 +41,7 @@ t.test('basic usage', async t => {
// are generated in the following test
const { npm } = await loadMockNpm(t, {
mocks: {
- '../../lib/utils/cmd-list.js': { commands: [] },
+ '{LIB}/utils/cmd-list.js': { commands: [] },
},
})
diff --git a/deps/npm/test/lib/fixtures/mock-globals.js b/deps/npm/test/lib/fixtures/mock-globals.js
index 02566e575a..55418dd8e1 100644
--- a/deps/npm/test/lib/fixtures/mock-globals.js
+++ b/deps/npm/test/lib/fixtures/mock-globals.js
@@ -1,6 +1,7 @@
const t = require('tap')
const mockGlobals = require('../../fixtures/mock-globals')
+/* eslint-disable no-console */
const originals = {
platform: process.platform,
error: console.error,
@@ -28,6 +29,7 @@ t.test('console', async t => {
t.equal(console.error, originals.error)
})
+/* eslint-enable no-console */
t.test('platform', async (t) => {
t.equal(process.platform, originals.platform)
@@ -235,6 +237,14 @@ t.test('replace', async (t) => {
t.strictSame(process.env, originals.env)
})
+t.test('dot key', async t => {
+ const dotKey = 'this.is.a.single.key'
+ mockGlobals(t, {
+ [`process.env."${dotKey}"`]: 'value',
+ })
+ t.strictSame(process.env[dotKey], 'value')
+})
+
t.test('multiple mocks and resets', async (t) => {
const initial = 'a'
const platforms = ['b', 'c', 'd', 'e', 'f', 'g']
@@ -299,11 +309,11 @@ t.test('multiple mocks and resets', async (t) => {
await t.test('platforms', async (t) => {
const resets = platforms.map((p) => {
- const { teardown, reset } = mockGlobals(t, { 'process.platform': p })
+ const { teardown: nestedTeardown, reset } = mockGlobals(t, { 'process.platform': p })
t.equal(process.platform, p)
return [
reset['process.platform'],
- teardown,
+ nestedTeardown,
]
})
diff --git a/deps/npm/test/lib/lifecycle-cmd.js b/deps/npm/test/lib/lifecycle-cmd.js
index 22011197ea..c2701931ca 100644
--- a/deps/npm/test/lib/lifecycle-cmd.js
+++ b/deps/npm/test/lib/lifecycle-cmd.js
@@ -1,31 +1,32 @@
const t = require('tap')
+const mockNpm = require('../fixtures/mock-npm')
const LifecycleCmd = require('../../lib/lifecycle-cmd.js')
-let runArgs = null
-const npm = {
- exec: async (cmd, args) => {
+
+t.test('create a lifecycle command', async t => {
+ let runArgs = null
+ const { npm } = await mockNpm(t)
+ npm.exec = async (cmd, args) => {
if (cmd === 'run-script') {
runArgs = args
return 'called the right thing'
}
- },
- config: {
- validate: () => {},
- },
-}
-t.test('create a lifecycle command', async t => {
- t.plan(5)
+ }
+
class TestStage extends LifecycleCmd {
static get name () {
return 'test-stage'
}
}
+
const cmd = new TestStage(npm)
t.match(cmd.usage, /test-stage/)
+
let result
result = await cmd.exec(['some', 'args'])
t.same(runArgs, ['test-stage', 'some', 'args'])
t.strictSame(result, 'called the right thing')
- result = await cmd.execWorkspaces(['some', 'args'], [])
+
+ result = await cmd.execWorkspaces(['some', 'args'])
t.same(runArgs, ['test-stage', 'some', 'args'])
t.strictSame(result, 'called the right thing')
})
diff --git a/deps/npm/test/lib/load-all-commands.js b/deps/npm/test/lib/load-all-commands.js
index aaf6a69c27..dd55560369 100644
--- a/deps/npm/test/lib/load-all-commands.js
+++ b/deps/npm/test/lib/load-all-commands.js
@@ -7,28 +7,41 @@ const util = require('util')
const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
const { allCommands } = require('../../lib/utils/cmd-list.js')
+const isAsyncFn = (v) => typeof v === 'function' && /^\[AsyncFunction:/.test(util.inspect(v))
+
t.test('load each command', async t => {
for (const cmd of allCommands) {
t.test(cmd, async t => {
- const { npm, outputs } = await loadMockNpm(t, {
+ const { npm, outputs, cmd: impl } = await loadMockNpm(t, {
+ command: cmd,
config: { usage: true },
})
- const impl = await npm.cmd(cmd)
+ const ctor = impl.constructor
+
if (impl.completion) {
t.type(impl.completion, 'function', 'completion, if present, is a function')
}
- t.type(impl.exec, 'function', 'implementation has an exec function')
- t.type(impl.execWorkspaces, 'function', 'implementation has an execWorkspaces function')
- t.equal(util.inspect(impl.exec), '[AsyncFunction: exec]', 'exec function is async')
- t.equal(
- util.inspect(impl.execWorkspaces),
- '[AsyncFunction: execWorkspaces]',
- 'execWorkspaces function is async'
- )
+
+ // exec fn
+ t.ok(isAsyncFn(impl.exec), 'exec is async')
+ t.ok(impl.exec.length <= 1, 'exec fn has 0 or 1 args')
+
+ // workspaces
+ t.type(ctor.ignoreImplicitWorkspace, 'boolean', 'ctor has ignoreImplictWorkspace boolean')
+ t.type(ctor.workspaces, 'boolean', 'ctor has workspaces boolean')
+ if (ctor.workspaces) {
+ t.ok(isAsyncFn(impl.execWorkspaces), 'execWorkspaces is async')
+ t.ok(impl.exec.length <= 1, 'execWorkspaces fn has 0 or 1 args')
+ } else {
+ t.notOk(impl.execWorkspaces, 'has no execWorkspaces fn')
+ }
+
+ // name/desc
t.ok(impl.description, 'implementation has a description')
t.ok(impl.name, 'implementation has a name')
t.equal(cmd, impl.name, 'command list and name are the same')
- t.ok(impl.ignoreImplicitWorkspace !== undefined, 'implementation has ignoreImplictWorkspace')
+
+ // usage
t.match(impl.usage, cmd, 'usage contains the command')
await npm.exec(cmd, [])
t.match(outputs[0][0], impl.usage, 'usage is what is output')
diff --git a/deps/npm/test/lib/npm.js b/deps/npm/test/lib/npm.js
index f850ff6aff..e6936b3e36 100644
--- a/deps/npm/test/lib/npm.js
+++ b/deps/npm/test/lib/npm.js
@@ -1,39 +1,10 @@
const t = require('tap')
const { resolve, dirname, join } = require('path')
const fs = require('fs')
-
const { load: loadMockNpm } = require('../fixtures/mock-npm.js')
const mockGlobals = require('../fixtures/mock-globals')
const { commands } = require('../../lib/utils/cmd-list.js')
-// delete this so that we don't have configs from the fact that it
-// is being run by 'npm test'
-const event = process.env.npm_lifecycle_event
-
-for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
- if (env === 'npm_command') {
- // should only be running this in the 'test' or 'run-script' command!
- // if the lifecycle event is 'test', then it'll be either 'test' or 'run',
- // otherwise it should always be run-script. Of course, it'll be missing
- // if this test is just run directly, which is also acceptable.
- if (event === 'test') {
- t.ok(
- ['test', 'run-script'].some(i => i === process.env[env]),
- 'should match "npm test" or "npm run test"'
- )
- } else {
- t.match(process.env[env], /^(run-script|exec)$/)
- }
- }
- delete process.env[env]
-}
-
-t.afterEach(async (t) => {
- for (const env of Object.keys(process.env).filter(e => /^npm_/.test(e))) {
- delete process.env[env]
- }
-})
-
t.test('not yet loaded', async t => {
const { npm, logs } = await loadMockNpm(t, { load: false })
t.match(npm, {
@@ -160,8 +131,8 @@ t.test('npm.load', async t => {
prefixDir: {
bin: t.fixture('symlink', dirname(process.execPath)),
},
- globals: ({ prefix }) => ({
- 'process.env.PATH': resolve(prefix, 'bin'),
+ globals: (dirs) => ({
+ 'process.env.PATH': resolve(dirs.prefix, 'bin'),
'process.argv': [
node,
process.argv[1],
@@ -299,9 +270,6 @@ t.test('npm.load', async t => {
},
})
- // verify that calling the command with a short name still sets
- // the npm.command property to the full canonical name of the cmd.
- npm.command = null
await npm.exec('run', [])
t.equal(npm.command, 'run-script', 'npm.command set to canonical name')
@@ -357,9 +325,7 @@ t.test('npm.load', async t => {
],
},
})
- // verify that calling the command with a short name still sets
- // the npm.command property to the full canonical name of the cmd.
- npm.command = null
+
await t.rejects(
npm.exec('run', []),
/Workspaces not supported for global packages/
@@ -441,9 +407,9 @@ t.test('debug log', async t => {
t.test('can load with bad dir', async t => {
const { npm, testdir } = await loadMockNpm(t, {
load: false,
- config: {
- 'logs-dir': (c) => join(c.testdir, 'my_logs_dir'),
- },
+ config: (dirs) => ({
+ 'logs-dir': join(dirs.testdir, 'my_logs_dir'),
+ }),
})
const logsDir = join(testdir, 'my_logs_dir')
@@ -648,15 +614,15 @@ t.test('implicit workspace rejection', async t => {
workspaces: ['./packages/a'],
}),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => join(prefix, 'packages', 'a'),
+ chdir: ({ prefix }) => join(prefix, 'packages', 'a'),
+ globals: {
'process.argv': [
process.execPath,
process.argv[1],
'--color', 'false',
'--workspace', './packages/a',
],
- }),
+ },
})
await t.rejects(
mock.npm.exec('team', []),
@@ -682,14 +648,14 @@ t.test('implicit workspace accept', async t => {
workspaces: ['./packages/a'],
}),
},
- globals: ({ prefix }) => ({
- 'process.cwd': () => join(prefix, 'packages', 'a'),
+ chdir: ({ prefix }) => join(prefix, 'packages', 'a'),
+ globals: {
'process.argv': [
process.execPath,
process.argv[1],
'--color', 'false',
],
- }),
+ },
})
await t.rejects(mock.npm.exec('org', []), /.*Usage/)
})
diff --git a/deps/npm/test/lib/utils/audit-error.js b/deps/npm/test/lib/utils/audit-error.js
index bcb7d8c16d..46a9dbc38c 100644
--- a/deps/npm/test/lib/utils/audit-error.js
+++ b/deps/npm/test/lib/utils/audit-error.js
@@ -1,36 +1,44 @@
const t = require('tap')
+const mockLogs = require('../../fixtures/mock-logs')
+const mockNpm = require('../../fixtures/mock-npm')
+const tmock = require('../../fixtures/tmock')
-const LOGS = []
-const OUTPUT = []
-const output = (...msg) => OUTPUT.push(msg)
-const auditError = t.mock('../../../lib/utils/audit-error.js', {
- 'proc-log': {
- warn: (...msg) => LOGS.push(msg),
- },
-})
+const auditError = async (t, { command, error, ...config } = {}) => {
+ const { logs, logMocks } = mockLogs()
+ const mockAuditError = tmock(t, '{LIB}/utils/audit-error', logMocks)
+
+ const mock = await mockNpm(t, {
+ command,
+ config,
+ })
-const npm = {
- command: null,
- flatOptions: {},
- output,
+ const res = {}
+ try {
+ res.result = mockAuditError(mock.npm, error ? { error } : {})
+ } catch (err) {
+ res.error = err
+ }
+
+ return {
+ ...res,
+ logs: logs.warn.filter((l) => l[0] === 'audit'),
+ output: mock.joinedOutput(),
+ }
}
-t.afterEach(() => {
- npm.flatOptions = {}
- OUTPUT.length = 0
- LOGS.length = 0
-})
-t.test('no error, not audit command', t => {
- npm.command = 'install'
- t.equal(auditError(npm, {}), false, 'no error')
- t.strictSame(OUTPUT, [], 'no output')
- t.strictSame(LOGS, [], 'no warnings')
- t.end()
+t.test('no error, not audit command', async t => {
+ const { result, error, logs, output } = await auditError(t, { command: 'install' })
+
+ t.equal(result, false, 'no error')
+ t.notOk(error, 'no error')
+
+ t.strictSame(output, '', 'no output')
+ t.strictSame(logs, [], 'no warnings')
})
-t.test('error, not audit command', t => {
- npm.command = 'install'
- t.equal(auditError(npm, {
+t.test('error, not audit command', async t => {
+ const { result, error, logs, output } = await auditError(t, {
+ command: 'install',
error: {
message: 'message',
body: Buffer.from('body'),
@@ -41,16 +49,17 @@ t.test('error, not audit command', t => {
},
statusCode: '420',
},
- }), true, 'had error')
- t.strictSame(OUTPUT, [], 'no output')
- t.strictSame(LOGS, [], 'no warnings')
- t.end()
+ })
+
+ t.equal(result, true, 'had error')
+ t.notOk(error, 'no error')
+ t.strictSame(output, '', 'no output')
+ t.strictSame(logs, [], 'no warnings')
})
-t.test('error, audit command, not json', t => {
- npm.command = 'audit'
- npm.flatOptions.json = false
- t.throws(() => auditError(npm, {
+t.test('error, audit command, not json', async t => {
+ const { result, error, logs, output } = await auditError(t, {
+ command: 'audit',
error: {
message: 'message',
body: Buffer.from('body'),
@@ -61,17 +70,19 @@ t.test('error, audit command, not json', t => {
},
statusCode: '420',
},
- }))
+ })
+
+ t.equal(result, undefined)
- t.strictSame(OUTPUT, [['body']], 'some output')
- t.strictSame(LOGS, [['audit', 'message']], 'some warnings')
- t.end()
+ t.ok(error, 'throws error')
+ t.strictSame(output, 'body', 'some output')
+ t.strictSame(logs, [['audit', 'message']], 'some warnings')
})
-t.test('error, audit command, json', t => {
- npm.command = 'audit'
- npm.flatOptions.json = true
- t.throws(() => auditError(npm, {
+t.test('error, audit command, json', async t => {
+ const { result, error, logs, output } = await auditError(t, {
+ json: true,
+ command: 'audit',
error: {
message: 'message',
body: { response: 'body' },
@@ -82,26 +93,25 @@ t.test('error, audit command, json', t => {
},
statusCode: '420',
},
- }))
+ })
- t.strictSame(OUTPUT, [
- [
- '{\n' +
- ' "message": "message",\n' +
- ' "method": "POST",\n' +
- ' "uri": "https://example.com/not/a/registry",\n' +
- ' "headers": {\n' +
- ' "head": [\n' +
- ' "ers"\n' +
- ' ]\n' +
- ' },\n' +
- ' "statusCode": "420",\n' +
- ' "body": {\n' +
- ' "response": "body"\n' +
- ' }\n' +
- '}',
- ],
- ], 'some output')
- t.strictSame(LOGS, [['audit', 'message']], 'some warnings')
- t.end()
+ t.equal(result, undefined)
+ t.ok(error, 'throws error')
+ t.strictSame(output,
+ '{\n' +
+ ' "message": "message",\n' +
+ ' "method": "POST",\n' +
+ ' "uri": "https://example.com/not/a/registry",\n' +
+ ' "headers": {\n' +
+ ' "head": [\n' +
+ ' "ers"\n' +
+ ' ]\n' +
+ ' },\n' +
+ ' "statusCode": "420",\n' +
+ ' "body": {\n' +
+ ' "response": "body"\n' +
+ ' }\n' +
+ '}'
+ , 'some output')
+ t.strictSame(logs, [['audit', 'message']], 'some warnings')
})
diff --git a/deps/npm/test/lib/utils/completion/installed-deep.js b/deps/npm/test/lib/utils/completion/installed-deep.js
index f0e36faee1..fa39f0f073 100644
--- a/deps/npm/test/lib/utils/completion/installed-deep.js
+++ b/deps/npm/test/lib/utils/completion/installed-deep.js
@@ -1,5 +1,6 @@
const { resolve } = require('path')
const t = require('tap')
+const installedDeep = require('../../../../lib/utils/completion/installed-deep.js')
let prefix
let globalDir = 'MISSING_GLOBAL_DIR'
@@ -11,8 +12,6 @@ const _flatOptions = {
return prefix
},
}
-const p = '../../../../lib/utils/completion/installed-deep.js'
-const installedDeep = require(p)
const npm = {
flatOptions: _flatOptions,
get prefix () {
diff --git a/deps/npm/test/lib/utils/completion/installed-shallow.js b/deps/npm/test/lib/utils/completion/installed-shallow.js
index 1445cbf2ff..5a65b6b6bf 100644
--- a/deps/npm/test/lib/utils/completion/installed-shallow.js
+++ b/deps/npm/test/lib/utils/completion/installed-shallow.js
@@ -1,10 +1,9 @@
-const flatOptions = { global: false }
-const npm = { flatOptions }
const t = require('tap')
const { resolve } = require('path')
+const installed = require('../../../../lib/utils/completion/installed-shallow.js')
-const p = '../../../../lib/utils/completion/installed-shallow.js'
-const installed = require(p)
+const flatOptions = { global: false }
+const npm = { flatOptions }
t.test('global not set, include globals with -g', async t => {
const dir = t.testdir({
diff --git a/deps/npm/test/lib/utils/config/definitions.js b/deps/npm/test/lib/utils/config/definitions.js
index dca584e104..288166039b 100644
--- a/deps/npm/test/lib/utils/config/definitions.js
+++ b/deps/npm/test/lib/utils/config/definitions.js
@@ -1,14 +1,15 @@
const t = require('tap')
const { resolve } = require('path')
const mockGlobals = require('../../../fixtures/mock-globals')
+const tmock = require('../../../fixtures/tmock')
const pkg = require('../../../../package.json')
// have to fake the node version, or else it'll only pass on this one
mockGlobals(t, { 'process.version': 'v14.8.0', 'process.env.NODE_ENV': undefined })
-const mockDefs = (mocks = {}) => t.mock('../../../../lib/utils/config/definitions.js', mocks)
+const mockDefs = (mocks = {}) => tmock(t, '{LIB}/utils/config/definitions.js', mocks)
-const isWin = (isWindows) => ({ '../../../../lib/utils/is-windows.js': { isWindows } })
+const isWin = (isWindows) => ({ '{LIB}/utils/is-windows.js': { isWindows } })
t.test('basic flattening function camelCases from css-case', t => {
const flat = {}
@@ -930,3 +931,12 @@ t.test('remap global-style', t => {
t.strictSame(flat, { installStrategy: 'shallow' })
t.end()
})
+
+t.test('otp changes auth-type', t => {
+ const obj = { 'auth-type': 'web', otp: 123456 }
+ const flat = {}
+ mockDefs().otp.flatten('otp', obj, flat)
+ t.strictSame(flat, { authType: 'legacy', otp: 123456 })
+ t.strictSame(obj, { 'auth-type': 'legacy', otp: 123456 })
+ t.end()
+})
diff --git a/deps/npm/test/lib/utils/display.js b/deps/npm/test/lib/utils/display.js
index c7332bce8e..cfe0181e23 100644
--- a/deps/npm/test/lib/utils/display.js
+++ b/deps/npm/test/lib/utils/display.js
@@ -2,10 +2,11 @@ const t = require('tap')
const log = require('../../../lib/utils/log-shim')
const mockLogs = require('../../fixtures/mock-logs')
const mockGlobals = require('../../fixtures/mock-globals')
+const tmock = require('../../fixtures/tmock')
const mockDisplay = (t, mocks) => {
const { logs, logMocks } = mockLogs(mocks)
- const Display = t.mock('../../../lib/utils/display', {
+ const Display = tmock(t, '{LIB}/utils/display', {
...mocks,
...logMocks,
})
@@ -44,7 +45,7 @@ t.test('can log', async (t) => {
error: (...args) => logs.push(['error', ...args]),
warn: (...args) => logs.push(['warn', ...args]),
},
- '../../../lib/utils/explain-eresolve.js': {
+ '{LIB}/utils/explain-eresolve.js': {
explain: (...args) => {
explains.push(args)
return 'explanation'
@@ -71,7 +72,7 @@ t.test('handles log throwing', async (t) => {
throw new Error('verbose')
},
},
- '../../../lib/utils/explain-eresolve.js': {
+ '{LIB}/utils/explain-eresolve.js': {
explain: () => {
throw new Error('explain')
},
diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js
index 29753c3039..9d07693989 100644
--- a/deps/npm/test/lib/utils/error-message.js
+++ b/deps/npm/test/lib/utils/error-message.js
@@ -1,13 +1,18 @@
const t = require('tap')
-const path = require('path')
+const { resolve } = require('path')
+const fs = require('fs/promises')
const { load: _loadMockNpm } = require('../../fixtures/mock-npm.js')
const mockGlobals = require('../../fixtures/mock-globals.js')
+const tmock = require('../../fixtures/tmock')
const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot.js')
t.formatSnapshot = (p) => {
if (Array.isArray(p.files) && !p.files.length) {
delete p.files
}
+ if (p?.json === undefined) {
+ delete p.json
+ }
return p
}
t.cleanSnapshot = p => cleanDate(cleanCwd(p))
@@ -22,35 +27,26 @@ mockGlobals(t, {
},
})
-const loadMockNpm = async (t, { load, command, prefixDir, config } = {}) => {
- const { npm, ...rest } = await _loadMockNpm(t, {
- load,
- prefixDir,
- config,
+const loadMockNpm = async (t, { errorMocks, ...opts } = {}) => {
+ const mockError = tmock(t, '{LIB}/utils/error-message.js', errorMocks)
+ const res = await _loadMockNpm(t, {
+ ...opts,
mocks: {
- '../../package.json': {
+ ...opts.mocks,
+ '{ROOT}/package.json': {
version: '123.456.789-npm',
},
},
})
- if (command !== undefined) {
- npm.command = command
- }
return {
- npm,
- ...rest,
+ ...res,
+ errorMessage: (er) => mockError(er, res.npm),
}
}
-const errorMessage = (er, { mocks, logMocks, npm } = {}) =>
- t.mock('../../../lib/utils/error-message.js', { ...mocks, ...logMocks })(er, npm)
-
t.test('just simple messages', async t => {
- const npm = await loadMockNpm(t, {
+ const { errorMessage } = await loadMockNpm(t, {
command: 'audit',
- config: {
- 'node-version': '99.99.99',
- },
})
const codes = [
'ENOAUDIT',
@@ -77,8 +73,7 @@ t.test('just simple messages', async t => {
'E403',
'ERR_SOCKET_TIMEOUT',
]
- t.plan(codes.length)
- codes.forEach(async code => {
+ for (const code of codes) {
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -90,12 +85,12 @@ t.test('just simple messages', async t => {
file,
stack,
})
- t.matchSnapshot(errorMessage(er, npm))
- })
+ t.matchSnapshot(errorMessage(er))
+ }
})
t.test('replace message/stack sensistive info', async t => {
- const npm = await loadMockNpm(t, { command: 'audit' })
+ const { errorMessage } = await loadMockNpm(t, { command: 'audit' })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -108,11 +103,11 @@ t.test('replace message/stack sensistive info', async t => {
file,
stack,
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
})
t.test('bad engine without config loaded', async t => {
- const npm = await loadMockNpm(t, { load: false })
+ const { errorMessage } = await loadMockNpm(t, { load: false })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -124,11 +119,11 @@ t.test('bad engine without config loaded', async t => {
file,
stack,
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
})
t.test('enoent without a file', async t => {
- const npm = await loadMockNpm(t)
+ const { errorMessage } = await loadMockNpm(t)
const path = '/some/path'
const pkgid = 'some@package'
const stack = 'dummy stack trace'
@@ -138,11 +133,11 @@ t.test('enoent without a file', async t => {
pkgid,
stack,
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
})
t.test('enolock without a command', async t => {
- const npm = await loadMockNpm(t, { command: null })
+ const { errorMessage } = await loadMockNpm(t, { command: null })
const path = '/some/path'
const pkgid = 'some@package'
const file = '/some/file'
@@ -154,41 +149,43 @@ t.test('enolock without a command', async t => {
file,
stack,
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
})
t.test('default message', async t => {
- const npm = await loadMockNpm(t)
- t.matchSnapshot(errorMessage(new Error('error object'), npm))
- t.matchSnapshot(errorMessage('error string', npm))
+ const { errorMessage } = await loadMockNpm(t)
+ t.matchSnapshot(errorMessage(new Error('error object')))
+ t.matchSnapshot(errorMessage('error string'))
t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), {
cmd: 'some command',
signal: 'SIGYOLO',
args: ['a', 'r', 'g', 's'],
stdout: 'stdout',
stderr: 'stderr',
- }), npm))
+ })))
})
t.test('args are cleaned', async t => {
- const npm = await loadMockNpm(t)
+ const { errorMessage } = await loadMockNpm(t)
t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), {
cmd: 'some command',
signal: 'SIGYOLO',
args: ['a', 'r', 'g', 's', 'https://evil:password@npmjs.org'],
stdout: 'stdout',
stderr: 'stderr',
- }), npm))
+ })))
})
t.test('eacces/eperm', async t => {
const runTest = (windows, loaded, cachePath, cacheDest) => async t => {
- if (windows) {
- mockGlobals(t, { 'process.platform': 'win32' })
- }
- const npm = await loadMockNpm(t, { windows, load: loaded })
- const path = `${cachePath ? npm.cache : '/not/cache/dir'}/path`
- const dest = `${cacheDest ? npm.cache : '/not/cache/dir'}/dest`
+ const { errorMessage, logs, cache } = await loadMockNpm(t, {
+ windows,
+ load: loaded,
+ globals: windows ? { 'process.platform': 'win32' } : [],
+ })
+
+ const path = `${cachePath ? cache : '/not/cache/dir'}/path`
+ const dest = `${cacheDest ? cache : '/not/cache/dir'}/dest`
const er = Object.assign(new Error('whoopsie'), {
code: 'EACCES',
path,
@@ -196,8 +193,8 @@ t.test('eacces/eperm', async t => {
stack: 'dummy stack trace',
})
- t.matchSnapshot(errorMessage(er, npm))
- t.matchSnapshot(npm.logs.verbose)
+ t.matchSnapshot(errorMessage(er))
+ t.matchSnapshot(logs.verbose)
}
for (const windows of [true, false]) {
@@ -217,50 +214,14 @@ t.test('json parse', t => {
t.test('merge conflict in package.json', async t => {
const prefixDir = {
- 'package.json': `
-{
- "array": [
-<<<<<<< HEAD
- 100,
- {
- "foo": "baz"
- },
-||||||| merged common ancestors
- 1,
-=======
- 111,
- 1,
- 2,
- 3,
- {
- "foo": "bar"
- },
->>>>>>> a
- 1
- ],
- "a": {
- "b": {
-<<<<<<< HEAD
- "c": {
- "x": "bbbb"
- }
-||||||| merged common ancestors
- "c": {
- "x": "aaaa"
- }
-=======
- "c": "xxxx"
->>>>>>> a
+ 'package.json': await fs.readFile(
+ resolve(__dirname, '../../fixtures/merge-conflict.json'), 'utf-8'),
}
- }
-}
-`,
- }
- const npm = await loadMockNpm(t, { prefixDir })
+ const { errorMessage, npm } = await loadMockNpm(t, { prefixDir })
t.matchSnapshot(errorMessage(Object.assign(new Error('conflicted'), {
code: 'EJSONPARSE',
- path: path.resolve(npm.prefix, 'package.json'),
- }), npm))
+ path: resolve(npm.prefix, 'package.json'),
+ })))
t.end()
})
@@ -268,11 +229,11 @@ t.test('json parse', t => {
const prefixDir = {
'package.json': 'not even slightly json',
}
- const npm = await loadMockNpm(t, { prefixDir })
+ const { errorMessage, npm } = await loadMockNpm(t, { prefixDir })
t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), {
code: 'EJSONPARSE',
- path: path.resolve(npm.prefix, 'package.json'),
- }), npm))
+ path: resolve(npm.prefix, 'package.json'),
+ })))
t.end()
})
@@ -280,11 +241,11 @@ t.test('json parse', t => {
const prefixDir = {
'blerg.json': 'not even slightly json',
}
- const npm = await loadMockNpm(t, { prefixDir })
+ const { npm, errorMessage } = await loadMockNpm(t, { prefixDir })
t.matchSnapshot(errorMessage(Object.assign(new Error('not json'), {
code: 'EJSONPARSE',
- path: path.resolve(npm.prefix, 'blerg.json'),
- }), npm))
+ path: resolve(npm.prefix, 'blerg.json'),
+ })))
t.end()
})
@@ -292,26 +253,26 @@ t.test('json parse', t => {
})
t.test('eotp/e401', async t => {
- const npm = await loadMockNpm(t)
+ const { errorMessage } = await loadMockNpm(t)
t.test('401, no auth headers', t => {
t.matchSnapshot(errorMessage(Object.assign(new Error('nope'), {
code: 'E401',
- }), npm))
+ })))
t.end()
})
t.test('401, no message', t => {
t.matchSnapshot(errorMessage({
code: 'E401',
- }, npm))
+ }))
t.end()
})
t.test('one-time pass challenge code', t => {
t.matchSnapshot(errorMessage(Object.assign(new Error('nope'), {
code: 'EOTP',
- }), npm))
+ })))
t.end()
})
@@ -319,7 +280,7 @@ t.test('eotp/e401', async t => {
const message = 'one-time pass'
t.matchSnapshot(errorMessage(Object.assign(new Error(message), {
code: 'E401',
- }), npm))
+ })))
t.end()
})
@@ -339,7 +300,7 @@ t.test('eotp/e401', async t => {
},
code: 'E401',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
}
@@ -347,11 +308,11 @@ t.test('eotp/e401', async t => {
})
t.test('404', async t => {
- const npm = await loadMockNpm(t)
+ const { errorMessage } = await loadMockNpm(t)
t.test('no package id', t => {
const er = Object.assign(new Error('404 not found'), { code: 'E404' })
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
t.test('you should publish it', t => {
@@ -359,7 +320,7 @@ t.test('404', async t => {
pkgid: 'yolo',
code: 'E404',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
t.test('name with warning', t => {
@@ -367,7 +328,7 @@ t.test('404', async t => {
pkgid: new Array(215).fill('x').join(''),
code: 'E404',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
t.test('name with error', t => {
@@ -375,7 +336,7 @@ t.test('404', async t => {
pkgid: 'node_modules',
code: 'E404',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
t.test('cleans sensitive info from package id', t => {
@@ -383,13 +344,13 @@ t.test('404', async t => {
pkgid: 'http://evil:password@npmjs.org/not-found',
code: 'E404',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
})
t.test('bad platform', async t => {
- const npm = await loadMockNpm(t)
+ const { errorMessage } = await loadMockNpm(t)
t.test('string os/arch', t => {
const er = Object.assign(new Error('a bad plat'), {
@@ -404,7 +365,7 @@ t.test('bad platform', async t => {
},
code: 'EBADPLATFORM',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
t.test('array os/arch', t => {
@@ -420,30 +381,29 @@ t.test('bad platform', async t => {
},
code: 'EBADPLATFORM',
})
- t.matchSnapshot(errorMessage(er, npm))
+ t.matchSnapshot(errorMessage(er))
t.end()
})
})
t.test('explain ERESOLVE errors', async t => {
- const { npm, ...rest } = await loadMockNpm(t)
const EXPLAIN_CALLED = []
- const er = Object.assign(new Error('could not resolve'), {
- code: 'ERESOLVE',
- })
-
- t.matchSnapshot(errorMessage(er, {
- npm,
- ...rest,
- mocks: {
- '../../../lib/utils/explain-eresolve.js': {
+ const { errorMessage } = await loadMockNpm(t, {
+ errorMocks: {
+ '{LIB}/utils/explain-eresolve.js': {
report: (...args) => {
EXPLAIN_CALLED.push(args)
return { explanation: 'explanation', file: 'report' }
},
},
},
- }))
+ })
+
+ const er = Object.assign(new Error('could not resolve'), {
+ code: 'ERESOLVE',
+ })
+
+ t.matchSnapshot(errorMessage(er))
t.match(EXPLAIN_CALLED, [[er, false]])
})
diff --git a/deps/npm/test/lib/utils/exit-handler.js b/deps/npm/test/lib/utils/exit-handler.js
index d22ec4dd14..76d5fec4c0 100644
--- a/deps/npm/test/lib/utils/exit-handler.js
+++ b/deps/npm/test/lib/utils/exit-handler.js
@@ -2,12 +2,13 @@ const t = require('tap')
const os = require('os')
const fs = require('fs')
const fsMiniPass = require('fs-minipass')
-const { join } = require('path')
+const { join, resolve } = require('path')
const EventEmitter = require('events')
const { format } = require('../../../lib/utils/log-file')
const { load: loadMockNpm } = require('../../fixtures/mock-npm')
const mockGlobals = require('../../fixtures/mock-globals')
const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot')
+const tmock = require('../../fixtures/tmock')
const pick = (obj, ...keys) => keys.reduce((acc, key) => {
acc[key] = obj[key]
@@ -35,7 +36,8 @@ t.cleanSnapshot = (path) => cleanDate(cleanCwd(path))
// nerf itself, thinking global.process is broken or gone.
mockGlobals(t, {
process: Object.assign(new EventEmitter(), {
- ...pick(process, 'execPath', 'stdout', 'stderr', 'cwd', 'env', 'umask'),
+ // these are process properties that are needed in the running code and tests
+ ...pick(process, 'execPath', 'stdout', 'stderr', 'cwd', 'chdir', 'env', 'umask'),
argv: ['/node', ...process.argv.slice(1)],
version: 'v1.0.0',
kill: () => {},
@@ -56,25 +58,32 @@ const mockExitHandler = async (t, { init, load, testdir, config, mocks, files }
load,
testdir,
mocks: {
- '../../package.json': {
+ '{ROOT}/package.json': {
version: '1.0.0',
},
...mocks,
},
- config: {
+ config: (dirs) => ({
loglevel: 'notice',
- ...config,
- },
+ ...(typeof config === 'function' ? config(dirs) : config),
+ }),
globals: {
'console.error': (err) => errors.push(err),
},
})
- const exitHandler = t.mock('../../../lib/utils/exit-handler.js', {
- '../../../lib/utils/error-message.js': (err) => ({
+ const exitHandler = tmock(t, '{LIB}/utils/exit-handler.js', {
+ '{LIB}/utils/error-message.js': (err) => ({
summary: [['ERR SUMMARY', err.message]],
detail: [['ERR DETAIL', err.message]],
...(files ? { files } : {}),
+ json: {
+ error: {
+ code: err.code,
+ summary: err.message,
+ detail: err.message,
+ },
+ },
}),
os: {
type: () => 'Foo',
@@ -89,7 +98,6 @@ const mockExitHandler = async (t, { init, load, testdir, config, mocks, files }
}
t.teardown(() => {
- delete process.exitCode
process.removeAllListeners('exit')
})
@@ -101,8 +109,8 @@ const mockExitHandler = async (t, { init, load, testdir, config, mocks, files }
// to t.plan() every test to make sure we get process.exit called. Also
// introduce a small artificial delay so the logs are consistently finished
// by the time the exit handler forces process.exit
- exitHandler: (...args) => new Promise(resolve => setTimeout(() => {
- process.once('exit', resolve)
+ exitHandler: (...args) => new Promise(res => setTimeout(() => {
+ process.once('exit', res)
exitHandler(...args)
}, 50)),
}
@@ -338,7 +346,7 @@ t.test('no logs dir', async (t) => {
t.test('timers fail to write', async (t) => {
// we want the fs.writeFileSync in the Timers class to fail
- const mockTimers = t.mock('../../../lib/utils/timers.js', {
+ const mockTimers = tmock(t, '{LIB}/utils/timers.js', {
fs: {
...fs,
writeFileSync: (file, ...rest) => {
@@ -352,13 +360,13 @@ t.test('timers fail to write', async (t) => {
})
const { exitHandler, logs } = await mockExitHandler(t, {
- config: {
- 'logs-dir': 'LOGS_DIR',
+ config: (dirs) => ({
+ 'logs-dir': resolve(dirs.prefix, 'LOGS_DIR'),
timing: true,
- },
+ }),
mocks: {
// note, this is relative to test/fixtures/mock-npm.js not this file
- '../../lib/utils/timers.js': mockTimers,
+ '{LIB}/utils/timers.js': mockTimers,
},
})
@@ -369,7 +377,7 @@ t.test('timers fail to write', async (t) => {
t.test('log files fail to write', async (t) => {
// we want the fsMiniPass.WriteStreamSync in the LogFile class to fail
- const mockLogFile = t.mock('../../../lib/utils/log-file.js', {
+ const mockLogFile = tmock(t, '{LIB}/utils/log-file.js', {
'fs-minipass': {
...fsMiniPass,
WriteStreamSync: (file, ...rest) => {
@@ -381,12 +389,12 @@ t.test('log files fail to write', async (t) => {
})
const { exitHandler, logs } = await mockExitHandler(t, {
- config: {
- 'logs-dir': 'LOGS_DIR',
- },
+ config: (dirs) => ({
+ 'logs-dir': resolve(dirs.prefix, 'LOGS_DIR'),
+ }),
mocks: {
// note, this is relative to test/fixtures/mock-npm.js not this file
- '../../lib/utils/log-file.js': mockLogFile,
+ '{LIB}/utils/log-file.js': mockLogFile,
},
})
@@ -417,9 +425,9 @@ t.test('files from error message', async (t) => {
t.test('files from error message with error', async (t) => {
const { exitHandler, logs } = await mockExitHandler(t, {
- config: {
- 'logs-dir': 'LOGS_DIR',
- },
+ config: (dirs) => ({
+ 'logs-dir': resolve(dirs.prefix, 'LOGS_DIR'),
+ }),
files: [
['error-file.txt', '# error file content'],
],
@@ -587,10 +595,7 @@ t.test('exits uncleanly when only emitting exit event', async (t) => {
t.test('do no fancy handling for shellouts', async t => {
const { exitHandler, npm, logs } = await mockExitHandler(t)
- const exec = await npm.cmd('exec')
-
- npm.command = 'exec'
- npm.commandInstance = exec
+ await npm.cmd('exec')
const loudNoises = () =>
logs.filter(([level]) => ['warn', 'error'].includes(level))
diff --git a/deps/npm/test/lib/utils/explain-dep.js b/deps/npm/test/lib/utils/explain-dep.js
index ed006c01d7..514f28d125 100644
--- a/deps/npm/test/lib/utils/explain-dep.js
+++ b/deps/npm/test/lib/utils/explain-dep.js
@@ -1,16 +1,11 @@
const { resolve } = require('path')
const t = require('tap')
const { explainNode, printNode } = require('../../../lib/utils/explain-dep.js')
+const { cleanCwd } = require('../../fixtures/clean-snapshot')
+
const testdir = t.testdirName
-const redactCwd = (path) => {
- const normalizePath = p => p
- .replace(/\\+/g, '/')
- .replace(/\r\n/g, '\n')
- return normalizePath(path)
- .replace(new RegExp(normalizePath(process.cwd()), 'g'), '{CWD}')
-}
-t.cleanSnapshot = (str) => redactCwd(str)
+t.cleanSnapshot = (str) => cleanCwd(str)
const cases = {
prodDep: {
diff --git a/deps/npm/test/lib/utils/log-file.js b/deps/npm/test/lib/utils/log-file.js
index 4be5231c1c..e134fe8790 100644
--- a/deps/npm/test/lib/utils/log-file.js
+++ b/deps/npm/test/lib/utils/log-file.js
@@ -4,11 +4,11 @@ const fs = _fs.promises
const path = require('path')
const os = require('os')
const fsMiniPass = require('fs-minipass')
-const rimraf = require('rimraf')
+const tmock = require('../../fixtures/tmock')
const LogFile = require('../../../lib/utils/log-file.js')
const { cleanCwd, cleanDate } = require('../../fixtures/clean-snapshot')
-t.cleanSnapshot = (path) => cleanDate(cleanCwd(path))
+t.cleanSnapshot = (s) => cleanDate(cleanCwd(s))
const getId = (d = new Date()) => d.toISOString().replace(/[.:]/g, '_')
const last = arr => arr[arr.length - 1]
@@ -43,7 +43,7 @@ const cleanErr = (message) => {
const loadLogFile = async (t, { buffer = [], mocks, testdir = {}, ...options } = {}) => {
const root = t.testdir(testdir)
- const MockLogFile = t.mock('../../../lib/utils/log-file.js', mocks)
+ const MockLogFile = tmock(t, '{LIB}/utils/log-file.js', mocks)
const logFile = new MockLogFile(Object.keys(options).length ? options : undefined)
buffer.forEach((b) => logFile.log(...b))
@@ -275,12 +275,14 @@ t.test('rimraf error', async t => {
logsMax,
testdir: makeOldLogs(oldLogs),
mocks: {
- rimraf: (...args) => {
- if (count >= 3) {
- throw new Error('bad rimraf')
- }
- count++
- return rimraf(...args)
+ 'fs/promises': {
+ rm: async (...args) => {
+ if (count >= 3) {
+ throw new Error('bad rimraf')
+ }
+ count++
+ return fs.rm(...args)
+ },
},
},
})
diff --git a/deps/npm/test/lib/utils/log-shim.js b/deps/npm/test/lib/utils/log-shim.js
index dee4efbaa4..7c8fb7ce3c 100644
--- a/deps/npm/test/lib/utils/log-shim.js
+++ b/deps/npm/test/lib/utils/log-shim.js
@@ -1,6 +1,7 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
-const makeShim = (mocks) => t.mock('../../../lib/utils/log-shim.js', mocks)
+const makeShim = (mocks) => tmock(t, '{LIB}/utils/log-shim.js', mocks)
const loggers = [
'notice',
diff --git a/deps/npm/test/lib/utils/open-url-prompt.js b/deps/npm/test/lib/utils/open-url-prompt.js
index a18fe85f68..faf2ab3258 100644
--- a/deps/npm/test/lib/utils/open-url-prompt.js
+++ b/deps/npm/test/lib/utils/open-url-prompt.js
@@ -1,6 +1,7 @@
const t = require('tap')
const mockGlobals = require('../../fixtures/mock-globals.js')
const EventEmitter = require('events')
+const tmock = require('../../fixtures/tmock')
const OUTPUT = []
const output = (...args) => OUTPUT.push(args)
@@ -22,14 +23,6 @@ let openerUrl = null
let openerOpts = null
let openerResult = null
-const open = async (url, options) => {
- openerUrl = url
- openerOpts = options
- if (openerResult) {
- throw openerResult
- }
-}
-
let questionShouldResolve = true
let openUrlPromptInterrupted = false
@@ -49,9 +42,15 @@ const readline = {
}),
}
-const openUrlPrompt = t.mock('../../../lib/utils/open-url-prompt.js', {
+const openUrlPrompt = tmock(t, '{LIB}/utils/open-url-prompt.js', {
'@npmcli/promise-spawn': {
- open,
+ open: async (url, options) => {
+ openerUrl = url
+ openerOpts = options
+ if (openerResult) {
+ throw openerResult
+ }
+ },
},
readline,
})
diff --git a/deps/npm/test/lib/utils/open-url.js b/deps/npm/test/lib/utils/open-url.js
index 70afd55033..28a11b3609 100644
--- a/deps/npm/test/lib/utils/open-url.js
+++ b/deps/npm/test/lib/utils/open-url.js
@@ -1,4 +1,5 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
const OUTPUT = []
const output = (...args) => OUTPUT.push(args)
@@ -28,7 +29,7 @@ const open = async (url, options) => {
}
}
-const openUrl = t.mock('../../../lib/utils/open-url.js', {
+const openUrl = tmock(t, '{LIB}/utils/open-url.js', {
'@npmcli/promise-spawn': {
open,
},
diff --git a/deps/npm/test/lib/utils/otplease.js b/deps/npm/test/lib/utils/otplease.js
index 79eaa798e6..d788c39da8 100644
--- a/deps/npm/test/lib/utils/otplease.js
+++ b/deps/npm/test/lib/utils/otplease.js
@@ -1,74 +1,74 @@
const t = require('tap')
+const setupMockNpm = require('../../fixtures/mock-npm')
+const tmock = require('../../fixtures/tmock')
-const { fake: mockNpm } = require('../../fixtures/mock-npm')
-const mockGlobals = require('../../fixtures/mock-globals')
+const setupOtplease = async (t, { otp = {}, ...rest }, fn) => {
+ const readUserInfo = {
+ otp: async () => '1234',
+ }
-const readUserInfo = {
- otp: async () => '1234',
-}
-const webAuth = async (opener) => {
- opener()
- return '1234'
-}
+ const webAuth = async (opener) => {
+ opener()
+ return '1234'
+ }
-const otplease = t.mock('../../../lib/utils/otplease.js', {
- '../../../lib/utils/read-user-info.js': readUserInfo,
- '../../../lib/utils/open-url-prompt.js': () => {},
- '../../../lib/utils/web-auth': webAuth,
-})
+ const otplease = tmock(t, '{LIB}/utils/otplease.js', {
+ '{LIB}/utils/read-user-info.js': readUserInfo,
+ '{LIB}/utils/open-url-prompt.js': () => {},
+ '{LIB}/utils/web-auth': webAuth,
+ })
+
+ const { npm } = await setupMockNpm(t, rest)
+
+ return await otplease(npm, otp, fn)
+}
t.test('returns function results on success', async (t) => {
- const fn = () => 'test string'
- const result = await otplease(null, {}, fn)
+ const result = await setupOtplease(t, {}, () => 'test string')
t.equal('test string', result)
})
t.test('returns function results on otp success', async (t) => {
- mockGlobals(t, {
- 'process.stdin': { isTTY: true },
- 'process.stdout': { isTTY: true },
- })
const fn = ({ otp }) => {
if (otp) {
return 'success'
}
throw Object.assign(new Error('nope'), { code: 'EOTP' })
}
- const result = await otplease(null, {}, fn)
+
+ const result = await setupOtplease(t, {
+ globals: {
+ 'process.stdin': { isTTY: true },
+ 'process.stdout': { isTTY: true },
+ },
+ }, fn)
+
t.equal('success', result)
})
t.test('prompts for otp for EOTP', async (t) => {
- const stdinTTY = process.stdin.isTTY
- const stdoutTTY = process.stdout.isTTY
- process.stdin.isTTY = true
- process.stdout.isTTY = true
- t.teardown(() => {
- process.stdin.isTTY = stdinTTY
- process.stdout.isTTY = stdoutTTY
- })
+ let called = false
- let runs = 0
const fn = async (opts) => {
- if (++runs === 1) {
+ if (!called) {
+ called = true
throw Object.assign(new Error('nope'), { code: 'EOTP' })
}
-
- t.equal(opts.some, 'prop', 'carried original options')
- t.equal(opts.otp, '1234', 'received the otp')
- t.end()
+ return opts
}
- await otplease(null, { some: 'prop' }, fn)
+ const result = await setupOtplease(t, {
+ otp: { some: 'prop' },
+ globals: {
+ 'process.stdin': { isTTY: true },
+ 'process.stdout': { isTTY: true },
+ },
+ }, fn)
+
+ t.strictSame(result, { some: 'prop', otp: '1234' })
})
t.test('returns function results on webauth success', async (t) => {
- mockGlobals(t, {
- 'process.stdin': { isTTY: true },
- 'process.stdout': { isTTY: true },
- })
-
- const npm = mockNpm({ config: { browser: 'firefox' } })
const fn = ({ otp }) => {
if (otp) {
return 'success'
@@ -82,75 +82,64 @@ t.test('returns function results on webauth success', async (t) => {
})
}
- const result = await otplease(npm, {}, fn)
+ const result = await setupOtplease(t, {
+ config: { browser: 'firefox' },
+ globals: {
+ 'process.stdin': { isTTY: true },
+ 'process.stdout': { isTTY: true },
+ },
+ }, fn)
+
t.equal('success', result)
})
t.test('prompts for otp for 401', async (t) => {
- const stdinTTY = process.stdin.isTTY
- const stdoutTTY = process.stdout.isTTY
- process.stdin.isTTY = true
- process.stdout.isTTY = true
- t.teardown(() => {
- process.stdin.isTTY = stdinTTY
- process.stdout.isTTY = stdoutTTY
- })
+ let called = false
- let runs = 0
const fn = async (opts) => {
- if (++runs === 1) {
+ if (!called) {
+ called = true
throw Object.assign(new Error('nope'), {
code: 'E401',
body: 'one-time pass required',
})
}
- t.equal(opts.some, 'prop', 'carried original options')
- t.equal(opts.otp, '1234', 'received the otp')
- t.end()
+ return opts
}
- await otplease(null, { some: 'prop' }, fn)
+ const result = await setupOtplease(t, {
+ globals: {
+ 'process.stdin': { isTTY: true },
+ 'process.stdout': { isTTY: true },
+ },
+ }, fn)
+
+ t.strictSame(result, { otp: '1234' })
})
t.test('does not prompt for non-otp errors', async (t) => {
- const stdinTTY = process.stdin.isTTY
- const stdoutTTY = process.stdout.isTTY
- process.stdin.isTTY = true
- process.stdout.isTTY = true
- t.teardown(() => {
- process.stdin.isTTY = stdinTTY
- process.stdout.isTTY = stdoutTTY
- })
-
const fn = async (opts) => {
throw new Error('nope')
}
- t.rejects(
- otplease(null, { some: 'prop' }, fn),
- { message: 'nope' },
- 'rejects with the original error'
- )
+ await t.rejects(setupOtplease(t, {
+ globals: {
+ 'process.stdin': { isTTY: true },
+ 'process.stdout': { isTTY: true },
+ },
+ }, fn), { message: 'nope' }, 'rejects with the original error')
})
t.test('does not prompt if stdin or stdout is not a tty', async (t) => {
- const stdinTTY = process.stdin.isTTY
- const stdoutTTY = process.stdout.isTTY
- process.stdin.isTTY = false
- process.stdout.isTTY = false
- t.teardown(() => {
- process.stdin.isTTY = stdinTTY
- process.stdout.isTTY = stdoutTTY
- })
-
const fn = async (opts) => {
throw Object.assign(new Error('nope'), { code: 'EOTP' })
}
- t.rejects(
- otplease(null, { some: 'prop' }, fn),
- { message: 'nope' },
- 'rejects with the original error'
- )
+ await t.rejects(setupOtplease(t, {
+ globals: {
+ 'process.stdin': { isTTY: false },
+ 'process.stdout': { isTTY: false },
+ },
+ }, fn), { message: 'nope' }, 'rejects with the original error')
})
diff --git a/deps/npm/test/lib/utils/pulse-till-done.js b/deps/npm/test/lib/utils/pulse-till-done.js
index 9f7a94614d..3b3f4b2f22 100644
--- a/deps/npm/test/lib/utils/pulse-till-done.js
+++ b/deps/npm/test/lib/utils/pulse-till-done.js
@@ -1,8 +1,9 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
let pulseStarted = null
-const pulseTillDone = t.mock('../../../lib/utils/pulse-till-done.js', {
+const pulseTillDone = tmock(t, '{LIB}/utils/pulse-till-done.js', {
npmlog: {
gauge: {
pulse: () => {
diff --git a/deps/npm/test/lib/utils/read-user-info.js b/deps/npm/test/lib/utils/read-user-info.js
index be805a2a87..dfd17a8e37 100644
--- a/deps/npm/test/lib/utils/read-user-info.js
+++ b/deps/npm/test/lib/utils/read-user-info.js
@@ -1,4 +1,5 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
let readOpts = null
let readResult = null
@@ -25,7 +26,7 @@ const npmUserValidate = {
}
let logMsg = null
-const readUserInfo = t.mock('../../../lib/utils/read-user-info.js', {
+const readUserInfo = tmock(t, '{LIB}/utils/read-user-info.js', {
read,
npmlog: {
clearProgress: () => {},
diff --git a/deps/npm/test/lib/utils/reify-finish.js b/deps/npm/test/lib/utils/reify-finish.js
index b565034058..ee112203a2 100644
--- a/deps/npm/test/lib/utils/reify-finish.js
+++ b/deps/npm/test/lib/utils/reify-finish.js
@@ -1,4 +1,6 @@
const t = require('tap')
+const { cleanNewlines } = require('../../fixtures/clean-snapshot')
+const tmock = require('../../fixtures/tmock')
const npm = {
config: {
@@ -30,9 +32,9 @@ const fs = {
},
}
-const reifyFinish = t.mock('../../../lib/utils/reify-finish.js', {
+const reifyFinish = tmock(t, '{LIB}/utils/reify-finish.js', {
fs,
- '../../../lib/utils/reify-output.js': reifyOutput,
+ '{LIB}/utils/reify-output.js': reifyOutput,
})
t.test('should not write if not global', async t => {
@@ -74,6 +76,6 @@ t.test('should write if everything above passes', async t => {
},
})
// windowwwwwwssss!!!!!
- const data = fs.readFileSync(`${path}/npmrc`, 'utf8').replace(/\r\n/g, '\n')
+ const data = cleanNewlines(fs.readFileSync(`${path}/npmrc`, 'utf8'))
t.matchSnapshot(data, 'written config')
})
diff --git a/deps/npm/test/lib/utils/reify-output.js b/deps/npm/test/lib/utils/reify-output.js
index b38a14de33..5d1d5be47e 100644
--- a/deps/npm/test/lib/utils/reify-output.js
+++ b/deps/npm/test/lib/utils/reify-output.js
@@ -1,25 +1,22 @@
const t = require('tap')
+const mockNpm = require('../../fixtures/mock-npm')
+const reifyOutput = require('../../../lib/utils/reify-output.js')
t.cleanSnapshot = str => str.replace(/in [0-9]+m?s/g, 'in {TIME}')
-const settings = {
- fund: true,
-}
-const npm = {
- started: Date.now(),
- flatOptions: settings,
- silent: false,
+const mockReify = async (t, reify, { command, ...config } = {}) => {
+ const mock = await mockNpm(t, {
+ command,
+ config,
+ })
+
+ reifyOutput(mock.npm, reify)
+
+ return mock.joinedOutput()
}
-const reifyOutput = require('../../../lib/utils/reify-output.js')
-t.test('missing info', (t) => {
- t.plan(1)
- npm.output = out => t.notMatch(
- out,
- 'looking for funding',
- 'should not print fund message if missing info'
- )
- reifyOutput(npm, {
+t.test('missing info', async t => {
+ const out = await mockReify(t, {
actualTree: {
children: [],
},
@@ -27,36 +24,30 @@ t.test('missing info', (t) => {
children: [],
},
})
-})
-t.test('even more missing info', t => {
- t.plan(1)
- npm.output = out => t.notMatch(
+ t.notMatch(
out,
'looking for funding',
'should not print fund message if missing info'
)
+})
- reifyOutput(npm, {
+t.test('even more missing info', async t => {
+ const out = await mockReify(t, {
actualTree: {
children: [],
},
})
-})
-t.test('single package', (t) => {
- t.plan(1)
- npm.output = out => {
- if (out.endsWith('looking for funding')) {
- t.match(
- out,
- '1 package is looking for funding',
- 'should print single package message'
- )
- }
- }
+ t.notMatch(
+ out,
+ 'looking for funding',
+ 'should not print fund message if missing info'
+ )
+})
- reifyOutput(npm, {
+t.test('single package', async t => {
+ const out = await mockReify(t, {
// a report with an error is the same as no report at all, if
// the command is not 'audit'
auditReport: {
@@ -87,20 +78,16 @@ t.test('single package', (t) => {
children: [],
},
})
-})
-t.test('no message when funding config is false', (t) => {
- t.teardown(() => {
- settings.fund = true
- })
- settings.fund = false
- npm.output = out => {
- if (out.endsWith('looking for funding')) {
- t.fail('should not print funding info', { actual: out })
- }
- }
+ t.match(
+ out,
+ '1 package is looking for funding',
+ 'should print single package message'
+ )
+})
- reifyOutput(npm, {
+t.test('no message when funding config is false', async t => {
+ const out = await mockReify(t, {
actualTree: {
name: 'foo',
package: {
@@ -123,24 +110,13 @@ t.test('no message when funding config is false', (t) => {
diff: {
children: [],
},
- })
+ }, { fund: false })
- t.end()
+ t.notMatch(out, 'looking for funding', 'should not print funding info')
})
-t.test('print appropriate message for many packages', (t) => {
- t.plan(1)
- npm.output = out => {
- if (out.endsWith('looking for funding')) {
- t.match(
- out,
- '3 packages are looking for funding',
- 'should print single package message'
- )
- }
- }
-
- reifyOutput(npm, {
+t.test('print appropriate message for many packages', async t => {
+ const out = await mockReify(t, {
actualTree: {
name: 'foo',
package: {
@@ -184,6 +160,12 @@ t.test('print appropriate message for many packages', (t) => {
children: [],
},
})
+
+ t.match(
+ out,
+ '3 packages are looking for funding',
+ 'should print single package message'
+ )
})
t.test('showing and not showing audit report', async t => {
@@ -231,15 +213,8 @@ t.test('showing and not showing audit report', async t => {
},
}
- t.test('no output when silent', t => {
- t.teardown(() => {
- delete npm.silent
- })
- npm.silent = true
- npm.output = out => {
- t.fail('should not get output when silent', { actual: out })
- }
- reifyOutput(npm, {
+ t.test('no output when silent', async t => {
+ const out = await mockReify(t, {
actualTree: { inventory: { size: 999 }, children: [] },
auditReport,
diff: {
@@ -247,16 +222,12 @@ t.test('showing and not showing audit report', async t => {
{ action: 'ADD', ideal: { location: 'loc' } },
],
},
- })
- t.end()
+ }, { silent: true })
+ t.equal(out, '', 'should not get output when silent')
})
- t.test('output when not silent', t => {
- const OUT = []
- npm.output = out => {
- OUT.push(out)
- }
- reifyOutput(npm, {
+ t.test('output when not silent', async t => {
+ const out = await mockReify(t, {
actualTree: { inventory: new Map(), children: [] },
auditReport,
diff: {
@@ -265,33 +236,14 @@ t.test('showing and not showing audit report', async t => {
],
},
})
- t.match(OUT.join('\n'), /Run `npm audit` for details\.$/, 'got audit report')
- t.end()
+
+ t.match(out, /Run `npm audit` for details\.$/, 'got audit report')
})
for (const json of [true, false]) {
- t.test(`json=${json}`, t => {
- t.teardown(() => {
- delete npm.flatOptions.json
- })
- npm.flatOptions.json = json
- t.test('set exit code when cmd is audit', t => {
- npm.output = () => {}
- const { exitCode } = process
- const { command } = npm
- npm.flatOptions.auditLevel = 'low'
- t.teardown(() => {
- delete npm.flatOptions.auditLevel
- npm.command = command
- // only set exitCode back if we're passing tests
- if (t.passing()) {
- process.exitCode = exitCode
- }
- })
-
- process.exitCode = 0
- npm.command = 'audit'
- reifyOutput(npm, {
+ t.test(`json=${json}`, async t => {
+ t.test('set exit code when cmd is audit', async t => {
+ await mockReify(t, {
actualTree: { inventory: new Map(), children: [] },
auditReport,
diff: {
@@ -299,29 +251,13 @@ t.test('showing and not showing audit report', async t => {
{ action: 'ADD', ideal: { location: 'loc' } },
],
},
- })
+ }, { command: 'audit', 'audit-level': 'low' })
t.equal(process.exitCode, 1, 'set exit code')
- t.end()
})
- t.test('do not set exit code when cmd is install', t => {
- npm.output = () => {}
- const { exitCode } = process
- const { command } = npm
- npm.flatOptions.auditLevel = 'low'
- t.teardown(() => {
- delete npm.flatOptions.auditLevel
- npm.command = command
- // only set exitCode back if we're passing tests
- if (t.passing()) {
- process.exitCode = exitCode
- }
- })
-
- process.exitCode = 0
- npm.command = 'install'
- reifyOutput(npm, {
+ t.test('do not set exit code when cmd is install', async t => {
+ await mockReify(t, {
actualTree: { inventory: new Map(), children: [] },
auditReport,
diff: {
@@ -329,28 +265,17 @@ t.test('showing and not showing audit report', async t => {
{ action: 'ADD', ideal: { location: 'loc' } },
],
},
- })
+ }, { command: 'install', 'audit-level': 'low' })
- t.equal(process.exitCode, 0, 'did not set exit code')
- t.end()
+ t.notOk(process.exitCode, 'did not set exit code')
})
- t.end()
})
}
-
- t.end()
})
-t.test('packages changed message', t => {
- const output = []
- npm.output = out => {
- output.push(out)
- }
-
+t.test('packages changed message', async t => {
// return a test function that builds up the mock and snapshots output
- const testCase = (t, added, removed, changed, audited, json, command) => {
- settings.json = json
- npm.command = command
+ const testCase = async (t, added, removed, changed, audited, json, command) => {
const mock = {
actualTree: {
inventory: { size: audited, has: () => true },
@@ -384,9 +309,9 @@ t.test('packages changed message', t => {
const ideal = { location: 'loc' }
mock.diff.children.push({ action: 'CHANGE', actual, ideal })
}
- output.length = 0
- reifyOutput(npm, mock)
- t.matchSnapshot(output.join('\n'), JSON.stringify({
+
+ const out = await mockReify(t, mock, { json, command })
+ t.matchSnapshot(out, JSON.stringify({
added,
removed,
changed,
@@ -412,20 +337,14 @@ t.test('packages changed message', t => {
cases.push([0, 0, 0, 2, true, 'audit'])
cases.push([0, 0, 0, 2, false, 'audit'])
- t.plan(cases.length)
- for (const [added, removed, changed, audited, json, command] of cases) {
- testCase(t, added, removed, changed, audited, json, command)
+ for (const c of cases) {
+ await t.test('', t => testCase(t, ...c))
}
-
- t.end()
})
-t.test('added packages should be looked up within returned tree', t => {
- t.test('has added pkg in inventory', t => {
- t.plan(1)
- npm.output = out => t.matchSnapshot(out)
-
- reifyOutput(npm, {
+t.test('added packages should be looked up within returned tree', async t => {
+ t.test('has added pkg in inventory', async t => {
+ const out = await mockReify(t, {
actualTree: {
name: 'foo',
inventory: {
@@ -438,13 +357,12 @@ t.test('added packages should be looked up within returned tree', t => {
],
},
})
- })
- t.test('missing added pkg in inventory', t => {
- t.plan(1)
- npm.output = out => t.matchSnapshot(out)
+ t.matchSnapshot(out)
+ })
- reifyOutput(npm, {
+ t.test('missing added pkg in inventory', async t => {
+ const out = await mockReify(t, {
actualTree: {
name: 'foo',
inventory: {
@@ -457,6 +375,7 @@ t.test('added packages should be looked up within returned tree', t => {
],
},
})
+
+ t.matchSnapshot(out)
})
- t.end()
})
diff --git a/deps/npm/test/lib/utils/tar.js b/deps/npm/test/lib/utils/tar.js
index f72b1432c8..78c01f3f57 100644
--- a/deps/npm/test/lib/utils/tar.js
+++ b/deps/npm/test/lib/utils/tar.js
@@ -1,10 +1,11 @@
const t = require('tap')
const pack = require('libnpmpack')
const ssri = require('ssri')
+const tmock = require('../../fixtures/tmock')
const { getContents } = require('../../../lib/utils/tar.js')
-const mockTar = ({ notice }) => t.mock('../../../lib/utils/tar.js', {
+const mockTar = ({ notice }) => tmock(t, '{LIB}/utils/tar.js', {
'proc-log': {
notice,
},
diff --git a/deps/npm/test/lib/utils/timers.js b/deps/npm/test/lib/utils/timers.js
index 23d8eb6e2c..74df6c28cd 100644
--- a/deps/npm/test/lib/utils/timers.js
+++ b/deps/npm/test/lib/utils/timers.js
@@ -2,10 +2,11 @@ const t = require('tap')
const { resolve, join } = require('path')
const fs = require('graceful-fs')
const mockLogs = require('../../fixtures/mock-logs')
+const tmock = require('../../fixtures/tmock')
const mockTimers = (t, options) => {
const { logs, logMocks } = mockLogs()
- const Timers = t.mock('../../../lib/utils/timers', {
+ const Timers = tmock(t, '{LIB}/utils/timers', {
...logMocks,
})
const timers = new Timers(options)
diff --git a/deps/npm/test/lib/utils/update-notifier.js b/deps/npm/test/lib/utils/update-notifier.js
index fa4a04bad9..e7830e6d9d 100644
--- a/deps/npm/test/lib/utils/update-notifier.js
+++ b/deps/npm/test/lib/utils/update-notifier.js
@@ -1,4 +1,6 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
+
let ciMock = {}
const flatOptions = { global: false, cache: t.testdir() + '/_cacache' }
@@ -17,7 +19,6 @@ let PACOTE_ERROR = null
const pacote = {
manifest: async (spec, opts) => {
if (!spec.match(/^npm@/)) {
- console.error(new Error('should only fetch manifest for npm'))
process.exit(1)
}
MANIFEST_REQUEST.push(spec)
@@ -53,22 +54,15 @@ const fs = {
...require('fs'),
stat: (path, cb) => {
if (basename(path) !== '_update-notifier-last-checked') {
- console.error(
- new Error('should only write to notifier last checked file')
- )
process.exit(1)
}
process.nextTick(() => cb(STAT_ERROR, { mtime: new Date(STAT_MTIME) }))
},
writeFile: (path, content, cb) => {
if (content !== '') {
- console.error(new Error('should not be writing content'))
process.exit(1)
}
if (basename(path) !== '_update-notifier-last-checked') {
- console.error(
- new Error('should only write to notifier last checked file')
- )
process.exit(1)
}
process.nextTick(() => cb(WRITE_ERROR))
@@ -85,7 +79,7 @@ t.afterEach(() => {
const runUpdateNotifier = async ({ color = true, ...npmOptions } = {}) => {
const _npm = { ...defaultNpm, ...npmOptions, logColor: color }
- return t.mock('../../../lib/utils/update-notifier.js', {
+ return tmock(t, '{LIB}/utils/update-notifier.js', {
'ci-info': ciMock,
pacote,
fs,
diff --git a/deps/npm/test/lib/utils/web-auth.js b/deps/npm/test/lib/utils/web-auth.js
index ee8a17ecbc..a4e8f4bbc7 100644
--- a/deps/npm/test/lib/utils/web-auth.js
+++ b/deps/npm/test/lib/utils/web-auth.js
@@ -1,10 +1,11 @@
const t = require('tap')
+const tmock = require('../../fixtures/tmock')
const webAuthCheckLogin = async () => {
return { token: 'otp-token' }
}
-const webauth = t.mock('../../../lib/utils/web-auth.js', {
+const webauth = tmock(t, '{LIB}/utils/web-auth.js', {
'npm-profile': { webAuthCheckLogin },
})