%PDF- <> %âãÏÓ endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/Annots[ 28 0 R 29 0 R] /MediaBox[ 0 0 595.5 842.25] /Contents 4 0 R/Group<>/Tabs/S>> endobj ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<>endobj 2 0 obj<> endobj 2 0 obj<>endobj 2 0 obj<>es 3 0 R>> endobj 2 0 obj<> ox[ 0.000000 0.000000 609.600000 935.600000]/Fi endobj 3 0 obj<> endobj 7 1 obj<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI]>>/Subtype/Form>> stream
const t = require('tap') const path = require('path') const tspawk = require('../../fixtures/tspawk') const { load: loadMockNpm } = require('../../fixtures/mock-npm') const spawk = tspawk(t) // TODO this ... smells. npm "script-shell" config mentions defaults but those // are handled by run-script, not npm. So for now we have to tie tests to some // pretty specific internals of runScript const makeSpawnArgs = require('@npmcli/run-script/lib/make-spawn-args.js') const npmConfig = { config: { 'ignore-scripts': false, editor: 'testeditor', }, prefixDir: { node_modules: { semver: { 'package.json': JSON.stringify({ scripts: { install: 'testinstall', }, }), node_modules: { abbrev: {}, }, }, '@npmcli': { 'scoped-package': {}, }, }, }, } t.test('npm edit', async t => { const { npm, joinedOutput } = await loadMockNpm(t, npmConfig) const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver') const [scriptShell, scriptArgs] = makeSpawnArgs({ event: 'install', path: npm.prefix, cmd: 'testinstall', }) spawk.spawn('testeditor', [semverPath]) spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath }) await npm.exec('edit', ['semver']) t.match(joinedOutput(), 'rebuilt dependencies successfully') }) t.test('rebuild failure', async t => { const { npm } = await loadMockNpm(t, npmConfig) const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver') const [scriptShell, scriptArgs] = makeSpawnArgs({ event: 'install', path: npm.prefix, cmd: 'testinstall', }) spawk.spawn('testeditor', [semverPath]) spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath }).exit(1).stdout('test error') await t.rejects( npm.exec('edit', ['semver']), { message: 'command failed' } ) }) t.test('editor failure', async t => { const { npm } = await loadMockNpm(t, npmConfig) const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver') spawk.spawn('testeditor', [semverPath]).exit(1).stdout('test editor failure') await t.rejects( npm.exec('edit', ['semver']), { message: 'editor process exited with code: 1' } ) }) t.test('npm edit editor has flags', async t => { const { npm } = await loadMockNpm(t, { ...npmConfig, config: { ...npmConfig.config, editor: 'testeditor --flag', }, }) const semverPath = path.resolve(npm.prefix, 'node_modules', 'semver') const [scriptShell, scriptArgs] = makeSpawnArgs({ event: 'install', path: npm.prefix, cmd: 'testinstall', }) spawk.spawn('testeditor', ['--flag', semverPath]) spawk.spawn(scriptShell, scriptArgs, { cwd: semverPath }) await npm.exec('edit', ['semver']) }) t.test('npm edit no args', async t => { const { npm } = await loadMockNpm(t) await t.rejects( npm.exec('edit', []), { code: 'EUSAGE' }, 'throws usage error' ) }) t.test('npm edit nonexistent package', async t => { const { npm } = await loadMockNpm(t, npmConfig) await t.rejects( npm.exec('edit', ['abbrev']), /lstat/ ) }) t.test('scoped package', async t => { const { npm } = await loadMockNpm(t, npmConfig) const scopedPath = path.resolve(npm.prefix, 'node_modules', '@npmcli', 'scoped-package') spawk.spawn('testeditor', [scopedPath]) await npm.exec('edit', ['@npmcli/scoped-package']) }) t.test('subdependency', async t => { const { npm } = await loadMockNpm(t, npmConfig) const subdepPath = path.resolve(npm.prefix, 'node_modules', 'semver', 'node_modules', 'abbrev') spawk.spawn('testeditor', [subdepPath]) await npm.exec('edit', ['semver/abbrev']) })