• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const t = require('tap')
2const fs = require('fs')
3const { resolve } = require('path')
4const setupMockNpm = require('../../fixtures/mock-npm')
5
6t.test('no args', async t => {
7  const { npm, joinedOutput, prefix: path } = await setupMockNpm(t, {
8    prefixDir: {
9      node_modules: {
10        a: {
11          'package.json': JSON.stringify({
12            name: 'a',
13            version: '1.0.0',
14            bin: 'cwd',
15            scripts: {
16              preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
17            },
18          }),
19        },
20        b: {
21          'package.json': JSON.stringify({
22            name: 'b',
23            version: '1.0.0',
24            bin: 'cwd',
25            scripts: {
26              preinstall: "node -e \"require('fs').writeFileSync('cwd', '')\"",
27            },
28          }),
29        },
30      },
31    },
32  })
33
34  const aBuildFile = resolve(path, 'node_modules/a/cwd')
35  const bBuildFile = resolve(path, 'node_modules/b/cwd')
36  const aBinFile = resolve(path, 'node_modules/.bin/a')
37  const bBinFile = resolve(path, 'node_modules/.bin/b')
38  t.throws(() => fs.statSync(aBuildFile))
39  t.throws(() => fs.statSync(bBuildFile))
40  t.throws(() => fs.statSync(aBinFile))
41  t.throws(() => fs.statSync(bBinFile))
42
43  await npm.exec('rebuild', [])
44
45  t.ok(() => fs.statSync(aBuildFile))
46  t.ok(() => fs.statSync(bBuildFile))
47  t.ok(() => fs.statSync(aBinFile))
48  t.ok(() => fs.statSync(bBinFile))
49
50  t.equal(
51    joinedOutput(),
52    'rebuilt dependencies successfully',
53    'should output success msg'
54  )
55})
56
57t.test('filter by pkg name', async t => {
58  const { npm, prefix: path } = await setupMockNpm(t, {
59    prefixDir: {
60      node_modules: {
61        a: {
62          'index.js': '',
63          'package.json': JSON.stringify({
64            name: 'a',
65            version: '1.0.0',
66            bin: 'index.js',
67          }),
68        },
69        b: {
70          'index.js': '',
71          'package.json': JSON.stringify({
72            name: 'b',
73            version: '1.0.0',
74            bin: 'index.js',
75          }),
76        },
77      },
78    },
79  })
80
81  const aBinFile = resolve(path, 'node_modules/.bin/a')
82  const bBinFile = resolve(path, 'node_modules/.bin/b')
83  t.throws(() => fs.statSync(aBinFile))
84  t.throws(() => fs.statSync(bBinFile))
85
86  await npm.exec('rebuild', ['b'])
87
88  t.throws(() => fs.statSync(aBinFile), 'should not link a bin')
89  t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin')
90})
91
92t.test('filter by pkg@<range>', async t => {
93  const { npm, prefix: path } = await setupMockNpm(t, {
94    prefixDir: {
95      node_modules: {
96        a: {
97          'index.js': '',
98          'package.json': JSON.stringify({
99            name: 'a',
100            version: '1.0.0',
101            bin: 'index.js',
102          }),
103          node_modules: {
104            b: {
105              'index.js': '',
106              'package.json': JSON.stringify({
107                name: 'b',
108                version: '2.0.0',
109                bin: 'index.js',
110              }),
111            },
112          },
113        },
114        b: {
115          'index.js': '',
116          'package.json': JSON.stringify({
117            name: 'b',
118            version: '1.0.0',
119            bin: 'index.js',
120          }),
121        },
122      },
123    },
124  })
125
126  const bBinFile = resolve(path, 'node_modules/.bin/b')
127  const nestedBinFile = resolve(path, 'node_modules/a/node_modules/.bin/b')
128
129  await npm.exec('rebuild', ['b@2'])
130
131  t.throws(() => fs.statSync(bBinFile), 'should not link b bin')
132  t.ok(() => fs.statSync(nestedBinFile), 'should link filtered pkg bin')
133})
134
135t.test('filter by directory', async t => {
136  const { npm, prefix: path } = await setupMockNpm(t, {
137    prefixDir: {
138      node_modules: {
139        a: {
140          'index.js': '',
141          'package.json': JSON.stringify({
142            name: 'a',
143            version: '1.0.0',
144            bin: 'index.js',
145          }),
146        },
147        b: {
148          'index.js': '',
149          'package.json': JSON.stringify({
150            name: 'b',
151            version: '1.0.0',
152            bin: 'index.js',
153          }),
154        },
155      },
156    },
157  })
158
159  const aBinFile = resolve(path, 'node_modules/.bin/a')
160  const bBinFile = resolve(path, 'node_modules/.bin/b')
161  t.throws(() => fs.statSync(aBinFile))
162  t.throws(() => fs.statSync(bBinFile))
163
164  await npm.exec('rebuild', ['file:node_modules/b'])
165
166  t.throws(() => fs.statSync(aBinFile), 'should not link a bin')
167  t.ok(() => fs.statSync(bBinFile), 'should link filtered pkg bin')
168})
169
170t.test('filter must be a semver version/range, or directory', async t => {
171  const { npm } = await setupMockNpm(t)
172
173  await t.rejects(
174    npm.exec('rebuild', ['git+ssh://github.com/npm/arborist']),
175    /`npm rebuild` only supports SemVer version\/range specifiers/,
176    'should throw type error'
177  )
178})
179
180t.test('global prefix', async t => {
181  const { npm, globalPrefix, joinedOutput } = await setupMockNpm(t, {
182    config: {
183      global: true,
184    },
185    globalPrefixDir: {
186      node_modules: {
187        a: {
188          'index.js': '',
189          'package.json': JSON.stringify({
190            name: 'a',
191            version: '1.0.0',
192            bin: 'index.js',
193          }),
194        },
195      },
196    },
197  })
198
199  await npm.exec('rebuild', [])
200  t.ok(() => fs.statSync(resolve(globalPrefix, 'lib/node_modules/.bin/a')))
201
202  t.equal(
203    joinedOutput(),
204    'rebuilt dependencies successfully',
205    'should output success msg'
206  )
207})
208