• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict'
2var Bluebird = require('bluebird')
3var test = require('tap').test
4var fs = require('fs')
5var mkdirp = require('mkdirp')
6var rimraf = require('rimraf')
7var path = require('path')
8var common = require('../common-tap.js')
9
10var testname = path.basename(__filename, '.js')
11var testdir = common.pkg
12var testmod = path.resolve(testdir, 'top-test')
13var testtgz = testmod + '-1.0.0.tgz'
14
15var bundleupdatesrc = path.resolve(testmod, 'bundle-update')
16var bundleupdatetgz = bundleupdatesrc + '-1.0.0.tgz'
17var bundleupdateNEW = path.resolve(bundleupdatesrc, 'NEW')
18var bundleupdateNEWpostinstall = path.resolve(testdir, 'node_modules', 'bundle-update', 'NEW')
19var bundleupdatebad = path.resolve(testmod, 'node_modules', 'bundle-update')
20
21var bundlekeepsrc = path.resolve(testmod, 'bundle-keep')
22var bundlekeeptgz = bundlekeepsrc + '-1.0.0.tgz'
23var bundlekeep = path.resolve(testmod, 'node_modules', 'bundle-keep')
24var bundlekeepOLD = path.resolve(bundlekeep, 'OLD')
25var bundlekeepOLDpostinstall = path.resolve(testdir, 'node_modules', 'top-test', 'node_modules', 'bundle-keep', 'OLD')
26
27var bundledeepsrc = path.resolve(testmod, 'bundle-deep')
28var bundledeeptgz = bundledeepsrc + '-1.0.0.tgz'
29var bundledeep = path.resolve(testmod, 'node_modules', 'bundle-deep')
30var bundledeepOLD = path.resolve(bundledeep, 'OLD')
31var bundledeepOLDpostinstall = path.resolve(testdir, 'node_modules', 'top-test', 'node_modules', 'bundle-deep', 'OLD')
32
33var bundledeepupdatesrc = path.resolve(testmod, 'bundle-deep-update')
34var bundledeepupdatetgz = bundledeepupdatesrc + '-1.0.0.tgz'
35var bundledeepupdate = path.resolve(bundledeep, 'node_modules', 'bundle-deep-update')
36var bundledeepupdateNEW = path.resolve(bundledeepupdatesrc, 'NEW')
37var bundledeepupdateNEWpostinstall = path.resolve(testdir, 'node_modules', 'bundle-deep-update', 'NEW')
38
39var testjson = {
40  dependencies: {'top-test': 'file:' + testtgz}
41}
42
43var testmodjson = {
44  name: 'top-test',
45  version: '1.0.0',
46  dependencies: {
47    'bundle-update': bundleupdatetgz,
48    'bundle-keep': bundlekeeptgz,
49    'bundle-deep': bundledeeptgz
50  },
51  bundledDependencies: ['bundle-update', 'bundle-keep', 'bundle-deep'],
52  files: ['OLD', 'NEW']
53}
54var bundlejson = {
55  name: 'bundle-update',
56  version: '1.0.0',
57  files: ['OLD', 'NEW']
58}
59
60var bundlekeepjson = {
61  name: 'bundle-keep',
62  version: '1.0.0',
63  _requested: {
64    rawSpec: bundlekeeptgz
65  },
66  _resolved: bundlekeeptgz,
67  _shasum: 'baadf00d',
68  files: ['OLD', 'NEW']
69
70}
71var bundledeepjson = {
72  name: 'bundle-deep',
73  version: '1.0.0',
74  dependencies: {
75    'bundle-deep-update': bundledeepupdatetgz
76  },
77  _requested: {
78    rawSpec: bundledeeptgz
79  },
80  _resolved: bundlekeeptgz,
81  _shasum: 'deadbeef',
82  files: ['OLD', 'NEW']
83
84}
85
86var bundledeepupdatejson = {
87  version: '1.0.0',
88  name: 'bundle-deep-update',
89  files: ['OLD', 'NEW']
90
91}
92
93function writepjs (dir, content) {
94  fs.writeFileSync(path.join(dir, 'package.json'), JSON.stringify(content, null, 2))
95}
96
97function setup () {
98  mkdirp.sync(testdir)
99  writepjs(testdir, testjson)
100  mkdirp.sync(testmod)
101  writepjs(testmod, testmodjson)
102
103  mkdirp.sync(bundleupdatesrc)
104  writepjs(bundleupdatesrc, bundlejson)
105  fs.writeFileSync(bundleupdateNEW, '')
106  mkdirp.sync(bundleupdatebad)
107  writepjs(bundleupdatebad, bundlejson)
108
109  mkdirp.sync(bundlekeepsrc)
110  writepjs(bundlekeepsrc, bundlekeepjson)
111  mkdirp.sync(bundlekeep)
112  writepjs(bundlekeep, bundlekeepjson)
113  fs.writeFileSync(bundlekeepOLD, '')
114
115  mkdirp.sync(bundledeepsrc)
116  writepjs(bundledeepsrc, bundledeepjson)
117  mkdirp.sync(bundledeep)
118  writepjs(bundledeep, bundledeepjson)
119  fs.writeFileSync(bundledeepOLD, '')
120
121  mkdirp.sync(bundledeepupdatesrc)
122  writepjs(bundledeepupdatesrc, bundledeepupdatejson)
123  mkdirp.sync(bundledeepupdate)
124  writepjs(bundledeepupdate, bundledeepupdatejson)
125  fs.writeFileSync(bundledeepupdateNEW, '')
126}
127
128function cleanup () {
129  rimraf.sync(testdir)
130}
131
132test('setup', function (t) {
133  cleanup()
134  setup()
135  return Bluebird.all([
136    common.npm(['pack', bundleupdatesrc], {cwd: path.dirname(bundleupdatetgz), stdio: 'inherit'}),
137    common.npm(['pack', bundlekeepsrc], {cwd: path.dirname(bundlekeeptgz), stdio: 'inherit'}),
138    common.npm(['pack', bundledeepupdatesrc], {cwd: path.dirname(bundledeepupdatetgz), stdio: 'inherit'})
139  ]).map((result) => result[0]).spread((bundleupdate, bundlekeep, bundledeepupdate) => {
140    t.is(bundleupdate, 0, 'bundleupdate')
141    t.is(bundlekeep, 0, 'bundlekeep')
142    t.is(bundledeepupdate, 0, 'bundledeepupdate')
143  }).then(() => {
144    return common.npm(['pack', bundledeepsrc], {cwd: path.dirname(bundledeeptgz), stdio: 'inherit'})
145  }).spread((code) => {
146    t.is(code, 0, 'bundledeep')
147    return common.npm(['pack', testmod], {cwd: path.dirname(testtgz), stdio: 'inherit'})
148  }).spread((code) => {
149    t.is(code, 0, 'testmod')
150  })
151})
152
153test('bundled', function (t) {
154  common.npm(['install', '--loglevel=verbose'], {cwd: testdir}, function (err, code, stdout, stderr) {
155    if (err) throw err
156    t.plan(9)
157    t.is(code, 0, 'npm itself completed ok')
158
159    // This tests that after the install we have a freshly installed version
160    // of `bundle-update` (in alignment with the package.json), instead of the
161    // version that was bundled with `top-test`.
162    // If npm doesn't do this, and selects the bundled version, things go very
163    // wrong because npm thinks it has a different module (with different
164    // metadata) installed in that location and will go off and try to do
165    // _things_ to it.  Things like chmod in particular, which in turn results
166    // in the dreaded ENOENT errors.
167    t.like(stderr, new RegExp('npm WARN ' + testname), "didn't stomp on other warnings")
168    t.like(stderr, /npm verb.*bundle-update/, 'included update warning about bundled dep')
169    t.like(stderr, /npm verb.*bundle-deep-update/, 'included update warning about deeply bundled dep')
170    t.like(stderr, /npm WARN top-test@1\.0\.0 had bundled packages that do not match/, 'single grouped warning')
171    fs.stat(bundleupdateNEWpostinstall, function (missing) {
172      t.ok(!missing, 'package.json overrode bundle')
173    })
174    fs.stat(bundledeepupdateNEWpostinstall, function (missing) {
175      t.ok(!missing, 'deep package.json overrode bundle')
176    })
177    // Relatedly, when upgrading, if a bundled module is replacing an existing
178    // module we want to choose the bundled version, not the version we're replacing.
179    fs.stat(bundlekeepOLDpostinstall, function (missing) {
180      t.ok(!missing, 'no override when package.json matches')
181    })
182    fs.stat(bundledeepOLDpostinstall, function (missing) {
183      t.ok(!missing, 'deep no override when package.json matches')
184    })
185  })
186})
187
188test('cleanup', function (t) {
189  cleanup()
190  t.end()
191})
192