1'use strict' 2var test = require('tap').test 3var Tacks = require('tacks') 4var File = Tacks.File 5var Dir = Tacks.Dir 6var fs = require('fs') 7var path = require('path') 8var common = require('../common-tap.js') 9 10var testdir = common.pkg 11var modAdir = path.resolve(testdir, 'modA') 12var modB1dir = path.resolve(testdir, 'modB@1') 13var modB2dir = path.resolve(testdir, 'modB@2') 14var modCdir = path.resolve(testdir, 'modC') 15 16var fixture = new Tacks(Dir({ 17 'package.json': File({ 18 dependencies: { 19 modA: 'file://' + modAdir 20 }, 21 devDependencies: { 22 modC: 'file://' + modCdir 23 } 24 }), 25 'npm-shrinkwrap.json': File({ 26 requires: true, 27 lockfileVersion: 1, 28 dependencies: { 29 modA: { 30 version: 'file://' + modAdir, 31 requires: { 32 modB: 'file://' + modB1dir 33 } 34 }, 35 modB: { 36 version: 'file://' + modB1dir 37 } 38 } 39 }), 40 'modA': Dir({ 41 'package.json': File({ 42 name: 'modA', 43 version: '1.0.0', 44 dependencies: { 45 'modB': 'file://' + modB1dir 46 } 47 }) 48 }), 49 'modB@1': Dir({ 50 'package.json': File({ 51 name: 'modB', 52 version: '1.0.0' 53 }), 54 'B1': File('') 55 }), 56 'modB@2': Dir({ 57 'package.json': File({ 58 name: 'modB', 59 version: '2.0.0' 60 }), 61 'B2': File('') 62 }), 63 'modC': Dir({ 64 'package.json': File({ 65 name: 'modC', 66 version: '1.0.0', 67 dependencies: { 68 'modB': 'file://' + modB2dir 69 } 70 }) 71 }) 72})) 73 74function setup () { 75 fixture.create(testdir) 76} 77 78function cleanup () { 79 fixture.remove(testdir) 80} 81 82test('setup', function (t) { 83 cleanup() 84 setup() 85 t.end() 86}) 87 88// Shrinkwraps need to let you override dependency versions specified in 89// package.json files. Indeed, this was already supported, but it was a bit 90// to keen on this. Previously, if you had a dep in your shrinkwrap then 91// anything that required that dependency would count as a match, regardless 92// of version. 93 94// This test ensures that the broad matching is not done when the matched 95// module is not a direct child of the module doing the requiring. 96 97test('bundled', function (t) { 98 common.npm(['install'], {cwd: testdir}, function (err, code, out, stderr) { 99 t.is(err, null, 'No fatal errors running npm') 100 t.is(code, 0, 'npm itself completed ok') 101 // Specifically, if B2 exists (or the modB directory under modC at all) 102 // that means modC was given its own copy of modB. Without the patch 103 // that went with this test, it wouldn't have been installed because npm 104 // would have consider modB@1 to have fulfilled modC's requirement. 105 fs.stat(path.join(testdir, 'node_modules', 'modC', 'node_modules', 'modB', 'B2'), function (missing) { 106 t.ok(!missing, 'modC got the right version of modB') 107 t.end() 108 }) 109 }) 110}) 111 112test('cleanup', function (t) { 113 cleanup() 114 t.end() 115}) 116