aboutsummaryrefslogtreecommitdiff
path: root/deps/npm/test
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/test')
-rw-r--r--deps/npm/test/common-tap.js1
-rw-r--r--deps/npm/test/network/bearer-token-check.js (renamed from deps/npm/test/tap/bearer-token-check.js)0
-rw-r--r--deps/npm/test/network/git-cache-locking.js (renamed from deps/npm/test/tap/git-cache-locking.js)0
-rw-r--r--deps/npm/test/network/git-cache-no-hooks.js (renamed from deps/npm/test/tap/git-cache-no-hooks.js)0
-rw-r--r--deps/npm/test/network/it.js (renamed from deps/npm/test/tap/it.js)0
-rw-r--r--deps/npm/test/network/legacy-bundled-git.js (renamed from deps/npm/test/tap/legacy-bundled-git.js)0
-rw-r--r--deps/npm/test/network/legacy-optional-deps.js (renamed from deps/npm/test/tap/legacy-optional-deps.js)0
-rw-r--r--deps/npm/test/network/legacy-shrinkwrap.js (renamed from deps/npm/test/tap/legacy-shrinkwrap.js)0
-rw-r--r--deps/npm/test/network/legacy-url-dep.js (renamed from deps/npm/test/tap/legacy-url-dep.js)0
-rw-r--r--deps/npm/test/network/outdated-symlink.js (renamed from deps/npm/test/tap/outdated-symlink.js)0
-rw-r--r--deps/npm/test/network/registry.js (renamed from deps/npm/test/tap/registry.js)0
-rw-r--r--deps/npm/test/tap/404-private-registry-scoped.js25
-rw-r--r--deps/npm/test/tap/404-private-registry.js22
-rw-r--r--deps/npm/test/tap/add-local.js137
-rw-r--r--deps/npm/test/tap/bundled-dependencies.js112
-rw-r--r--deps/npm/test/tap/correct-mkdir.js105
-rw-r--r--deps/npm/test/tap/files-and-ignores.js7
-rw-r--r--deps/npm/test/tap/full-warning-messages.js4
-rw-r--r--deps/npm/test/tap/install-cli-only-shrinkwrap.js139
-rw-r--r--deps/npm/test/tap/install-parse-error.js1
-rw-r--r--deps/npm/test/tap/install-property-conflicts.js74
-rw-r--r--deps/npm/test/tap/install-shrinkwrapped-git.js159
-rw-r--r--deps/npm/test/tap/invalid-dep-version-filtering.js135
-rw-r--r--deps/npm/test/tap/lifecycle-order.js57
-rw-r--r--deps/npm/test/tap/lifecycle-path.js39
-rw-r--r--deps/npm/test/tap/local-args-relative-to-cwd.js65
-rw-r--r--deps/npm/test/tap/node-modules-path-munge.js39
-rw-r--r--deps/npm/test/tap/optional-metadep-rollback-collision.js6
-rw-r--r--deps/npm/test/tap/shrinkwrap-default-arg-ver.js104
-rw-r--r--deps/npm/test/tap/shrinkwrap-dev-dep-cycle.js93
-rw-r--r--deps/npm/test/tap/shrinkwrap-local-dependency.js188
-rw-r--r--deps/npm/test/tap/shrinkwrap-optional-platform.js96
-rw-r--r--deps/npm/test/tap/shrinkwrap-optional-property.js100
-rw-r--r--deps/npm/test/tap/shrinkwrap-prod-dependency-also.js1
-rw-r--r--deps/npm/test/tap/shrinkwrap-prod-dependency.js1
-rw-r--r--deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js102
-rw-r--r--deps/npm/test/tap/shrinkwrap-save-dev-without-existing-dev-deps.js87
-rw-r--r--deps/npm/test/tap/shrinkwrap-transitive-dev.js83
-rw-r--r--deps/npm/test/tap/update-symlink.js118
39 files changed, 1944 insertions, 156 deletions
diff --git a/deps/npm/test/common-tap.js b/deps/npm/test/common-tap.js
index 847c87ba0f..14c1581f78 100644
--- a/deps/npm/test/common-tap.js
+++ b/deps/npm/test/common-tap.js
@@ -45,6 +45,7 @@ exports.npm = function (cmd, opts, cb) {
if (!opts.env.npm_config_cache) {
opts.env.npm_config_cache = npm_config_cache
}
+ nodeBin = opts.nodeExecPath || nodeBin
var stdout = ''
var stderr = ''
diff --git a/deps/npm/test/tap/bearer-token-check.js b/deps/npm/test/network/bearer-token-check.js
index 8ddbec29a4..8ddbec29a4 100644
--- a/deps/npm/test/tap/bearer-token-check.js
+++ b/deps/npm/test/network/bearer-token-check.js
diff --git a/deps/npm/test/tap/git-cache-locking.js b/deps/npm/test/network/git-cache-locking.js
index 29ab5709b9..29ab5709b9 100644
--- a/deps/npm/test/tap/git-cache-locking.js
+++ b/deps/npm/test/network/git-cache-locking.js
diff --git a/deps/npm/test/tap/git-cache-no-hooks.js b/deps/npm/test/network/git-cache-no-hooks.js
index 0021064cea..0021064cea 100644
--- a/deps/npm/test/tap/git-cache-no-hooks.js
+++ b/deps/npm/test/network/git-cache-no-hooks.js
diff --git a/deps/npm/test/tap/it.js b/deps/npm/test/network/it.js
index 6fc2a6fd49..6fc2a6fd49 100644
--- a/deps/npm/test/tap/it.js
+++ b/deps/npm/test/network/it.js
diff --git a/deps/npm/test/tap/legacy-bundled-git.js b/deps/npm/test/network/legacy-bundled-git.js
index 15fbac84ea..15fbac84ea 100644
--- a/deps/npm/test/tap/legacy-bundled-git.js
+++ b/deps/npm/test/network/legacy-bundled-git.js
diff --git a/deps/npm/test/tap/legacy-optional-deps.js b/deps/npm/test/network/legacy-optional-deps.js
index 80ad7cc47e..80ad7cc47e 100644
--- a/deps/npm/test/tap/legacy-optional-deps.js
+++ b/deps/npm/test/network/legacy-optional-deps.js
diff --git a/deps/npm/test/tap/legacy-shrinkwrap.js b/deps/npm/test/network/legacy-shrinkwrap.js
index 6f53030377..6f53030377 100644
--- a/deps/npm/test/tap/legacy-shrinkwrap.js
+++ b/deps/npm/test/network/legacy-shrinkwrap.js
diff --git a/deps/npm/test/tap/legacy-url-dep.js b/deps/npm/test/network/legacy-url-dep.js
index 46378cd3ef..46378cd3ef 100644
--- a/deps/npm/test/tap/legacy-url-dep.js
+++ b/deps/npm/test/network/legacy-url-dep.js
diff --git a/deps/npm/test/tap/outdated-symlink.js b/deps/npm/test/network/outdated-symlink.js
index 809cfec2e2..809cfec2e2 100644
--- a/deps/npm/test/tap/outdated-symlink.js
+++ b/deps/npm/test/network/outdated-symlink.js
diff --git a/deps/npm/test/tap/registry.js b/deps/npm/test/network/registry.js
index d8ec4a204e..d8ec4a204e 100644
--- a/deps/npm/test/tap/registry.js
+++ b/deps/npm/test/network/registry.js
diff --git a/deps/npm/test/tap/404-private-registry-scoped.js b/deps/npm/test/tap/404-private-registry-scoped.js
index 84251b113c..0f0cbc4ec7 100644
--- a/deps/npm/test/tap/404-private-registry-scoped.js
+++ b/deps/npm/test/tap/404-private-registry-scoped.js
@@ -1,9 +1,24 @@
var test = require('tap').test
+var path = require('path')
+var mkdirp = require('mkdirp')
+var rimraf = require('rimraf')
var common = require('../common-tap.js')
var mr = require('npm-registry-mock')
var server
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+
+function setup () {
+ cleanup()
+ mkdirp.sync(testdir)
+}
+
+function cleanup () {
+ rimraf.sync(testdir)
+}
+
test('setup', function (t) {
+ setup()
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
t.ifError(err, 'registry mocked successfully')
server = s
@@ -12,8 +27,11 @@ test('setup', function (t) {
})
test('scoped package names not mangled on error with non-root registry', function (t) {
+ server.get('/@scope%2ffoo').reply(404, {})
common.npm(
[
+ '--registry=' + common.registry,
+ '--cache=' + testdir,
'cache',
'add',
'@scope/foo@*',
@@ -23,16 +41,17 @@ test('scoped package names not mangled on error with non-root registry', functio
function (er, code, stdout, stderr) {
t.ifError(er, 'correctly handled 404')
t.equal(code, 1, 'exited with error')
- t.match(stderr, /404 Not found/, 'should notify the sort of error as a 404')
+ t.match(stderr, /E404/, 'should notify the sort of error as a 404')
t.match(stderr, /@scope\/foo/, 'should have package name in error')
+ server.done()
t.end()
}
)
})
test('cleanup', function (t) {
- t.pass('cleaned up')
- server.done()
server.close()
+ cleanup()
+ t.pass('cleaned up')
t.end()
})
diff --git a/deps/npm/test/tap/404-private-registry.js b/deps/npm/test/tap/404-private-registry.js
index a30f61432a..a38fa02c12 100644
--- a/deps/npm/test/tap/404-private-registry.js
+++ b/deps/npm/test/tap/404-private-registry.js
@@ -1,13 +1,25 @@
-require('../common-tap')
var test = require('tap').test
var path = require('path')
+var mkdirp = require('mkdirp')
+var rimraf = require('rimraf')
var common = require('../common-tap.js')
var mr = require('npm-registry-mock')
var server
var packageName = path.basename(__filename, '.js')
+var testdir = path.join(__dirname, packageName)
+
+function setup () {
+ cleanup()
+ mkdirp.sync(testdir)
+}
+
+function cleanup () {
+ rimraf.sync(testdir)
+}
test('setup', function (t) {
+ setup()
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
t.ifError(err, 'registry mocked successfully')
server = s
@@ -16,8 +28,11 @@ test('setup', function (t) {
})
test('package names not mangled on error with non-root registry', function (t) {
+ server.get('/' + packageName).reply(404, {})
common.npm(
[
+ '--registry=' + common.registry,
+ '--cache=' + testdir,
'cache',
'add',
packageName + '@*'
@@ -27,14 +42,15 @@ test('package names not mangled on error with non-root registry', function (t) {
t.ifError(er, 'correctly handled 404')
t.equal(code, 1, 'exited with error')
t.match(stderr, packageName, 'should have package name in error')
+ server.done()
t.end()
}
)
})
test('cleanup', function (t) {
- t.pass('cleaned up')
- server.done()
server.close()
+ cleanup()
+ t.pass('cleaned up')
t.end()
})
diff --git a/deps/npm/test/tap/add-local.js b/deps/npm/test/tap/add-local.js
new file mode 100644
index 0000000000..cc615b8997
--- /dev/null
+++ b/deps/npm/test/tap/add-local.js
@@ -0,0 +1,137 @@
+var path = require('path')
+var test = require('tap').test
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var requireInject = require('require-inject')
+
+var pkg = path.join(__dirname, '/local-dir')
+var cache = path.join(pkg, '/cache')
+var tmp = path.join(pkg, '/tmp')
+var prefix = path.join(pkg, '/prefix')
+
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+
+test('addLocal directory race on Windows', function (t) {
+ setup()
+ var p = {
+ name: 'test',
+ version: '1.0.0',
+ type: 'directory',
+ spec: pkg
+ }
+ var fixture = new Tacks(
+ Dir({
+ 'package.json': File(p)
+ })
+ )
+ var addLocal = requireInject('../../lib/cache/add-local', {
+ '../../lib/npm.js': {
+ cache: cache,
+ tmp: tmp,
+ prefix: prefix
+ },
+ '../../lib/cache/get-stat': function (cb) {
+ cb(null, {})
+ },
+ chownr: function (x, y, z, cb) {
+ cb(new Error('chownr should never have been called'))
+ },
+ '../../lib/cache/add-local-tarball.js': function (tgz, data, shasum, cb) {
+ cb(null)
+ },
+ '../../lib/utils/lifecycle.js': function (data, cycle, p, cb) {
+ cb(null)
+ },
+ '../../lib/utils/tar.js': {
+ pack: function (tgz, p, data, cb) {
+ cb(null)
+ }
+ },
+ 'sha': {
+ get: function (tgz, cb) {
+ cb(null, 'deadbeef')
+ }
+ }
+ })
+
+ fixture.create(pkg)
+ addLocal(p, null, function (err) {
+ t.ifErr(err, 'addLocal completed without error')
+ t.done()
+ })
+})
+
+test('addLocal temporary cache file race', function (t) {
+ // See https://github.com/npm/npm/issues/12669
+ setup()
+ var p = {
+ name: 'test',
+ version: '1.0.0',
+ type: 'directory',
+ spec: pkg
+ }
+ var fixture = new Tacks(
+ Dir({
+ 'package.json': File(p)
+ })
+ )
+ var addLocal = requireInject('../../lib/cache/add-local', {
+ // basic setup/mock stuff
+ '../../lib/npm.js': {
+ cache: cache,
+ tmp: tmp,
+ prefix: prefix
+ },
+ '../../lib/cache/add-local-tarball.js': function (tgz, data, shasum, cb) {
+ cb(null)
+ },
+ '../../lib/utils/lifecycle.js': function (data, cycle, p, cb) {
+ cb(null)
+ },
+ '../../lib/utils/tar.js': {
+ pack: function (tgz, p, data, cb) {
+ cb(null)
+ }
+ },
+ 'sha': {
+ get: function (tgz, cb) {
+ cb(null, 'deadbeef')
+ }
+ },
+
+ // Test-specific mocked values to simulate race.
+ '../../lib/cache/get-stat': function (cb) {
+ cb(null, {uid: 1, gid: 2})
+ },
+ chownr: function (x, y, z, cb) {
+ // Simulate a race condition between `tar.pack` and `chownr`
+ // where the latter will return `ENOENT` when an async process
+ // removes a file that its internal `fs.readdir` listed.
+ cb({code: 'ENOENT'})
+ }
+ })
+
+ fixture.create(pkg)
+ addLocal(p, null, function (err) {
+ t.ifErr(err, 'addLocal completed without error')
+ t.done()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.done()
+})
+
+function setup () {
+ mkdirp.sync(cache)
+ mkdirp.sync(tmp)
+}
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+}
diff --git a/deps/npm/test/tap/bundled-dependencies.js b/deps/npm/test/tap/bundled-dependencies.js
new file mode 100644
index 0000000000..a49610e666
--- /dev/null
+++ b/deps/npm/test/tap/bundled-dependencies.js
@@ -0,0 +1,112 @@
+'use strict'
+var test = require('tap').test
+var common = require('../common-tap.js')
+var path = require('path')
+var rimraf = require('rimraf')
+var mkdirp = require('mkdirp')
+var fs = require('graceful-fs')
+var tar = require('tar')
+var zlib = require('zlib')
+var basepath = path.resolve(__dirname, path.basename(__filename, '.js'))
+var fixturepath = path.resolve(basepath, 'npm-test-bundled-deps')
+var targetpath = path.resolve(basepath, 'target')
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+
+test('basic bundling', function (t) {
+ var fixture = new Tacks(
+ Dir({
+ 'package.json': File({
+ name: 'npm-test-files',
+ version: '1.2.5',
+ bundledDependencies: [
+ 'addme'
+ ]
+ }),
+ node_modules: Dir({
+ addme: Dir({
+ 'index.js': File('')
+ }),
+ iggyme: Dir({
+ 'index.js': File('')
+ })
+ })
+ })
+ )
+ withFixture(t, fixture, function (done) {
+ t.ok(fileExists('node_modules/addme'), 'bundled dep included')
+ t.notOk(fileExists('node_modules/iggyme'), 'unspecified dep not included')
+ done()
+ })
+})
+
+test('scoped dep bundling', function (t) {
+ var fixture = new Tacks(
+ Dir({
+ 'package.json': File({
+ name: 'npm-test-files',
+ version: '1.2.5',
+ bundledDependencies: [
+ '@foo/addme'
+ ]
+ }),
+ node_modules: Dir({
+ '@foo': Dir({
+ addme: Dir({
+ 'index.js': File('')
+ }),
+ iggyme: Dir({
+ 'index.js': File('')
+ })
+ })
+ })
+ })
+ )
+ withFixture(t, fixture, function (done) {
+ t.ok(fileExists('node_modules/@foo/addme'), 'bundled dep included')
+ t.notOk(
+ fileExists('node_modules/@foo/iggyme'),
+ 'unspecified dep not included')
+ done()
+ })
+})
+
+function fileExists (file) {
+ try {
+ return !!fs.statSync(path.resolve(targetpath, 'package', file))
+ } catch (_) {
+ return false
+ }
+}
+
+function withFixture (t, fixture, tester) {
+ fixture.create(fixturepath)
+ mkdirp.sync(targetpath)
+ common.npm(['pack', fixturepath], {cwd: basepath}, extractAndCheck)
+ function extractAndCheck (err, code) {
+ if (err) throw err
+ t.is(code, 0, 'pack went ok')
+ extractTarball(checkTests)
+ }
+ function checkTests (err) {
+ if (err) throw err
+ tester(removeAndDone)
+ }
+ function removeAndDone (err) {
+ if (err) throw err
+ fixture.remove(fixturepath)
+ rimraf.sync(basepath)
+ t.done()
+ }
+}
+
+function extractTarball (cb) {
+ // Unpack to disk so case-insensitive filesystems are consistent
+ fs.createReadStream(path.join(basepath, 'npm-test-files-1.2.5.tgz'))
+ .pipe(zlib.Unzip())
+ .on('error', cb)
+ .pipe(tar.Extract(targetpath))
+ .on('error', cb)
+ .on('end', function () { cb() })
+}
diff --git a/deps/npm/test/tap/correct-mkdir.js b/deps/npm/test/tap/correct-mkdir.js
index 4bfc6b1c97..a4f8659873 100644
--- a/deps/npm/test/tap/correct-mkdir.js
+++ b/deps/npm/test/tap/correct-mkdir.js
@@ -56,3 +56,108 @@ test('correct-mkdir: no race conditions', function (t) {
// Immediate call again in case of race condition there
correctMkdir(cache_dir, handleCallFinish)
})
+
+test('correct-mkdir: ignore ENOENTs from chownr', function (t) {
+ var mock_fs = {}
+ mock_fs.stat = function (path, cb) {
+ if (path === cache_dir) {
+ cb(null, {
+ isDirectory: function () {
+ return true
+ }
+ })
+ } else {
+ assert.ok(false, 'Unhandled stat path: ' + path)
+ }
+ }
+ var mock_chownr = function (path, uid, gid, cb) {
+ cb({code: 'ENOENT'})
+ }
+ var mocks = {
+ 'graceful-fs': mock_fs,
+ 'chownr': mock_chownr
+ }
+ var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
+
+ function handleCallFinish (err) {
+ t.ifErr(err, 'chownr\'s ENOENT errors were ignored')
+ t.end()
+ }
+ correctMkdir(cache_dir, handleCallFinish)
+})
+
+// NEED TO RUN LAST
+
+// These test checks that Windows users are protected by crashes related to
+// unexpectedly having a UID/GID other than 0 if a user happens to add these
+// variables to their environment. There are assumptions in correct-mkdir
+// that special-case Windows by checking on UID-related things.
+test('correct-mkdir: SUDO_UID and SUDO_GID non-Windows', function (t) {
+ process.env.SUDO_UID = 999
+ process.env.SUDO_GID = 999
+ process.getuid = function () { return 0 }
+ process.getgid = function () { return 0 }
+ var mock_fs = {}
+ mock_fs.stat = function (path, cb) {
+ if (path === cache_dir) {
+ cb(null, {
+ uid: 0,
+ isDirectory: function () {
+ return true
+ }
+ })
+ } else {
+ assert.ok(false, 'Unhandled stat path: ' + path)
+ }
+ }
+ var mock_chownr = function (path, uid, gid, cb) {
+ t.is(uid, +process.env.SUDO_UID, 'using the environment\'s UID')
+ t.is(gid, +process.env.SUDO_GID, 'using the environment\'s GID')
+ cb(null, {})
+ }
+ var mocks = {
+ 'graceful-fs': mock_fs,
+ 'chownr': mock_chownr
+ }
+ var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
+
+ function handleCallFinish () {
+ t.end()
+ }
+ correctMkdir(cache_dir, handleCallFinish)
+})
+
+test('correct-mkdir: SUDO_UID and SUDO_GID Windows', function (t) {
+ process.env.SUDO_UID = 999
+ process.env.SUDO_GID = 999
+ delete process.getuid
+ delete process.getgid
+ var mock_fs = {}
+ mock_fs.stat = function (path, cb) {
+ if (path === cache_dir) {
+ cb(null, {
+ uid: 0,
+ isDirectory: function () {
+ return true
+ }
+ })
+ } else {
+ assert.ok(false, 'Unhandled stat path: ' + path)
+ }
+ }
+ var mock_chownr = function (path, uid, gid, cb) {
+ t.fail('chownr should not be called at all on Windows')
+ cb('nope')
+ }
+ var mocks = {
+ 'graceful-fs': mock_fs,
+ 'chownr': mock_chownr
+ }
+ var correctMkdir = requireInject('../../lib/utils/correct-mkdir.js', mocks)
+
+ function handleCallFinish (err) {
+ t.ifErr(err, 'chownr was not called because Windows')
+ t.end()
+ }
+ correctMkdir(cache_dir, handleCallFinish)
+})
diff --git a/deps/npm/test/tap/files-and-ignores.js b/deps/npm/test/tap/files-and-ignores.js
index a8f4b222b8..88d9d12922 100644
--- a/deps/npm/test/tap/files-and-ignores.js
+++ b/deps/npm/test/tap/files-and-ignores.js
@@ -404,7 +404,8 @@ test('certain files ignored unconditionally', function (t) {
'.npmrc',
'.foo.swp',
'.DS_Store',
- '._ohno'
+ '._ohno',
+ 'foo.orig'
]
}),
'.git': Dir({foo: File('')}),
@@ -421,7 +422,8 @@ test('certain files ignored unconditionally', function (t) {
'.foo.swp': File(''),
'.DS_Store': Dir({foo: File('')}),
'._ohno': File(''),
- '._ohnoes': Dir({noes: File('')})
+ '._ohnoes': Dir({noes: File('')}),
+ 'foo.orig': File('')
})
)
withFixture(t, fixture, function (done) {
@@ -440,6 +442,7 @@ test('certain files ignored unconditionally', function (t) {
t.notOk(fileExists('.DS_Store'), '.DS_Store not included')
t.notOk(fileExists('._ohno'), '._ohno not included')
t.notOk(fileExists('._ohnoes'), '._ohnoes not included')
+ t.notOk(fileExists('foo.orig'), 'foo.orig not included')
done()
})
})
diff --git a/deps/npm/test/tap/full-warning-messages.js b/deps/npm/test/tap/full-warning-messages.js
index 3c74c61d0c..6745ee3db2 100644
--- a/deps/npm/test/tap/full-warning-messages.js
+++ b/deps/npm/test/tap/full-warning-messages.js
@@ -94,8 +94,8 @@ test('tree-style', function (t) {
t.notMatch(stdout, /modB/, 'modB not installed')
var stderrlines = stderr.trim().split(/\n/)
t.is(stderrlines.length, 2, 'two lines of warnings')
- t.match(stderr, /Skipping failed optional dependency/, 'expected optional failure warning')
- t.match(stderr, /Not compatible with your operating system or architecture/, 'reason for optional failure')
+ t.match(stderr, /SKIPPING OPTIONAL DEPENDENCY/, 'expected optional failure warning')
+ t.match(stderr, /Unsupported platform/, 'reason for optional failure')
exists(t, modJoin(base, 'modA'), 'module A')
notExists(t, modJoin(base, 'modB'), 'module B')
t.done()
diff --git a/deps/npm/test/tap/install-cli-only-shrinkwrap.js b/deps/npm/test/tap/install-cli-only-shrinkwrap.js
new file mode 100644
index 0000000000..17ff1ec955
--- /dev/null
+++ b/deps/npm/test/tap/install-cli-only-shrinkwrap.js
@@ -0,0 +1,139 @@
+var fs = require('graceful-fs')
+var path = require('path')
+var existsSync = fs.existsSync || path.existsSync
+
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var pkg = path.join(__dirname, path.basename(__filename, '.js'))
+
+var EXEC_OPTS = { cwd: pkg }
+
+var json = {
+ name: 'install-cli-only-shrinkwrap',
+ description: 'fixture',
+ version: '0.0.0',
+ dependencies: {
+ dependency: 'file:./dependency'
+ },
+ devDependencies: {
+ 'dev-dependency': 'file:./dev-dependency'
+ }
+}
+
+var shrinkwrap = {
+ name: 'install-cli-only-shrinkwrap',
+ description: 'fixture',
+ version: '0.0.0',
+ dependencies: {
+ dependency: {
+ version: '0.0.0',
+ from: 'file:./dependency'
+ },
+ 'dev-dependency': {
+ version: '0.0.0',
+ from: 'file:./dev-dependency',
+ dev: true
+ }
+ }
+}
+
+var dependency = {
+ name: 'dependency',
+ description: 'fixture',
+ version: '0.0.0'
+}
+
+var devDependency = {
+ name: 'dev-dependency',
+ description: 'fixture',
+ version: '0.0.0'
+}
+
+test('setup', function (t) {
+ setup()
+ t.pass('setup ran')
+ t.end()
+})
+
+test('\'npm install --only=development\' should only install devDependencies', function (t) {
+ common.npm(['install', '--only=development'], EXEC_OPTS, function (err, code, stderr, stdout) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.is(code, 0, 'npm install did not raise error code')
+ t.ok(
+ existsSync(
+ path.resolve(pkg, 'node_modules/dev-dependency/package.json')
+ ),
+ 'devDependency was installed'
+ )
+ t.notOk(
+ existsSync(path.resolve(pkg, 'node_modules/dependency/package.json')),
+ 'dependency was NOT installed'
+ )
+ t.end()
+ })
+})
+
+test('\'npm install --only=production\' should only install dependencies', function (t) {
+ cleanup()
+ setup()
+ common.npm(['install', '--only=production'], EXEC_OPTS, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.is(code, 0, 'npm install did not raise error code')
+ t.ok(
+ existsSync(
+ path.resolve(pkg, 'node_modules/dependency/package.json')
+ ),
+ 'dependency was installed'
+ )
+ t.notOk(
+ existsSync(path.resolve(pkg, 'node_modules/dev-dependency/package.json')),
+ 'devDependency was NOT installed'
+ )
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.pass('cleaned up')
+ t.end()
+})
+
+function setup () {
+ mkdirp.sync(path.join(pkg, 'dependency'))
+ fs.writeFileSync(
+ path.join(pkg, 'dependency', 'package.json'),
+ JSON.stringify(dependency, null, 2)
+ )
+
+ mkdirp.sync(path.join(pkg, 'dev-dependency'))
+ fs.writeFileSync(
+ path.join(pkg, 'dev-dependency', 'package.json'),
+ JSON.stringify(devDependency, null, 2)
+ )
+
+ mkdirp.sync(path.join(pkg, 'node_modules'))
+ fs.writeFileSync(
+ path.join(pkg, 'package.json'),
+ JSON.stringify(json, null, 2)
+ )
+ fs.writeFileSync(
+ path.join(pkg, 'npm-shrinkwrap.json'),
+ JSON.stringify(shrinkwrap, null, 2)
+ )
+ process.chdir(pkg)
+}
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+}
diff --git a/deps/npm/test/tap/install-parse-error.js b/deps/npm/test/tap/install-parse-error.js
index b142abb39a..72d19efc25 100644
--- a/deps/npm/test/tap/install-parse-error.js
+++ b/deps/npm/test/tap/install-parse-error.js
@@ -49,3 +49,4 @@ test('cleanup', function (t) {
cleanup()
t.end()
})
+
diff --git a/deps/npm/test/tap/install-property-conflicts.js b/deps/npm/test/tap/install-property-conflicts.js
new file mode 100644
index 0000000000..8f293885ab
--- /dev/null
+++ b/deps/npm/test/tap/install-property-conflicts.js
@@ -0,0 +1,74 @@
+var fs = require('fs')
+var resolve = require('path').resolve
+
+var osenv = require('osenv')
+var mkdirp = require('mkdirp')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var pkg = resolve(__dirname, 'install-property-conflicts')
+var target = resolve(pkg, '_target')
+
+var EXEC_OPTS = {
+ cwd: target
+}
+
+var json = {
+ name: 'install-property-conflicts',
+ version: '1.2.3',
+ type: 'nose-boop!'
+}
+
+test('setup', function (t) {
+ setup()
+ t.pass('setup ran')
+ t.end()
+})
+
+test('install package with a `type` property', function (t) {
+ t.comment('issue: https://github.com/npm/npm/issues/11398')
+ common.npm(
+ [
+ 'install',
+ '--prefix', target,
+ pkg
+ ],
+ EXEC_OPTS,
+ function (err, code, stdout, stderr) {
+ t.ifError(err, 'npm command ran from test')
+ t.equals(code, 0, 'install exited with success (0)')
+ var installedPkg = resolve(
+ target,
+ 'node_modules',
+ 'install-property-conflicts',
+ 'package.json')
+ t.ok(fs.statSync(installedPkg), 'package installed successfully')
+ t.end()
+ }
+ )
+})
+
+test('clean', function (t) {
+ cleanup()
+ t.pass('cleaned up')
+ t.end()
+})
+
+function setup () {
+ cleanup()
+ mkdirp.sync(pkg)
+ // make sure it installs locally
+ mkdirp.sync(resolve(target, 'node_modules'))
+ fs.writeFileSync(
+ resolve(pkg, 'package.json'),
+ JSON.stringify(json, null, 2) + '\n'
+ )
+}
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+ rimraf.sync(target)
+}
diff --git a/deps/npm/test/tap/install-shrinkwrapped-git.js b/deps/npm/test/tap/install-shrinkwrapped-git.js
new file mode 100644
index 0000000000..34875ffb65
--- /dev/null
+++ b/deps/npm/test/tap/install-shrinkwrapped-git.js
@@ -0,0 +1,159 @@
+var fs = require('fs')
+var path = require('path')
+var resolve = path.resolve
+var osenv = require('osenv')
+var mkdirp = require('mkdirp')
+var rimraf = require('rimraf')
+var test = require('tap').test
+var npm = require('../../lib/npm')
+var common = require('../common-tap')
+var chain = require('slide').chain
+
+var mockPath = resolve(__dirname, 'install-shrinkwrapped')
+var parentPath = resolve(mockPath, 'parent')
+var parentNodeModulesPath = path.join(parentPath, 'node_modules')
+var outdatedNodeModulesPath = resolve(mockPath, 'node-modules-backup')
+var childPath = resolve(mockPath, 'child.git')
+
+var gitDaemon
+var gitDaemonPID
+var git
+
+var parentPackageJSON = JSON.stringify({
+ name: 'parent',
+ version: '0.1.0'
+})
+
+var childPackageJSON = JSON.stringify({
+ name: 'child',
+ version: '0.1.0'
+})
+
+test('setup', function (t) {
+ setup(function (err, result) {
+ t.ifError(err, 'git started up successfully')
+
+ if (!err) {
+ gitDaemon = result[result.length - 2]
+ gitDaemonPID = result[result.length - 1]
+ }
+
+ t.end()
+ })
+})
+
+test('shrinkwrapped git dependency got updated', function (t) {
+ t.comment('test for https://github.com/npm/npm/issues/12718')
+
+ // Prepare the child package git repo with two commits
+ prepareChildAndGetRefs(function (refs) {
+ chain([
+ // Install & shrinkwrap child package's first commit
+ [npm.commands.install, ['git://localhost:1234/child.git#' + refs[0]]],
+ [npm.commands.shrinkwrap, []],
+ // Backup node_modules with the first commit
+ [fs.rename, parentNodeModulesPath, outdatedNodeModulesPath],
+ // Install & shrinkwrap child package's second commit
+ [npm.commands.install, ['git://localhost:1234/child.git#' + refs[1]]],
+ [npm.commands.shrinkwrap, []],
+ // Restore node_modules with the first commit
+ [rimraf, parentNodeModulesPath],
+ [fs.rename, outdatedNodeModulesPath, parentNodeModulesPath],
+ // Update node_modules
+ [npm.commands.install, []]
+ ], function () {
+ var childPackageJSON = require(path.join(parentNodeModulesPath, 'child', 'package.json'))
+ t.equal(
+ childPackageJSON._resolved,
+ 'git://localhost:1234/child.git#' + refs[1],
+ "Child package wasn't updated"
+ )
+ t.end()
+ })
+ })
+})
+
+test('clean', function (t) {
+ gitDaemon.on('close', function () {
+ cleanup()
+ t.end()
+ })
+ process.kill(gitDaemonPID)
+})
+
+function setup (cb) {
+ // Setup parent package
+ mkdirp.sync(parentPath)
+ fs.writeFileSync(resolve(parentPath, 'package.json'), parentPackageJSON)
+ process.chdir(parentPath)
+
+ // Setup child
+ mkdirp.sync(childPath)
+ fs.writeFileSync(resolve(childPath, 'package.json'), childPackageJSON)
+
+ // Setup npm and then git
+ npm.load({
+ registry: common.registry,
+ loglevel: 'silent',
+ save: true // Always install packages with --save
+ }, function () {
+ // It's important to initialize git after npm because it uses config
+ initializeGit(cb)
+ })
+}
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(mockPath)
+ rimraf.sync(common['npm_config_cache'])
+}
+
+function prepareChildAndGetRefs (cb) {
+ var opts = { cwd: childPath, env: { PATH: process.env.PATH } }
+ chain([
+ [fs.writeFile, path.join(childPath, 'README.md'), ''],
+ git.chainableExec(['add', 'README.md'], opts),
+ git.chainableExec(['commit', '-m', 'Add README'], opts),
+ git.chainableExec(['log', '--pretty=format:"%H"', '-2'], opts)
+ ], function () {
+ var gitLogStdout = arguments[arguments.length - 1]
+ var refs = gitLogStdout[gitLogStdout.length - 1].split('\n').map(function (ref) {
+ return ref.match(/^"(.+)"$/)[1]
+ }).reverse() // Reverse refs order: last, first -> first, last
+ cb(refs)
+ })
+}
+
+function initializeGit (cb) {
+ git = require('../../lib/utils/git')
+ common.makeGitRepo({
+ path: childPath,
+ commands: [startGitDaemon]
+ }, cb)
+}
+
+function startGitDaemon (cb) {
+ var daemon = git.spawn(
+ [
+ 'daemon',
+ '--verbose',
+ '--listen=localhost',
+ '--export-all',
+ '--base-path=' + mockPath, // Path to the dir that contains child.git
+ '--reuseaddr',
+ '--port=1234'
+ ],
+ {
+ cwd: parentPath,
+ env: process.env,
+ stdio: ['pipe', 'pipe', 'pipe']
+ }
+ )
+ daemon.stderr.on('data', function findChild (c) {
+ var cpid = c.toString().match(/^\[(\d+)\]/)
+ if (cpid[1]) {
+ this.removeListener('data', findChild)
+ cb(null, [daemon, cpid[1]])
+ }
+ })
+}
diff --git a/deps/npm/test/tap/invalid-dep-version-filtering.js b/deps/npm/test/tap/invalid-dep-version-filtering.js
new file mode 100644
index 0000000000..a4a872f54e
--- /dev/null
+++ b/deps/npm/test/tap/invalid-dep-version-filtering.js
@@ -0,0 +1,135 @@
+'use strict'
+var path = require('path')
+var test = require('tap').test
+var mr = require('npm-registry-mock')
+var common = require('../common-tap')
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+var cachedir = path.join(testdir, 'cache')
+
+var fixture = new Tacks(Dir({
+ cache: Dir(),
+ node_modules: Dir(),
+ tarballs: Dir({
+ 'pkgA.tgz': File(new Buffer(
+ '1f8b0800000000000003edcfcf0a0221100670cf3ec5e0396cfcb703bd8d' +
+ '842cb5e4ca5a5da2776f5da153b78408fc5d3e6684e133f9e3e4c7b04f35' +
+ 'e539cf9135868883b5509206b725ea3a6f9c01a634598d8e48134365d0e0' +
+ 'fadebac827b77cf5cb5ae5db3bf52bf0ce3ff1e00022fa4b100710691abd' +
+ 'd895cd3d2cf934c7b25412250afee4bfaeda755dd735f40211b5bced0008' +
+ '0000',
+ 'hex'
+ )),
+ 'pkgB1.tgz': File(new Buffer(
+ '1f8b0800000000000003edcfc10a0221140550d77ec5c375d8d3d111fa1b' +
+ '0b196ac891b16913fd7be308adda2544f0cee6e25d3caec99f463f847daa' +
+ '292f798aac3144ec8d8192aeb75ba2aeef8ded8029ed8c46eb1c1a86aa43' +
+ 'bd76d87ac8274bbef9799df2ed9dfa1578e79f78700011fd35880388340e' +
+ '47b12bcd3dccf93cc5522a8912057ff25f4f258410d2d00b247d22080008' +
+ '0000',
+ 'hex'
+ ))
+ })
+}))
+
+var pkgAtgz = path.join(testdir, 'tarballs', 'pkgA.tgz')
+var pkgB1tgz = path.join(testdir, 'tarballs', 'pkgB1.tgz')
+
+var server
+
+var pkgA = {
+ name: 'pkg-a',
+ 'dist-tags': {
+ latest: '1.0.0'
+ },
+ versions: {
+ '1.0.0': {
+ name: 'pkg-a',
+ version: '1.0.0',
+ dependencies: {
+ 'pkg-b': '1.0.0'
+ },
+ dist: {
+ shasum: 'dc5471ce0439f0f47749bb01473cad4570cc7dc5',
+ tarball: common.registry + '/pkg-a/-/pkg-a-1.0.0.tgz'
+ }
+ }
+ }
+}
+
+var pkgB = {
+ name: 'pkg-b',
+ 'dist-tags': {
+ latest: '1.0.0'
+ },
+ versions: {
+ '1.0.0': {
+ name: 'pkg-b',
+ version: '1.0.0',
+ dist: {
+ shasum: '53031aa2cf774c0e841c6fdbbe54c13825cd5640',
+ tarball: common.registry + '/pkg-b/-/pkg-b-1.0.0.tgz'
+ }
+ },
+ '1.0.0rc1': {
+ name: 'pkg-b',
+ version: '1.0.0rc1',
+ dist: {
+ shasum: '7f4b1bf680e3a31113d77619b4dc7c3b4c7dc15c',
+ tarball: common.registry + '/pkg-b/-/pkg-b-1.0.0-rc1.tgz'
+ }
+ }
+ }
+}
+
+function setup () {
+ cleanup()
+ fixture.create(testdir)
+}
+function cleanup () {
+ fixture.remove(testdir)
+}
+
+test('setup', function (t) {
+ setup()
+ mr({ port: common.port, throwOnUnmatched: true }, function (err, s) {
+ t.ifError(err, 'registry mocked successfully')
+ server = s
+ t.end()
+ })
+})
+
+test('invalid versions should be ignored', function (t) {
+ server.get('/pkg-a').reply(200, pkgA)
+ server.get('/pkg-b').reply(200, pkgB)
+ server.get('/pkg-a/-/pkg-a-1.0.0.tgz').replyWithFile(200, pkgAtgz)
+ server.get('/pkg-b/-/pkg-b-1.0.0.tgz').replyWithFile(200, pkgB1tgz)
+
+ common.npm(
+ [
+ 'install',
+ '--cache', cachedir,
+ '--registry', common.registry,
+ '--fetch-retries=0',
+ 'pkg-a@1.0.0'
+ ],
+ {cwd: testdir},
+ function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.equal(code, 0, 'install succeded')
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ server.done()
+ t.end()
+ }
+ )
+})
+
+test('cleanup', function (t) {
+ server.close()
+ cleanup()
+ t.end()
+})
diff --git a/deps/npm/test/tap/lifecycle-order.js b/deps/npm/test/tap/lifecycle-order.js
new file mode 100644
index 0000000000..903e1945d1
--- /dev/null
+++ b/deps/npm/test/tap/lifecycle-order.js
@@ -0,0 +1,57 @@
+var fs = require('graceful-fs')
+var path = require('path')
+
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var pkg = path.resolve(__dirname, path.basename(__filename, '.js'))
+
+var json = {
+ name: 'lifecycle-order',
+ version: '1.0.0',
+ scripts: {
+ preinstall: 'node -e "var fs = require(\'fs\'); fs.openSync(\'preinstall-step\', \'w+\'); if (fs.existsSync(\'node_modules\')) { throw \'node_modules exists on preinstall\' }"',
+ install: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'preinstall-step\')) { fs.openSync(\'install-step\', \'w+\') } else { throw \'Out of order\' }"',
+ postinstall: 'node -e "var fs = require(\'fs\'); if (fs.existsSync(\'install-step\')) { fs.openSync(\'postinstall-step\', \'w+\') } else { throw \'Out of order\' }"'
+ }
+}
+
+test('setup', function (t) {
+ cleanup()
+ mkdirp.sync(pkg)
+ fs.writeFileSync(
+ path.join(pkg, 'package.json'),
+ JSON.stringify(json, null, 2)
+ )
+
+ process.chdir(pkg)
+ t.end()
+})
+
+test('lifecycle scripts execute in the proper order', function (t) {
+ common.npm('install', {cwd: pkg}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.is(code, 0, 'no error')
+
+ // All three files should exist
+ t.ok(fs.existsSync(path.join(pkg, 'preinstall-step')), 'preinstall ok')
+ t.ok(fs.existsSync(path.join(pkg, 'install-step')), 'install ok')
+ t.ok(fs.existsSync(path.join(pkg, 'postinstall-step')), 'postinstall ok')
+
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+}
diff --git a/deps/npm/test/tap/lifecycle-path.js b/deps/npm/test/tap/lifecycle-path.js
index 3264fe87be..684fd4d3b5 100644
--- a/deps/npm/test/tap/lifecycle-path.js
+++ b/deps/npm/test/tap/lifecycle-path.js
@@ -31,11 +31,33 @@ test('setup', function (t) {
t.end()
})
-test('make sure the path is correct', function (t) {
+test('make sure the path is correct, without directory of current node', function (t) {
+ checkPath(false, t)
+})
+
+test('make sure the path is correct, with directory of current node', function (t) {
+ checkPath(true, t)
+})
+
+function checkPath (withDirOfCurrentNode, t) {
+ var newPATH = PATH
+ var currentNodeExecPath = process.execPath
+ if (withDirOfCurrentNode) {
+ var newNodeExeDir = path.join(pkg, 'node-bin')
+ mkdirp.sync(newNodeExeDir)
+ currentNodeExecPath = path.join(newNodeExeDir, 'my_bundled_' + path.basename(process.execPath))
+ fs.writeFileSync(currentNodeExecPath, fs.readFileSync(process.execPath))
+ fs.chmodSync(currentNodeExecPath, '755')
+ } else {
+ // Ensure that current node interpreter will be found in the PATH,
+ // so the PATH won't be prepended with its parent directory
+ newPATH = [path.dirname(process.execPath), PATH].join(process.platform === 'win32' ? ';' : ':')
+ }
common.npm(['run-script', 'env'], {
cwd: pkg,
+ nodeExecPath: currentNodeExecPath,
env: {
- PATH: PATH
+ PATH: newPATH
},
stdio: [ 0, 'pipe', 2 ]
}, function (er, code, stdout) {
@@ -60,17 +82,18 @@ test('make sure the path is correct', function (t) {
})
// get the ones we tacked on, then the system-specific requirements
- var expect = [
- '{{ROOT}}/bin/node-gyp-bin',
- '{{ROOT}}/test/tap/lifecycle-path/node_modules/.bin',
- path.dirname(process.execPath)
- ].concat(PATH.split(pathSplit)).map(function (p) {
+ var expectedPaths = ['{{ROOT}}/bin/node-gyp-bin',
+ '{{ROOT}}/test/tap/lifecycle-path/node_modules/.bin']
+ if (withDirOfCurrentNode) {
+ expectedPaths.push('{{ROOT}}/test/tap/lifecycle-path/node-bin')
+ }
+ var expect = expectedPaths.concat(newPATH.split(pathSplit)).map(function (p) {
return p.replace(/\\/g, '/')
})
t.same(actual, expect)
t.end()
})
-})
+}
test('cleanup', function (t) {
cleanup()
diff --git a/deps/npm/test/tap/local-args-relative-to-cwd.js b/deps/npm/test/tap/local-args-relative-to-cwd.js
new file mode 100644
index 0000000000..6c424bf67f
--- /dev/null
+++ b/deps/npm/test/tap/local-args-relative-to-cwd.js
@@ -0,0 +1,65 @@
+'use strict'
+var fs = require('graceful-fs')
+var path = require('path')
+var test = require('tap').test
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+var common = require('../common-tap.js')
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+
+var fixture = new Tacks(
+ Dir({
+ example: Dir({
+ }),
+ mod1: Dir({
+ 'package.json': File({
+ name: 'mod1',
+ version: '1.0.0'
+ })
+ }),
+ node_modules: Dir({
+ })
+ })
+)
+
+function setup () {
+ fixture.create(testdir)
+}
+
+function cleanup () {
+ fixture.remove(testdir)
+}
+
+test('setup', function (t) {
+ cleanup()
+ setup()
+ t.end()
+})
+
+function exists (file) {
+ try {
+ fs.statSync(file)
+ return true
+ } catch (ex) {
+ return false
+ }
+}
+
+test('local-args-relative-to-cwd', function (t) {
+ var instdir = path.join(testdir, 'example')
+ var config = ['--loglevel=error']
+ common.npm(config.concat(['install', '../mod1']), {cwd: instdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.is(code, 0, 'install ran ok')
+ t.ok(exists(path.join(testdir, 'node_modules', 'mod1')), 'mod1 installed')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
diff --git a/deps/npm/test/tap/node-modules-path-munge.js b/deps/npm/test/tap/node-modules-path-munge.js
new file mode 100644
index 0000000000..fdca0393cc
--- /dev/null
+++ b/deps/npm/test/tap/node-modules-path-munge.js
@@ -0,0 +1,39 @@
+var common = require('../common-tap.js')
+var t = require('tap')
+var fs = require('fs')
+var rimraf = require('rimraf')
+var mkdirp = require('mkdirp')
+var path = require('path')
+var dir = path.join(__dirname, 'my_node_modules')
+var script = process.platform === 'win32' ? 'echo %PATH%' : 'echo $PATH'
+
+t.test('setup', function (t) {
+ rimraf.sync(dir)
+ mkdirp.sync(dir)
+ fs.writeFileSync(dir + '/package.json', JSON.stringify({
+ name: 'my_node_modules',
+ version: '1.2.3',
+ scripts: {
+ test: script
+ }
+ }))
+ t.end()
+})
+
+t.test('verify PATH is munged right', function (t) {
+ common.npm(['test'], { cwd: dir }, function (err, code, stdout, stderr) {
+ if (err) {
+ throw err
+ }
+ t.equal(code, 0, 'exit ok')
+ t.notOk(stderr, 'should have no stderr')
+ var expect = path.resolve(dir, 'node_modules', '.bin').toLowerCase()
+ t.contains(stdout.toLowerCase(), expect)
+ t.end()
+ })
+})
+
+t.test('cleanup', function (t) {
+ rimraf.sync(dir)
+ t.end()
+})
diff --git a/deps/npm/test/tap/optional-metadep-rollback-collision.js b/deps/npm/test/tap/optional-metadep-rollback-collision.js
index a9294858d2..bc1bccd16e 100644
--- a/deps/npm/test/tap/optional-metadep-rollback-collision.js
+++ b/deps/npm/test/tap/optional-metadep-rollback-collision.js
@@ -199,14 +199,12 @@ test('go go test racer', function (t) {
env: {
PATH: process.env.PATH,
Path: process.env.Path
- },
- stdio: [0, 'pipe', 2]
+ }
},
function (er, code, stdout, stderr) {
t.ifError(er, 'install ran to completion without error')
t.is(code, 0, 'npm install exited with code 0')
- t.is(stderr, '')
-
+ t.comment(stdout.trim())
// stdout should be empty, because we only have one, optional, dep and
// if it fails we shouldn't try installing anything
t.equal(stdout, '')
diff --git a/deps/npm/test/tap/shrinkwrap-default-arg-ver.js b/deps/npm/test/tap/shrinkwrap-default-arg-ver.js
new file mode 100644
index 0000000000..d87bc92391
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-default-arg-ver.js
@@ -0,0 +1,104 @@
+'use strict'
+var path = require('path')
+var fs = require('graceful-fs')
+var test = require('tap').test
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+var common = require('../common-tap.js')
+var mr = require('npm-registry-mock')
+
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+var config = [
+ '--loglevel=error',
+ '--registry=' + common.registry,
+ '--cache=' + path.join(testdir, 'cache')
+]
+
+var fixture = new Tacks(
+ Dir({
+ 'cache': Dir(),
+ 'npm-shrinkwrap.json': File({
+ name: 'shrinkwrap-default-arg-ver',
+ version: '1.0.0',
+ dependencies: {
+ underscore: {
+ version: '1.3.1',
+ from: 'mod1@>=1.3.1 <2.0.0',
+ resolved: common.registry + '/underscore/-/underscore-1.3.1.tgz'
+ }
+ }
+ }),
+ 'package.json': File({
+ name: 'shrinkwrap-default-arg-ver',
+ version: '1.0.0',
+ dependencies: {
+ underscore: '^1.3.1'
+ }
+ })
+ })
+)
+var installed = path.join(testdir, 'node_modules', 'underscore', 'package.json')
+
+function setup () {
+ fixture.create(testdir)
+}
+
+function cleanup () {
+ fixture.remove(testdir)
+}
+
+var server
+test('setup', function (t) {
+ cleanup()
+ setup()
+ mr({port: common.port}, function (er, s) {
+ if (er) throw er
+ server = s
+ t.end()
+ })
+})
+
+function exists (file) {
+ try {
+ fs.statSync(file)
+ return true
+ } catch (ex) {
+ return false
+ }
+}
+test('shrinkwrap-default-arg-version', function (t) {
+ // When this feature was malfunctioning npm would select the version of
+ // `mod1` from the `package.json` instead of the `npm-shrinkwrap.json`,
+ // which in this case would mean trying the registry instead of installing
+ // from a local folder.
+ common.npm(config.concat(['install', 'underscore']), {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.is(code, 0, 'installed ok')
+ t.ok(exists(path.join(testdir, 'node_modules', 'underscore')), 'underscore installed')
+ var pjson = JSON.parse(fs.readFileSync(installed))
+ t.is(pjson.version, '1.3.1', 'got shrinkwrap version')
+ t.end()
+ })
+})
+
+test('can-override', function (t) {
+ common.npm(config.concat(['install', 'underscore@latest']), {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.is(code, 0, 'installed ok')
+ t.ok(exists(path.join(testdir, 'node_modules', 'underscore')), 'underscore installed')
+ var pjson = JSON.parse(fs.readFileSync(installed))
+ t.is(pjson.version, '1.5.1', 'got latest version')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ server.close()
+ cleanup()
+ t.end()
+})
diff --git a/deps/npm/test/tap/shrinkwrap-dev-dep-cycle.js b/deps/npm/test/tap/shrinkwrap-dev-dep-cycle.js
new file mode 100644
index 0000000000..c9511bb152
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-dev-dep-cycle.js
@@ -0,0 +1,93 @@
+'use strict'
+var fs = require('fs')
+var path = require('path')
+var test = require('tap').test
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+var common = require('../common-tap.js')
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+
+var fixture = new Tacks(
+ Dir({
+ node_modules: Dir({
+ 'a': Dir({
+ 'package.json': File({
+ _requested: {
+ rawSpec: 'file:///mods/a'
+ },
+ dependencies: {
+ 'b': 'file:///mods/b'
+ },
+ name: 'a',
+ version: '1.0.0'
+ })
+ }),
+ 'b': Dir({
+ 'package.json': File({
+ _requested: {
+ rawSpec: 'file:///mods/b'
+ },
+ dependencies: {
+ 'a': 'file:///mods/a'
+ },
+ name: 'b',
+ version: '1.0.0'
+ })
+ })
+ }),
+ 'package.json': File({
+ name: 'test',
+ version: '1.0.0',
+ devDependencies: {
+ 'a': 'file:///mods/a'
+ }
+ })
+ })
+)
+
+var expectedShrinkwrap = {
+ name: 'test',
+ version: '1.0.0',
+ dependencies: {}
+}
+
+function setup () {
+ cleanup()
+ fixture.create(testdir)
+}
+
+function cleanup () {
+ fixture.remove(testdir)
+}
+
+function readJson (file) {
+ try {
+ var contents = fs.readFileSync(file)
+ return JSON.parse(contents)
+ } catch (ex) {
+ return ex
+ }
+}
+
+test('setup', function (t) {
+ setup()
+ t.end()
+})
+
+test('shrinkwrap cycle in dev deps', function (t) {
+ common.npm(['shrinkwrap'], {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.is(code, 0, 'result code = ok')
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ var actualShrinkwrap = readJson(path.join(testdir, 'npm-shrinkwrap.json'))
+ t.isDeeply(actualShrinkwrap, expectedShrinkwrap, 'shrinkwrap is right')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
diff --git a/deps/npm/test/tap/shrinkwrap-local-dependency.js b/deps/npm/test/tap/shrinkwrap-local-dependency.js
index 8d7c0712f9..d3537756c0 100644
--- a/deps/npm/test/tap/shrinkwrap-local-dependency.js
+++ b/deps/npm/test/tap/shrinkwrap-local-dependency.js
@@ -1,121 +1,123 @@
var test = require('tap').test
var path = require('path')
var fs = require('fs')
-var osenv = require('osenv')
var rimraf = require('rimraf')
-var mkdirp = require('mkdirp')
var common = require('../common-tap.js')
-
-var PKG_DIR = path.resolve(__dirname, 'shrinkwrap-local-dependency')
-var CACHE_DIR = path.resolve(PKG_DIR, 'cache')
-var DEP_DIR = path.resolve(PKG_DIR, 'dep')
-
-var desired = {
- 'name': 'npm-test-shrinkwrap-local-dependency',
- 'version': '0.0.0',
- 'dependencies': {
- 'npm-test-shrinkwrap-local-dependency-dep': {
- 'version': '0.0.0',
- 'from': 'dep',
- 'resolved': 'file:dep'
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+
+var testdir = path.resolve(__dirname, path.basename(__filename, '.js'))
+var cachedir = path.resolve(testdir, 'cache')
+var config = ['--cache=' + cachedir, '--loglevel=error']
+
+var shrinkwrap = {
+ name: 'shrinkwrap-local-dependency',
+ version: '1.0.0',
+ dependencies: {
+ mod2: {
+ version: '1.0.0',
+ from: path.join('mods', 'mod2'),
+ resolved: 'file:' + path.join('mods', 'mod2'),
+ dependencies: {
+ mod1: {
+ version: '1.0.0',
+ from: path.join('mods', 'mod1'),
+ resolved: 'file:' + path.join('mods', 'mod1')
+ }
+ }
}
}
}
-var root = {
- 'author': 'Thomas Torp',
- 'name': 'npm-test-shrinkwrap-local-dependency',
- 'version': '0.0.0',
- 'dependencies': {
- 'npm-test-shrinkwrap-local-dependency-dep': 'file:./dep'
- }
+var fixture = new Tacks(
+ Dir({
+ cache: Dir(),
+ mods: Dir({
+ mod1: Dir({
+ 'package.json': File({
+ name: 'mod1',
+ version: '1.0.0'
+ })
+ }),
+ mod2: Dir({
+ 'package.json': File({
+ name: 'mod2',
+ version: '1.0.0',
+ dependencies: {
+ mod1: 'file:' + path.join('..', 'mod1')
+ }
+ })
+ })
+ }),
+ 'package.json': File({
+ name: 'shrinkwrap-local-dependency',
+ version: '1.0.0',
+ dependencies: {
+ mod2: 'file:' + path.join('mods', 'mod2')
+ }
+ })
+ })
+)
+
+function setup () {
+ cleanup()
+ fixture.create(testdir)
+}
+
+function cleanNodeModules () {
+ rimraf.sync(path.resolve(testdir, 'node_modules'))
}
-var dependency = {
- 'author': 'Thomas Torp',
- 'name': 'npm-test-shrinkwrap-local-dependency-dep',
- 'version': '0.0.0'
+function cleanup () {
+ fixture.remove(testdir)
}
test('shrinkwrap uses resolved with file: on local deps', function (t) {
setup()
- common.npm(
- ['--cache=' + CACHE_DIR, '--loglevel=silent', 'install', '.'],
- {},
- function (err, code) {
- t.ifError(err, 'npm install worked')
- t.equal(code, 0, 'npm exited normally')
-
- common.npm(
- ['--cache=' + CACHE_DIR, '--loglevel=silent', 'shrinkwrap'],
- {},
- function (err, code) {
- t.ifError(err, 'npm shrinkwrap worked')
- t.equal(code, 0, 'npm exited normally')
-
- fs.readFile('npm-shrinkwrap.json', { encoding: 'utf8' }, function (err, data) {
- t.ifError(err, 'read file correctly')
- t.deepEqual(JSON.parse(data), desired, 'shrinkwrap looks correct')
+ common.npm(config.concat(['install', '--legacy']), {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.equal(code, 0, 'npm exited normally')
- t.end()
- })
- }
- )
- }
- )
+ common.npm(config.concat('shrinkwrap'), {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.equal(code, 0, 'npm exited normally')
+ var data = fs.readFileSync(path.join(testdir, 'npm-shrinkwrap.json'), { encoding: 'utf8' })
+ t.deepEqual(JSON.parse(data), shrinkwrap, 'shrinkwrap looks correct')
+ t.end()
+ })
+ })
})
+function exists (file) {
+ try {
+ fs.statSync(file)
+ return true
+ } catch (ex) {
+ return false
+ }
+}
+
test("'npm install' should install local packages from shrinkwrap", function (t) {
cleanNodeModules()
- common.npm(
- ['--cache=' + CACHE_DIR, '--loglevel=silent', 'install', '.'],
- {},
- function (err, code) {
- t.ifError(err, 'install ran correctly')
- t.notOk(code, 'npm install exited with code 0')
- var dependencyPackageJson = path.resolve(
- PKG_DIR,
- 'node_modules/npm-test-shrinkwrap-local-dependency-dep/package.json'
- )
- t.ok(
- JSON.parse(fs.readFileSync(dependencyPackageJson, 'utf8')),
- 'package with local dependency installed from shrinkwrap'
- )
-
- t.end()
- }
- )
+ common.npm(config.concat(['install']), {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.equal(code, 0, 'npm exited normally')
+ t.ok(exists(path.join(testdir, 'node_modules', 'mod2')), 'mod2 exists')
+ t.ok(exists(path.join(testdir, 'node_modules', 'mod2', 'node_modules', 'mod1')), 'mod1 exists')
+ t.end()
+ })
})
test('cleanup', function (t) {
cleanup()
t.end()
})
-
-function setup () {
- cleanup()
- mkdirp.sync(PKG_DIR)
- mkdirp.sync(CACHE_DIR)
- mkdirp.sync(DEP_DIR)
- fs.writeFileSync(
- path.resolve(PKG_DIR, 'package.json'),
- JSON.stringify(root, null, 2)
- )
- fs.writeFileSync(
- path.resolve(DEP_DIR, 'package.json'),
- JSON.stringify(dependency, null, 2)
- )
- process.chdir(PKG_DIR)
-}
-
-function cleanNodeModules () {
- rimraf.sync(path.resolve(PKG_DIR, 'node_modules'))
-}
-
-function cleanup () {
- process.chdir(osenv.tmpdir())
- cleanNodeModules()
- rimraf.sync(PKG_DIR)
-}
diff --git a/deps/npm/test/tap/shrinkwrap-optional-platform.js b/deps/npm/test/tap/shrinkwrap-optional-platform.js
new file mode 100644
index 0000000000..09d26f778b
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-optional-platform.js
@@ -0,0 +1,96 @@
+'use strict'
+var path = require('path')
+var test = require('tap').test
+var Tacks = require('tacks')
+var File = Tacks.File
+var Dir = Tacks.Dir
+var extend = Object.assign || require('util')._extend
+var common = require('../common-tap.js')
+
+var basedir = path.join(__dirname, path.basename(__filename, '.js'))
+var testdir = path.join(basedir, 'testdir')
+var cachedir = path.join(basedir, 'cache')
+var globaldir = path.join(basedir, 'global')
+var tmpdir = path.join(basedir, 'tmp')
+
+var conf = {
+ cwd: testdir,
+ env: extend(extend({}, process.env), {
+ npm_config_cache: cachedir,
+ npm_config_tmp: tmpdir,
+ npm_config_prefix: globaldir,
+ npm_config_registry: common.registry,
+ npm_config_loglevel: 'warn'
+ })
+}
+
+var fixture = new Tacks(Dir({
+ cache: Dir(),
+ global: Dir(),
+ tmp: Dir(),
+ testdir: Dir({
+ mod1: Dir({
+ 'package.json': File({
+ name: 'mod1',
+ version: '1.0.0',
+ scripts: {
+
+ },
+ os: ['nosuchos']
+ })
+ }),
+ 'npm-shrinkwrap.json': File({
+ name: 'shrinkwrap-optional-platform',
+ version: '1.0.0',
+ dependencies: {
+ mod1: {
+ version: '1.0.0',
+ from: 'mod1',
+ resolved: 'file:mod1',
+ optional: true
+ }
+ }
+ }),
+ 'package.json': File({
+ name: 'shrinkwrap-optional-platform',
+ version: '1.0.0',
+ optionalDependencies: {
+ mod1: 'file:mod1'
+ },
+ description: 'x',
+ repository: 'x',
+ license: 'Artistic-2.0'
+ })
+ })
+}))
+
+function setup () {
+ cleanup()
+ fixture.create(basedir)
+}
+
+function cleanup () {
+ fixture.remove(basedir)
+}
+
+test('setup', function (t) {
+ setup()
+ t.done()
+})
+
+test('example', function (t) {
+ common.npm(['install'], conf, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.is(code, 0, 'install ran ok')
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.notMatch(stderr, /Exit status 1/, 'did not try to install opt dep')
+ t.done()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.done()
+})
+
diff --git a/deps/npm/test/tap/shrinkwrap-optional-property.js b/deps/npm/test/tap/shrinkwrap-optional-property.js
new file mode 100644
index 0000000000..47f11a750b
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-optional-property.js
@@ -0,0 +1,100 @@
+var fs = require('fs')
+var path = require('path')
+
+var mkdirp = require('mkdirp')
+var mr = require('npm-registry-mock')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+var npm = npm = require('../../')
+
+var pkg = path.resolve(__dirname, 'shrinkwrap-optional-dependency')
+
+test('shrinkwrap adds optional property when optional dependency', function (t) {
+ t.plan(1)
+
+ mr({port: common.port}, function (er, s) {
+ function fail (err) {
+ s.close() // Close on failure to allow node to exit
+ t.fail(err)
+ }
+
+ setup(function (err) {
+ if (err) return fail(err)
+
+ // Install with the optional dependency
+ npm.install('.', function (err) {
+ if (err) return fail(err)
+
+ writePackage()
+
+ npm.commands.shrinkwrap([], true, function (err, results) {
+ if (err) return fail(err)
+
+ t.deepEqual(results, desired)
+ s.close()
+ t.end()
+ })
+ })
+ })
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
+
+var desired = {
+ name: 'npm-test-shrinkwrap-optional-dependency',
+ version: '0.0.0',
+ dependencies: {
+ 'test-package': {
+ version: '0.0.0',
+ from: 'test-package@0.0.0',
+ resolved: common.registry + '/test-package/-/test-package-0.0.0.tgz'
+ },
+ 'underscore': {
+ version: '1.3.3',
+ from: 'underscore@1.3.3',
+ resolved: 'http://localhost:1337/underscore/-/underscore-1.3.3.tgz',
+ optional: true
+ }
+ }
+}
+
+var json = {
+ author: 'Maximilian Antoni',
+ name: 'npm-test-shrinkwrap-optional-dependency',
+ version: '0.0.0',
+ dependencies: {
+ 'test-package': '0.0.0'
+ },
+ optionalDependencies: {
+ 'underscore': '1.3.3'
+ }
+}
+
+function writePackage () {
+ fs.writeFileSync(path.join(pkg, 'package.json'), JSON.stringify(json, null, 2))
+}
+
+function setup (cb) {
+ cleanup()
+ mkdirp.sync(pkg)
+ writePackage()
+ process.chdir(pkg)
+
+ var opts = {
+ cache: path.resolve(pkg, 'cache'),
+ registry: common.registry
+ }
+ npm.load(opts, cb)
+}
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(pkg)
+}
diff --git a/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js b/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js
index 723960ac32..d3e86fcd65 100644
--- a/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js
+++ b/deps/npm/test/tap/shrinkwrap-prod-dependency-also.js
@@ -70,6 +70,7 @@ var desired = {
resolved: common.registry + '/request/-/request-0.9.0.tgz'
},
underscore: {
+ dev: true,
version: '1.5.1',
from: 'underscore@1.5.1',
resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz'
diff --git a/deps/npm/test/tap/shrinkwrap-prod-dependency.js b/deps/npm/test/tap/shrinkwrap-prod-dependency.js
index 5bc834376e..57d6ecd3b1 100644
--- a/deps/npm/test/tap/shrinkwrap-prod-dependency.js
+++ b/deps/npm/test/tap/shrinkwrap-prod-dependency.js
@@ -50,6 +50,7 @@ var desired = {
resolved: common.registry + '/request/-/request-0.9.0.tgz'
},
underscore: {
+ dev: true,
version: '1.5.1',
from: 'underscore@1.5.1',
resolved: common.registry + '/underscore/-/underscore-1.5.1.tgz'
diff --git a/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js b/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js
new file mode 100644
index 0000000000..eacea9e3ce
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-save-dev-with-existing-deps.js
@@ -0,0 +1,102 @@
+var fs = require('fs')
+var path = require('path')
+
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var base = path.resolve(__dirname, path.basename(__filename, '.js'))
+var installme = path.join(base, 'installme')
+var installme_pkg = path.join(installme, 'package.json')
+var example = path.join(base, 'example')
+var example_shrinkwrap = path.join(example, 'npm-shrinkwrap.json')
+var example_pkg = path.join(example, 'package.json')
+var installed_prod = path.join(example, 'node_modules', 'installed-prod')
+var installed_prod_pkg = path.join(installed_prod, 'package.json')
+var installed_dev = path.join(example, 'node_modules', 'installed-dev')
+var installed_dev_pkg = path.join(installed_dev, 'package.json')
+
+var EXEC_OPTS = { cwd: example }
+
+var installme_pkg_json = {
+ name: 'installme',
+ version: '1.0.0',
+ dependencies: {}
+}
+
+var example_pkg_json = {
+ name: 'example',
+ version: '1.0.0',
+ dependencies: {
+ 'installed-prod': '1.0'
+ },
+ devDependencies: {
+ 'installed-dev': '1.0'
+ }
+}
+
+var example_shrinkwrap_json = {
+ name: 'example',
+ version: '1.0.0',
+ dependencies: {
+ 'installed-prod': {
+ version: '1.0.0'
+ },
+ 'installed-dev': {
+ version: '1.0.0'
+ }
+ }
+}
+
+var installed_prod_pkg_json = {
+ _id: 'installed-prod@1.0.0',
+ name: 'installed-prod',
+ version: '1.0.0'
+}
+
+var installed_dev_pkg_json = {
+ _id: 'installed-dev@1.0.0',
+ name: 'installed-dev',
+ version: '1.0.0'
+}
+
+function writeJson (filename, obj) {
+ mkdirp.sync(path.dirname(filename))
+ fs.writeFileSync(filename, JSON.stringify(obj, null, 2))
+}
+
+test('setup', function (t) {
+ cleanup()
+ writeJson(installme_pkg, installme_pkg_json)
+ writeJson(example_pkg, example_pkg_json)
+ writeJson(example_shrinkwrap, example_shrinkwrap_json)
+ writeJson(installed_prod_pkg, installed_prod_pkg_json)
+ writeJson(installed_dev_pkg, installed_dev_pkg_json)
+ t.end()
+})
+
+test('install --save-dev leaves prod deps alone', function (t) {
+ common.npm(['install', '--save-dev', 'file://' + installme], EXEC_OPTS, function (er, code, stdout, stderr) {
+ t.ifError(er, "spawn didn't catch fire")
+ t.is(code, 0, 'install completed ok')
+ t.is(stderr, '', 'install completed without error output')
+ var shrinkwrap = JSON.parse(fs.readFileSync(example_shrinkwrap))
+ t.ok(shrinkwrap.dependencies['installed-prod'], "save-dev new install didn't remove prod dep")
+ t.ok(shrinkwrap.dependencies['installed-dev'], "save-dev new install didn't remove dev dep")
+ t.ok(shrinkwrap.dependencies.installme, 'save-dev new install DID add new dev dep')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(base)
+}
diff --git a/deps/npm/test/tap/shrinkwrap-save-dev-without-existing-dev-deps.js b/deps/npm/test/tap/shrinkwrap-save-dev-without-existing-dev-deps.js
new file mode 100644
index 0000000000..436b17895a
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-save-dev-without-existing-dev-deps.js
@@ -0,0 +1,87 @@
+var fs = require('fs')
+var path = require('path')
+
+var mkdirp = require('mkdirp')
+var osenv = require('osenv')
+var rimraf = require('rimraf')
+var test = require('tap').test
+
+var common = require('../common-tap.js')
+
+var base = path.resolve(__dirname, path.basename(__filename, '.js'))
+var installme = path.join(base, 'installme')
+var installme_pkg = path.join(installme, 'package.json')
+var example = path.join(base, 'example')
+var example_shrinkwrap = path.join(example, 'npm-shrinkwrap.json')
+var example_pkg = path.join(example, 'package.json')
+var installed = path.join(example, 'node_modules', 'installed')
+var installed_pkg = path.join(installed, 'package.json')
+
+var EXEC_OPTS = { cwd: example }
+
+var installme_pkg_json = {
+ name: 'installme',
+ version: '1.0.0',
+ dependencies: {}
+}
+
+var example_pkg_json = {
+ name: 'example',
+ version: '1.0.0',
+ dependencies: {
+ 'installed': '1.0'
+ },
+ devDependencies: {}
+}
+
+var example_shrinkwrap_json = {
+ name: 'example',
+ version: '1.0.0',
+ dependencies: {
+ installed: {
+ version: '1.0.0'
+ }
+ }
+}
+
+var installed_pkg_json = {
+ _id: 'installed@1.0.0',
+ name: 'installed',
+ version: '1.0.0'
+}
+
+function writeJson (filename, obj) {
+ mkdirp.sync(path.dirname(filename))
+ fs.writeFileSync(filename, JSON.stringify(obj, null, 2))
+}
+
+test('setup', function (t) {
+ cleanup()
+ writeJson(installme_pkg, installme_pkg_json)
+ writeJson(example_pkg, example_pkg_json)
+ writeJson(example_shrinkwrap, example_shrinkwrap_json)
+ writeJson(installed_pkg, installed_pkg_json)
+ t.end()
+})
+
+test('install --save-dev leaves dev deps alone', function (t) {
+ common.npm(['install', '--save-dev', 'file://' + installme], EXEC_OPTS, function (er, code, stdout, stderr) {
+ t.ifError(er, "spawn didn't catch fire")
+ t.is(code, 0, 'install completed ok')
+ t.is(stderr, '', 'install completed without error output')
+ var shrinkwrap = JSON.parse(fs.readFileSync(example_shrinkwrap))
+ t.ok(shrinkwrap.dependencies.installed, "save-dev new install didn't remove dep")
+ t.notOk(shrinkwrap.dependencies.installme, 'save-dev new install DID NOT add new dev dep')
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
+
+function cleanup () {
+ process.chdir(osenv.tmpdir())
+ rimraf.sync(base)
+}
diff --git a/deps/npm/test/tap/shrinkwrap-transitive-dev.js b/deps/npm/test/tap/shrinkwrap-transitive-dev.js
new file mode 100644
index 0000000000..80a38f7f9e
--- /dev/null
+++ b/deps/npm/test/tap/shrinkwrap-transitive-dev.js
@@ -0,0 +1,83 @@
+'use strict'
+var fs = require('fs')
+var path = require('path')
+var test = require('tap').test
+var Tacks = require('tacks')
+var common = require('../common-tap.js')
+var File = Tacks.File
+var Dir = Tacks.Dir
+
+var testname = path.basename(__filename, '.js')
+var testdir = path.join(__dirname, testname)
+var cachedir = path.join(testdir, 'cache')
+var swfile = path.join(testdir, 'npm-shrinkwrap.json')
+var fixture = new Tacks(
+ Dir({
+ cache: Dir(),
+ mods: Dir({
+ moda: Dir({
+ 'package.json': File({
+ name: 'moda',
+ version: '1.0.0',
+ dependencies: {
+ modb: '../modb'
+ }
+ })
+ }),
+ modb: Dir({
+ 'package.json': File({
+ name: 'modb',
+ version: '1.0.0'
+ })
+ })
+ }),
+ 'package.json': File({
+ name: testname,
+ version: '1.0.0',
+ devDependencies: {
+ moda: 'file:mods/moda'
+ }
+ })
+ })
+)
+
+function setup () {
+ cleanup()
+ fixture.create(testdir)
+}
+
+function cleanup () {
+ fixture.remove(testdir)
+}
+
+test('setup', function (t) {
+ setup()
+ common.npm(['install', '--cache=' + cachedir], {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.is(code, 0, 'setup ok')
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ t.end()
+ })
+})
+
+test('transitive-deps-of-dev-deps', function (t) {
+ common.npm(['shrinkwrap', '--loglevel=error'], {cwd: testdir}, function (err, code, stdout, stderr) {
+ if (err) throw err
+ t.is(code, 0, 'shrinkwrap ran ok')
+ t.comment(stdout.trim())
+ t.comment(stderr.trim())
+ try {
+ var shrinkwrap = JSON.parse(fs.readFileSync(swfile))
+ t.isDeeply(shrinkwrap.dependencies, {}, 'empty shrinkwrap')
+ } catch (ex) {
+ t.ifError(ex)
+ }
+ t.end()
+ })
+})
+
+test('cleanup', function (t) {
+ cleanup()
+ t.end()
+})
diff --git a/deps/npm/test/tap/update-symlink.js b/deps/npm/test/tap/update-symlink.js
index 1447fde628..1fb07b8a75 100644
--- a/deps/npm/test/tap/update-symlink.js
+++ b/deps/npm/test/tap/update-symlink.js
@@ -1,6 +1,5 @@
var fs = require('graceful-fs')
var path = require('path')
-var osenv = require('osenv')
var mkdirp = require('mkdirp')
var mr = require('npm-registry-mock')
var rimraf = require('rimraf')
@@ -8,14 +7,17 @@ var test = require('tap').test
var common = require('../common-tap.js')
-var pkg = path.resolve(__dirname, 'update-symlink')
-var originalLog
-
-var fakeRoot = path.join(__dirname, 'fakeRoot')
+var testdir = path.join(__dirname, path.basename(__filename, '.js'))
+var pkg = path.resolve(testdir, 'update-symlink')
+var cachedir = path.join(testdir, 'cache')
+var globaldir = path.join(testdir, 'global')
var OPTS = {
env: {
- 'npm_config_prefix': fakeRoot
- }
+ 'npm_config_cache': cachedir,
+ 'npm_config_prefix': globaldir,
+ 'npm_config_registry': common.registry
+ },
+ cwd: pkg
}
var jsonLocal = {
@@ -28,57 +30,92 @@ var jsonLocal = {
}
}
+var server
test('setup', function (t) {
cleanup()
- originalLog = console.log
+ mkdirp.sync(cachedir)
mkdirp.sync(pkg)
- common.npm(['install', '-g', 'underscore@1.3.1'], OPTS, function (err, c, out) {
+ fs.writeFileSync(
+ path.join(pkg, 'package.json'),
+ JSON.stringify(jsonLocal, null, 2)
+ )
+
+ mr({ port: common.port }, thenInstallUnderscore)
+
+ function thenInstallUnderscore (er, s) {
+ server = s
+ common.npm(['install', '-g', 'underscore@1.3.1'], OPTS, thenLink)
+ }
+
+ function thenLink (err, c, out) {
t.ifError(err, 'global install did not error')
- process.chdir(pkg)
- fs.writeFileSync(
- path.join(pkg, 'package.json'),
- JSON.stringify(jsonLocal, null, 2)
- )
- common.npm(['link', 'underscore'], OPTS, function (err, c, out) {
- t.ifError(err, 'link did not error')
- common.npm(['install', 'async@0.2.9'], OPTS, function (err, c, out) {
- t.ifError(err, 'local install did not error')
- common.npm(['ls'], OPTS, function (err, c, out, stderr) {
- t.ifError(err)
- t.equal(c, 0)
- t.equal(stderr, '', 'got expected stderr')
- t.has(out, /async@0.2.9/, 'installed ok')
- t.has(out, /underscore@1.3.1/, 'creates local link ok')
- t.end()
- })
- })
- })
- })
-})
+ common.npm(['link', 'underscore'], OPTS, thenInstallAsync)
+ }
-test('when update is called linked packages should be excluded', function (t) {
- console.log = function () {}
- mr({ port: common.port }, function (er, s) {
- common.npm(['update'], OPTS, function (err, c, out, stderr) {
+ function thenInstallAsync (err, c, out) {
+ t.ifError(err, 'link did not error')
+ common.npm(['install', 'async@0.2.9'], OPTS, thenVerify)
+ }
+
+ function thenVerify (err, c, out) {
+ t.ifError(err, 'local install did not error')
+ common.npm(['ls'], OPTS, function (err, c, out, stderr) {
t.ifError(err)
- t.has(out, /async@1.5.2/, 'updated ok')
- t.doesNotHave(stderr, /ERR!/, 'no errors in stderr')
- s.close()
+ t.equal(c, 0)
+ t.equal(stderr, '', 'got expected stderr')
+ t.has(out, /async@0.2.9/, 'installed ok')
+ t.has(out, /underscore@1.3.1/, 'creates local link ok')
t.end()
})
+ }
+})
+
+test('when update is called linked packages should be excluded', function (t) {
+ common.npm(['update'], OPTS, function (err, c, out, stderr) {
+ t.ifError(err)
+ t.equal(c, 0)
+ t.has(out, /async@0.2.10/, 'updated ok')
+ t.doesNotHave(stderr, /ERR!/, 'no errors in stderr')
+ t.end()
+ })
+})
+
+test('when install is called and the package already exists as a link, outputs a warning if the requested version is not the same as the linked one', function (t) {
+ common.npm(['install', 'underscore'], OPTS, function (err, c, out, stderr) {
+ t.ifError(err)
+ t.equal(c, 0)
+
+ t.comment(out.trim())
+ t.comment(stderr.trim())
+ t.doesNotHave(out, /underscore/, 'linked package not updated')
+ t.has(stderr, /underscore/, 'warning output relating to linked package')
+ t.doesNotHave(stderr, /ERR!/, 'no errors in stderr')
+ t.end()
+ })
+})
+
+test('when install is called and the package already exists as a link, does not warn if the requested version is same as the linked one', function (t) {
+ common.npm(['install', 'underscore@1.3.1'], OPTS, function (err, c, out, stderr) {
+ t.ifError(err)
+ t.equal(c, 0)
+ t.comment(out.trim())
+ t.comment(stderr.trim())
+ t.doesNotHave(out, /underscore/, 'linked package not updated')
+ t.doesNotHave(stderr, /underscore/, 'no warning or error relating to linked package')
+ t.doesNotHave(stderr, /ERR!/, 'no errors in stderr')
+ t.end()
})
})
test('cleanup', function (t) {
+ server.close()
common.npm(['rm', 'underscore', 'async'], OPTS, function (err, code) {
t.ifError(err, 'npm removed the linked package without error')
t.equal(code, 0, 'cleanup in local ok')
- process.chdir(osenv.tmpdir())
common.npm(['rm', '-g', 'underscore'], OPTS, function (err, code) {
t.ifError(err, 'npm removed the global package without error')
t.equal(code, 0, 'cleanup in global ok')
- console.log = originalLog
cleanup()
t.end()
})
@@ -86,6 +123,5 @@ test('cleanup', function (t) {
})
function cleanup () {
- rimraf.sync(pkg)
- rimraf.sync(fakeRoot)
+ rimraf.sync(testdir)
}