Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rebuild.js9
-rw-r--r--test/lib/rebuild.js222
2 files changed, 228 insertions, 3 deletions
diff --git a/lib/rebuild.js b/lib/rebuild.js
index 076cfc699..f373d8cf5 100644
--- a/lib/rebuild.js
+++ b/lib/rebuild.js
@@ -1,10 +1,13 @@
+'use strict'
+
+const { resolve } = require('path')
const Arborist = require('@npmcli/arborist')
+const npa = require('npm-package-arg')
+const semver = require('semver')
+
const npm = require('./npm.js')
const usageUtil = require('./utils/usage.js')
-const { resolve } = require('path')
const output = require('./utils/output.js')
-const npa = require('npm-package-arg')
-const semver = require('semver')
const cmd = (args, cb) => rebuild(args).then(() => cb()).catch(cb)
diff --git a/test/lib/rebuild.js b/test/lib/rebuild.js
new file mode 100644
index 000000000..dbc37d57a
--- /dev/null
+++ b/test/lib/rebuild.js
@@ -0,0 +1,222 @@
+const fs = require('fs')
+const { resolve } = require('path')
+const t = require('tap')
+const requireInject = require('require-inject')
+
+let result = ''
+
+const npm = {
+ globalDir: '',
+ flatOptions: {
+ global: false,
+ },
+ prefix: '',
+}
+const mocks = {
+ '../../lib/npm.js': npm,
+ '../../lib/utils/output.js': (...msg) => {
+ result += msg.join('\n')
+ },
+ '../../lib/utils/usage.js': () => 'usage instructions',
+}
+
+const rebuild = requireInject('../../lib/rebuild.js', mocks)
+
+t.afterEach(cb => {
+ npm.prefix = ''
+ npm.flatOptions.global = false
+ npm.globalDir = ''
+ result = ''
+ cb()
+})
+
+t.test('no args', 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 aBuildFile = resolve(path, 'node_modules/a/cwd')
+ const bBuildFile = resolve(path, 'node_modules/b/cwd')
+ const aBinFile = resolve(path, 'node_modules/.bin/a')
+ const bBinFile = resolve(path, 'node_modules/.bin/b')
+ t.throws(() => fs.statSync(aBuildFile))
+ t.throws(() => fs.statSync(bBuildFile))
+ t.throws(() => fs.statSync(aBinFile))
+ t.throws(() => fs.statSync(bBinFile))
+
+ npm.prefix = path
+
+ rebuild([], err => {
+ if (err)
+ throw err
+
+ t.ok(() => fs.statSync(aBuildFile))
+ t.ok(() => fs.statSync(bBuildFile))
+ t.ok(() => fs.statSync(aBinFile))
+ t.ok(() => fs.statSync(bBinFile))
+
+ t.equal(
+ result,
+ 'rebuilt dependencies successfully',
+ 'should output success msg'
+ )
+
+ t.end()
+ })
+})
+
+t.test('filter by pkg name', 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',
+ }),
+ },
+ },
+ })
+
+ 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))
+
+ rebuild(['b'], err => {
+ if (err)
+ throw err
+
+ t.throws(() => fs.statSync(aBinFile), 'should not link a bin')
+ t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin')
+
+ t.end()
+ })
+})
+
+t.test('filter by pkg@<range>', 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',
+ }),
+ },
+ },
+ },
+ 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')
+
+ rebuild(['b@2'], err => {
+ if (err)
+ throw err
+
+ t.throws(() => fs.statSync(bBinFile), 'should not link b bin')
+ t.ok(() => fs.statSync(nestedBinFile), 'should link filtered pkg bin')
+
+ t.end()
+ })
+})
+
+t.test('filter must be a semver version/range', t => {
+ rebuild(['b:git+ssh://github.com/npm/arborist'], err => {
+ t.match(
+ err,
+ /Error: `npm rebuild` only supports SemVer version\/range specifiers/,
+ 'should throw type error'
+ )
+
+ t.end()
+ })
+})
+
+t.test('global prefix', t => {
+ const globalPath = t.testdir({
+ lib: {
+ node_modules: {
+ a: {
+ 'index.js': '',
+ 'package.json': JSON.stringify({
+ name: 'a',
+ version: '1.0.0',
+ bin: 'index.js',
+ }),
+ },
+ },
+ },
+ })
+
+ npm.flatOptions.global = true
+ npm.globalDir = resolve(globalPath, 'lib', 'node_modules')
+
+ rebuild([], err => {
+ if (err)
+ throw err
+
+ t.ok(() => fs.statSync(resolve(globalPath, 'lib/node_modules/.bin/a')))
+
+ t.equal(
+ result,
+ 'rebuilt dependencies successfully',
+ 'should output success msg'
+ )
+
+ t.end()
+ })
+})