1var fs = require('fs') 2var join = require('path').join 3 4var mkdirp = require('mkdirp') 5var rimraf = require('rimraf') 6var test = require('tap').test 7 8var common = require('../common-tap.js') 9var pkg = common.pkg 10var modules = join(pkg, 'node_modules') 11 12var EXEC_OPTS = { cwd: pkg } 13 14var body = [ 15 'move\t@scope/shared\t2.1.6\tnode_modules/@scope/shared\t\tnode_modules/first/node_modules/@scope/shared', 16 'move\tfirstUnique\t0.6.0\tnode_modules/firstUnique\t\tnode_modules/first/node_modules/firstUnique', 17 'remove\t@scope/shared\t2.1.6\tnode_modules/second/node_modules/@scope/shared', 18 'move\tsecondUnique\t1.2.0\tnode_modules/secondUnique\t\tnode_modules/second/node_modules/secondUnique' 19] 20 21var deduper = { 22 'name': 'dedupe', 23 'version': '0.0.0', 24 'dependencies': { 25 'first': '1.0.0', 26 'second': '2.0.0' 27 } 28} 29 30var first = { 31 'name': 'first', 32 'version': '1.0.0', 33 'dependencies': { 34 'firstUnique': '0.6.0', 35 '@scope/shared': '2.1.6' 36 }, 37 '_resolved': 'foo', 38 '_integrity': 'sha1-deadbeef' 39} 40 41var second = { 42 'name': 'second', 43 'version': '2.0.0', 44 'dependencies': { 45 'secondUnique': '1.2.0', 46 '@scope/shared': '2.1.6' 47 }, 48 '_resolved': 'foo', 49 '_integrity': 'sha1-deadbeef' 50} 51 52var shared = { 53 'name': '@scope/shared', 54 'version': '2.1.6', 55 '_resolved': 'foo', 56 '_integrity': 'sha1-deadbeef' 57} 58 59var firstUnique = { 60 'name': 'firstUnique', 61 'version': '0.6.0', 62 '_resolved': 'foo', 63 '_integrity': 'sha1-deadbeef' 64} 65 66var secondUnique = { 67 'name': 'secondUnique', 68 'version': '1.2.0', 69 '_resolved': 'foo', 70 '_integrity': 'sha1-deadbeef' 71} 72 73test('setup', function (t) { 74 setup() 75 t.end() 76}) 77 78// we like the cars 79function ltrimm (l) { return l.trim() } 80 81test('dedupe finds the common scoped modules and moves it up one level', function (t) { 82 common.npm( 83 [ 84 'find-dupes' // I actually found a use for this command! 85 ], 86 EXEC_OPTS, 87 function (err, code, stdout, stderr) { 88 t.ifError(err, 'successful dry run against fake install') 89 t.notOk(code, 'npm ran without issue') 90 t.notOk(stderr, 'npm printed no errors') 91 t.same( 92 stdout.trim().replace(/\\/g, '/').split('\n').map(ltrimm), 93 body.map(ltrimm), 94 'got expected output' 95 ) 96 97 t.end() 98 } 99 ) 100}) 101 102test('cleanup', function (t) { 103 cleanup() 104 t.end() 105}) 106 107function setup (cb) { 108 cleanup() 109 110 mkdirp.sync(pkg) 111 fs.writeFileSync( 112 join(pkg, 'package.json'), 113 JSON.stringify(deduper, null, 2) 114 ) 115 116 mkdirp.sync(join(modules, 'first')) 117 fs.writeFileSync( 118 join(modules, 'first', 'package.json'), 119 JSON.stringify(first, null, 2) 120 ) 121 122 mkdirp.sync(join(modules, 'first', 'node_modules', 'firstUnique')) 123 fs.writeFileSync( 124 join(modules, 'first', 'node_modules', 'firstUnique', 'package.json'), 125 JSON.stringify(firstUnique, null, 2) 126 ) 127 128 mkdirp.sync(join(modules, 'first', 'node_modules', '@scope', 'shared')) 129 fs.writeFileSync( 130 join(modules, 'first', 'node_modules', '@scope', 'shared', 'package.json'), 131 JSON.stringify(shared, null, 2) 132 ) 133 134 mkdirp.sync(join(modules, 'second')) 135 fs.writeFileSync( 136 join(modules, 'second', 'package.json'), 137 JSON.stringify(second, null, 2) 138 ) 139 140 mkdirp.sync(join(modules, 'second', 'node_modules', 'secondUnique')) 141 fs.writeFileSync( 142 join(modules, 'second', 'node_modules', 'secondUnique', 'package.json'), 143 JSON.stringify(secondUnique, null, 2) 144 ) 145 146 mkdirp.sync(join(modules, 'second', 'node_modules', '@scope', 'shared')) 147 fs.writeFileSync( 148 join(modules, 'second', 'node_modules', '@scope', 'shared', 'package.json'), 149 JSON.stringify(shared, null, 2) 150 ) 151} 152 153function cleanup () { 154 rimraf.sync(pkg) 155} 156