• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1const t = require('tap')
2const path = require('path')
3const tspawk = require('../../fixtures/tspawk')
4const { load: loadMockNpm } = require('../../fixtures/mock-npm')
5
6const spawk = tspawk(t)
7
8const npmConfig = {
9  config: {
10    'ignore-scripts': false,
11    editor: 'testeditor',
12    'script-shell': process.platform === 'win32' ? process.env.COMSPEC : 'sh',
13  },
14  prefixDir: {
15    node_modules: {
16      semver: {
17        'package.json': JSON.stringify({
18          scripts: {
19            install: 'testinstall',
20          },
21        }),
22        node_modules: {
23          abbrev: {},
24        },
25      },
26      '@npmcli': {
27        'scoped-package': {},
28      },
29    },
30  },
31}
32
33const isCmdRe = /(?:^|\\)cmd(?:\.exe)?$/i
34
35t.test('npm edit', async t => {
36  const { npm, joinedOutput } = await loadMockNpm(t, npmConfig)
37
38  const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
39  spawk.spawn('testeditor', [semverPath])
40
41  const scriptShell = npm.config.get('script-shell')
42  const scriptArgs = isCmdRe.test(scriptShell)
43    ? ['/d', '/s', '/c', 'testinstall']
44    : ['-c', 'testinstall']
45  spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath })
46
47  await npm.exec('edit', ['semver'])
48  t.match(joinedOutput(), 'rebuilt dependencies successfully')
49})
50
51t.test('rebuild failure', async t => {
52  const { npm } = await loadMockNpm(t, npmConfig)
53
54  const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
55  spawk.spawn('testeditor', [semverPath])
56
57  const scriptShell = npm.config.get('script-shell')
58  const scriptArgs = isCmdRe.test(scriptShell)
59    ? ['/d', '/s', '/c', 'testinstall']
60    : ['-c', 'testinstall']
61  spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath }).exit(1).stdout('test error')
62  await t.rejects(
63    npm.exec('edit', ['semver']),
64    { message: 'command failed' }
65  )
66})
67
68t.test('editor failure', async t => {
69  const { npm } = await loadMockNpm(t, npmConfig)
70
71  const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
72  spawk.spawn('testeditor', [semverPath]).exit(1).stdout('test editor failure')
73
74  await t.rejects(
75    npm.exec('edit', ['semver']),
76    { message: 'editor process exited with code: 1' }
77  )
78})
79
80t.test('npm edit editor has flags', async t => {
81  const { npm } = await loadMockNpm(t, {
82    ...npmConfig,
83    config: {
84      ...npmConfig.config,
85      editor: 'testeditor --flag',
86    },
87  })
88
89  const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver')
90  spawk.spawn('testeditor', ['--flag', semverPath])
91
92  const scriptShell = npm.config.get('script-shell')
93  const scriptArgs = isCmdRe.test(scriptShell)
94    ? ['/d', '/s', '/c', 'testinstall']
95    : ['-c', 'testinstall']
96  spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath })
97
98  await npm.exec('edit', ['semver'])
99})
100
101t.test('npm edit no args', async t => {
102  const { npm } = await loadMockNpm(t)
103  await t.rejects(
104    npm.exec('edit', []),
105    { code: 'EUSAGE' },
106    'throws usage error'
107  )
108})
109
110t.test('npm edit nonexistent package', async t => {
111  const { npm } = await loadMockNpm(t, npmConfig)
112
113  await t.rejects(
114    npm.exec('edit', ['abbrev']),
115    /lstat/
116  )
117})
118
119t.test('scoped package', async t => {
120  const { npm } = await loadMockNpm(t, npmConfig)
121  const scopedPath = path.resolve(npm.prefix, 'node_modules', '@npmcli', 'scoped-package')
122  spawk.spawn('testeditor', [scopedPath])
123  await npm.exec('edit', ['@npmcli/scoped-package'])
124})
125
126t.test('subdependency', async t => {
127  const { npm } = await loadMockNpm(t, npmConfig)
128  const subdepPath = path.resolve(npm.prefix, 'node_modules', 'semver', 'node_modules', 'abbrev')
129  spawk.spawn('testeditor', [subdepPath])
130  await npm.exec('edit', ['semver/abbrev'])
131})
132