1const t = require('tap') 2const path = require('path') 3const fs = require('fs') 4 5const { load: loadMockNpm } = require('../../fixtures/mock-npm') 6const MockRegistry = require('@npmcli/mock-registry') 7 8t.test('should throw in global mode', async (t) => { 9 const { npm } = await loadMockNpm(t, { 10 config: { 11 global: true, 12 }, 13 }) 14 t.rejects( 15 npm.exec('dedupe', []), 16 { code: 'EDEDUPEGLOBAL' }, 17 'throws EDEDUPEGLOBALE' 18 ) 19}) 20 21const treeWithDupes = { 22 'package.json': JSON.stringify({ 23 name: 'test-top', 24 version: '1.0.0', 25 dependencies: { 26 'test-dep-a': '*', 27 'test-dep-b': '*', 28 }, 29 }), 30 node_modules: { 31 'test-dep-a': { 32 'package.json': JSON.stringify({ 33 name: 'test-dep-a', 34 version: '1.0.1', 35 dependencies: { 'test-sub': '*' }, 36 }), 37 node_modules: { 38 'test-sub': { 39 'package.json': JSON.stringify({ 40 name: 'test-sub', 41 version: '1.0.0', 42 }), 43 }, 44 }, 45 }, 46 'test-dep-b': { 47 'package.json': JSON.stringify({ 48 name: 'test-dep-b', 49 version: '1.0.0', 50 dependencies: { 'test-sub': '*' }, 51 }), 52 node_modules: { 53 'test-sub': { 54 'package.json': JSON.stringify({ 55 name: 'test-sub', 56 version: '1.0.0', 57 }), 58 }, 59 }, 60 }, 61 }, 62} 63 64t.test('dedupe', async (t) => { 65 const { npm, joinedOutput } = await loadMockNpm(t, { 66 prefixDir: treeWithDupes, 67 }) 68 const registry = new MockRegistry({ 69 tap: t, 70 registry: npm.config.get('registry'), 71 }) 72 const manifestSub = registry.manifest({ 73 name: 'test-sub', 74 packuments: [{ version: '1.0.0' }], 75 }) 76 77 await registry.package({ 78 manifest: manifestSub, 79 tarballs: { 80 '1.0.0': path.join(npm.prefix, 'node_modules', 'test-dep-a', 'node_modules', 'test-sub'), 81 }, 82 }) 83 await npm.exec('dedupe', []) 84 t.match(joinedOutput(), /added 1 package, and removed 2 packages/) 85 t.ok( 86 fs.existsSync(path.join(npm.prefix, 'node_modules', 'test-sub')), 87 'test-sub was hoisted' 88 ) 89 t.notOk( 90 fs.existsSync(path.join(npm.prefix, 'node_modules', 'test-dep-a', 'node_modules', 'test-sub')), 91 'test-dep-a/test-sub was removed' 92 ) 93 t.notOk( 94 fs.existsSync(path.join(npm.prefix, 'node_modules', 'test-dep-b', 'node_modules', 'test-sub')), 95 'test-dep-b/test-sub was removed') 96}) 97