diff options
author | Kat Marchán <kzm@sykosomatic.org> | 2016-05-27 14:07:59 -0700 |
---|---|---|
committer | Jeremiah Senkpiel <fishrock123@rocketmail.com> | 2016-05-28 10:42:48 -0400 |
commit | bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400 (patch) | |
tree | aab54a7bbc42e1477a8a2b175dfc9f9eb36ca9e2 /deps/npm/test | |
parent | 16f98e589c69ffe6283aa11493fd417368708557 (diff) | |
download | android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.tar.gz android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.tar.bz2 android-node-v8-bd8b1ddb2007dcc8ec2a0a08e16208aa21b83400.zip |
deps: upgrade npm to 3.9.3
Contains the following npm releases:
- v3.9.0: https://github.com/npm/npm/releases/tag/v3.9.0
- v3.9.1: https://github.com/npm/npm/releases/tag/v3.9.1
- v3.9.2: https://github.com/npm/npm/releases/tag/v3.9.2
- v3.9.3: https://github.com/npm/npm/releases/tag/v3.9.3
PR-URL: https://github.com/nodejs/node/pull/7030
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Diffstat (limited to 'deps/npm/test')
64 files changed, 1645 insertions, 560 deletions
diff --git a/deps/npm/test/common-tap.js b/deps/npm/test/common-tap.js index d7e9c8f7d0..847c87ba0f 100644 --- a/deps/npm/test/common-tap.js +++ b/deps/npm/test/common-tap.js @@ -1,3 +1,8 @@ +'use strict' +var fs = require('graceful-fs') +var readCmdShim = require('read-cmd-shim') +var isWindows = require('../lib/utils/is-windows.js') + // cheesy hackaround for test deps (read: nock) that rely on setImmediate if (!global.setImmediate || !require('timers').setImmediate) { require('timers').setImmediate = global.setImmediate = function () { @@ -25,9 +30,12 @@ process.env.random_env_var = 'foo' process.env.npm_config_node_version = process.version.replace(/-.*$/, '') var bin = exports.bin = require.resolve('../bin/npm-cli.js') + var chain = require('slide').chain var once = require('once') +var nodeBin = exports.nodeBin = process.env.npm_node_execpath || process.env.NODE || process.execPath + exports.npm = function (cmd, opts, cb) { cb = once(cb) cmd = [bin].concat(cmd) @@ -40,8 +48,7 @@ exports.npm = function (cmd, opts, cb) { var stdout = '' var stderr = '' - var node = process.execPath - var child = spawn(node, cmd, opts) + var child = spawn(nodeBin, cmd, opts) if (child.stderr) { child.stderr.on('data', function (chunk) { @@ -88,3 +95,27 @@ exports.makeGitRepo = function (params, cb) { chain(commands, cb) } + +exports.readBinLink = function (path) { + if (isWindows) { + return readCmdShim.sync(path) + } else { + return fs.readlinkSync(path) + } +} + +exports.skipIfWindows = function (why) { + if (!isWindows) return + console.log('1..1') + if (!why) why = 'this test not available on windows' + console.log('ok 1 # skip ' + why) + process.exit(0) +} + +exports.pendIfWindows = function (why) { + if (!isWindows) return + console.log('1..1') + if (!why) why = 'this test is pending further changes on windows' + console.log('not ok 1 # todo ' + why) + process.exit(0) +} diff --git a/deps/npm/test/fixtures/config/userconfig-with-gc b/deps/npm/test/fixtures/config/userconfig-with-gc new file mode 100644 index 0000000000..62ad80be11 --- /dev/null +++ b/deps/npm/test/fixtures/config/userconfig-with-gc @@ -0,0 +1,22 @@ +globalconfig=/Users/zkat/Documents/code/npm/test/fixtures/config/globalconfig +email=i@izs.me +env-thing=asdf +init.author.name=Isaac Z. Schlueter +init.author.email=i@izs.me +init.author.url=http://blog.izs.me/ +init.version=1.2.3 +proprietary-attribs=false +npm:publishtest=true +_npmjs.org:couch=https://admin:password@localhost:5984/registry +npm-www:nocache=1 +sign-git-tag=false +message=v%s +strict-ssl=false +_auth="dXNlcm5hbWU6cGFzc3dvcmQ=" + +[_token] +AuthSession=yabba-dabba-doodle +version=1 +expires=1345001053415 +path=/ +httponly=true diff --git a/deps/npm/test/tap/00-config-setup.js b/deps/npm/test/tap/00-config-setup.js index 0310f48d5c..7303c8328f 100644 --- a/deps/npm/test/tap/00-config-setup.js +++ b/deps/npm/test/tap/00-config-setup.js @@ -21,7 +21,7 @@ exports.ucData = 'sign-git-tag': true, message: 'v%s', 'strict-ssl': false, - 'tmp': process.env.HOME + '/.tmp', + 'tmp': path.normalize(process.env.HOME + '/.tmp'), _auth: 'dXNlcm5hbWU6cGFzc3dvcmQ=', _token: { AuthSession: 'yabba-dabba-doodle', @@ -38,10 +38,10 @@ Object.keys(process.env).forEach(function (k) { } }) process.env.npm_config_userconfig = exports.userconfig -process.env.npm_config_other_env_thing = 1000 +process.env.npm_config_other_env_thing = '1000' process.env.random_env_var = 'asdf' process.env.npm_config__underbar_env_thing = 'underful' -process.env.NPM_CONFIG_UPPERCASE_ENV_THING = 42 +process.env.NPM_CONFIG_UPPERCASE_ENV_THING = '42' exports.envData = { userconfig: exports.userconfig, @@ -61,11 +61,11 @@ try { fs.statSync(projectConf) } catch (er) { // project conf not found, probably working with packed npm - fs.writeFileSync(projectConf, function () {/* + fs.writeFileSync(projectConf, function () { /* save-prefix = ~ proprietary-attribs = false legacy-bundling = true - */}.toString().split('\n').slice(1, -1).join('\n')) + */ }.toString().split('\n').slice(1, -1).join('\n')) } var projectRc = path.join(__dirname, '..', 'fixtures', 'config', '.npmrc') diff --git a/deps/npm/test/tap/bugs.js b/deps/npm/test/tap/bugs.js index 090c2b9cb2..8b992fd7be 100644 --- a/deps/npm/test/tap/bugs.js +++ b/deps/npm/test/tap/bugs.js @@ -1,9 +1,6 @@ -if (process.platform === 'win32') { - console.error('skipping test, because windows and shebangs') - process.exit(0) -} - var common = require('../common-tap.js') +common.pendIfWindows('not working because Windows and shebangs') + var mr = require('npm-registry-mock') var test = require('tap').test diff --git a/deps/npm/test/tap/builtin-config.js b/deps/npm/test/tap/builtin-config.js index bb08767c56..22a447c9cf 100644 --- a/deps/npm/test/tap/builtin-config.js +++ b/deps/npm/test/tap/builtin-config.js @@ -14,7 +14,7 @@ var folder = path.resolve(__dirname, 'builtin-config') var test = require('tap').test var npm = path.resolve(__dirname, '../..') var spawn = require('child_process').spawn -var node = process.execPath +var node = common.nodeBin test('setup', function (t) { t.plan(1) @@ -34,9 +34,10 @@ test('install npm into first folder', function (t) { '--prefix=' + folder + '/first', '--ignore-scripts', '--cache=' + folder + '/cache', - '--loglevel=silent', - '--tmp=' + folder + '/tmp'] - common.npm(args, {stdio: 'inherit'}, function (er, code) { + '--tmp=' + folder + '/tmp', + '--loglevel=warn', + '--progress'] + common.npm(args, {}, function (er, code) { if (er) throw er t.equal(code, 0) t.end() @@ -49,8 +50,7 @@ test('write npmrc file', function (t) { '--prefix=' + folder + '/first', '--cache=' + folder + '/cache', '--tmp=' + folder + '/tmp', - '--', - node, __filename, 'write-builtin', process.pid + '--', node, __filename, 'write-builtin', process.pid ], {'stdio': 'inherit'}, function (er, code) { @@ -73,9 +73,9 @@ test('use first npm to install second npm', function (t) { {}, function (er, code, so) { if (er) throw er - t.equal(code, 0) + t.equal(code, 0, 'got npm root') var root = so.trim() - t.ok(fs.statSync(root).isDirectory()) + t.ok(fs.statSync(root).isDirectory(), 'npm root is dir') var bin = path.resolve(root, 'npm/bin/npm-cli.js') spawn( @@ -84,14 +84,16 @@ test('use first npm to install second npm', function (t) { bin, 'install', npm, '-g', + '--ignore-scripts', '--prefix=' + folder + '/second', '--cache=' + folder + '/cache', '--tmp=' + folder + '/tmp' - ] + ], + {} ) .on('error', function (er) { throw er }) .on('close', function (code) { - t.equal(code, 0, 'code is zero') + t.equal(code, 0, 'second npm install') t.end() }) } @@ -120,9 +122,9 @@ test('verify that the builtin config matches', function (t) { var secondRoot = so.trim() var firstRc = path.resolve(firstRoot, 'npm', 'npmrc') var secondRc = path.resolve(secondRoot, 'npm', 'npmrc') - var firstData = fs.readFileSync(firstRc, 'utf8') - var secondData = fs.readFileSync(secondRc, 'utf8') - t.equal(firstData, secondData) + var firstData = fs.readFileSync(firstRc, 'utf8').split(/\r?\n/) + var secondData = fs.readFileSync(secondRc, 'utf8').split(/\r?\n/) + t.isDeeply(firstData, secondData) t.end() }) }) diff --git a/deps/npm/test/tap/bundled-dependencies-no-pkgjson.js b/deps/npm/test/tap/bundled-dependencies-no-pkgjson.js new file mode 100644 index 0000000000..44eb47a03a --- /dev/null +++ b/deps/npm/test/tap/bundled-dependencies-no-pkgjson.js @@ -0,0 +1,47 @@ +var test = require('tap').test +var path = require('path') +var fs = require('graceful-fs') + +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') +var common = require('../common-tap.js') + +var dir = path.resolve(__dirname, 'bundled-dependencies-no-pkgjson') +var pkg = path.resolve(dir, 'pkg-with-bundled-dep') +var dep = path.resolve(pkg, 'node_modules', 'a-bundled-dep') + +var pkgJson = JSON.stringify({ + name: 'pkg-with-bundled-dep', + version: '1.0.0', + dependencies: { + }, + bundledDependencies: [ + 'a-bundled-dep' + ] +}, null, 2) + '\n' + +test('setup', function (t) { + mkdirp.sync(path.join(dir, 'node_modules')) + mkdirp.sync(dep) + + fs.writeFileSync(path.resolve(pkg, 'package.json'), pkgJson) + fs.writeFileSync(path.resolve(dep, 'index.js'), '') + t.end() +}) + +test('proper error on bundled dep with no package.json', function (t) { + t.plan(3) + var npmArgs = ['install', './' + path.basename(pkg)] + + common.npm(npmArgs, { cwd: dir }, function (err, code, stdout, stderr) { + t.ifError(err, 'npm ran without issue') + t.notEqual(code, 0) + t.like(stderr, /ENOENT/, 'ENOENT should be in stderr') + t.end() + }) +}) + +test('cleanup', function (t) { + rimraf.sync(dir) + t.end() +}) diff --git a/deps/npm/test/tap/cache-ls-filenames.js b/deps/npm/test/tap/cache-ls-filenames.js new file mode 100644 index 0000000000..c67bca25f3 --- /dev/null +++ b/deps/npm/test/tap/cache-ls-filenames.js @@ -0,0 +1,51 @@ +var t = require('tap') +var path = require('path') +var fs = require('fs') +var mkdirp = require('mkdirp') +var rimraf = require('rimraf') +var spawn = require('child_process').spawn +var npm = require.resolve('../../bin/npm-cli.js') +var dir = path.resolve(__dirname, 'cache-ls-filenames') +var node = process.execPath + +t.test('setup', function (t) { + rimraf.sync(dir) + mkdirp.sync(dir + '/a/b/c/d') + for (var i = 0; i < 5; i++) { + fs.writeFileSync(dir + '/file-' + i, 'x\n') + fs.writeFileSync(dir + '/a/b/file-' + i, 'x\n') + } + t.end() +}) + +function test (t, args) { + var child = spawn(node, [npm, 'cache', 'ls', '--cache=' + dir].concat(args)) + var out = '' + child.stdout.on('data', function (c) { + out += c + }) + child.on('close', function (code, signal) { + t.equal(code, 0) + t.equal(signal, null) + out.trim().split(/[\n\r]+/).map(function (filename) { + return filename.replace(/^~/, process.env.HOME) + }).forEach(function (file) { + // verify that all exist + t.ok(fs.existsSync(file), 'exists: ' + file) + }) + t.end() + }) +} + +t.test('without path arg', function (t) { + test(t, []) +}) + +t.test('with path arg', function (t) { + test(t, ['a']) +}) + +t.test('cleanup', function (t) { + rimraf.sync(dir) + t.end() +}) diff --git a/deps/npm/test/tap/cache-shasum.js b/deps/npm/test/tap/cache-shasum.js index 90915ed850..40495c0995 100644 --- a/deps/npm/test/tap/cache-shasum.js +++ b/deps/npm/test/tap/cache-shasum.js @@ -1,4 +1,3 @@ -var npm = require.resolve('../../') var test = require('tap').test var path = require('path') var rimraf = require('rimraf') @@ -6,7 +5,6 @@ var mkdirp = require('mkdirp') var mr = require('npm-registry-mock') var common = require('../common-tap.js') var cache = path.resolve(__dirname, 'cache-shasum') -var spawn = require('child_process').spawn var sha = require('sha') var server @@ -21,20 +19,15 @@ test('mock reg', function (t) { }) test('npm cache add request', function (t) { - var c = spawn(process.execPath, [ - npm, 'cache', 'add', 'request@2.27.0', + common.npm([ + 'cache', 'add', 'request@2.27.0', '--cache=' + cache, '--registry=' + common.registry, - '--loglevel=quiet' - ]) - c.stderr.pipe(process.stderr) - - c.stdout.on('data', function (d) { - t.fail('Should not get data on stdout: ' + d) - }) - - c.on('close', function (code) { - t.notOk(code, 'exit ok') + '--loglevel=error' + ], {}, function (err, code, stdout) { + if (err) throw err + t.is(code, 0, 'cmd ran without error') + t.is(stdout, '', 'should not get data on stdout') t.end() }) }) @@ -53,6 +46,5 @@ test('compare', function (t) { test('cleanup', function (t) { server.close() - rimraf.sync(cache) - t.end() + rimraf(cache, t.end) }) diff --git a/deps/npm/test/tap/check-permissions.js b/deps/npm/test/tap/check-permissions.js index d3c0c6da25..0a5f2e038a 100644 --- a/deps/npm/test/tap/check-permissions.js +++ b/deps/npm/test/tap/check-permissions.js @@ -78,9 +78,14 @@ function writableTests (t, writable) { writable(writableDir, function (er) { t.error(er, 'writable dir is writable') }) - writable(nonWritableDir, function (er) { - t.ok(er, 'non-writable dir resulted in an error') - }) + if (process.platform !== 'win32') { + // Windows folders cannot be set to be read-only. + writable(nonWritableDir, function (er) { + t.ok(er, 'non-writable dir resulted in an error') + }) + } else { + t.pass('windows folders cannot be read-only') + } } function cleanup () { diff --git a/deps/npm/test/tap/config-basic.js b/deps/npm/test/tap/config-basic.js index ff33181470..cabfa24396 100644 --- a/deps/npm/test/tap/config-basic.js +++ b/deps/npm/test/tap/config-basic.js @@ -11,7 +11,6 @@ var projectData = { var ucData = common.ucData var envData = common.envData -var envDataFix = common.envDataFix var gcData = { 'package-config:foo': 'boo' } @@ -19,9 +18,17 @@ var biData = {} var cli = { foo: 'bar', umask: parseInt('022', 8) } +var expectNames = [ + 'cli', + 'envData', + 'projectData', + 'ucData', + 'gcData', + 'biData' +] var expectList = [ cli, - envDataFix, + envData, projectData, ucData, gcData, @@ -31,7 +38,7 @@ var expectList = [ var expectSources = { cli: { data: cli }, env: { - data: envDataFix, + data: envData, source: envData, prefix: '' }, @@ -53,17 +60,31 @@ var expectSources = { builtin: { data: biData } } +function isDeeplyDetails (t, aa, bb, msg, seen) { + if (aa == null && bb == null) return t.pass(msg) + if (typeof bb !== 'object') return t.is(aa, bb, msg) + if (!seen) seen = [] + for (var kk in seen) if (seen[kk] === aa || seen[kk] === bb) return + seen.push(aa, bb) + t.is(Object.keys(aa).length, Object.keys(bb).length, msg + ': # of elements') + Object.keys(bb).forEach(function (key) { + isDeeplyDetails(t, aa[key], bb[key], msg + ' -> ' + key, seen) + }) +} + test('no builtin', function (t) { t.comment(process.env) npmconf.load(cli, function (er, conf) { if (er) throw er - t.same(conf.list, expectList, 'config properties in list format match expected') - t.same(conf.sources, expectSources, 'config by source matches expected') + expectNames.forEach(function (name, ii) { + isDeeplyDetails(t, conf.list[ii], expectList[ii], 'config properities list: ' + name) + }) + isDeeplyDetails(t, conf.sources, expectSources, 'config by source') t.same(npmconf.rootConf.list, [], 'root configuration is empty') - t.equal(npmconf.rootConf.root, npmconf.defs.defaults, 'defaults match up') - t.equal(conf.root, npmconf.defs.defaults, 'current root config matches defaults') - t.equal(conf.get('umask'), parseInt('022', 8), 'umask is as expected') - t.equal(conf.get('heading'), 'npm', 'config name is as expected') + isDeeplyDetails(t, npmconf.rootConf.root, npmconf.defs.defaults, 'defaults') + isDeeplyDetails(t, conf.root, npmconf.defs.defaults, 'current root config is defaults') + t.is(conf.get('umask'), parseInt('022', 8), 'umask is as expected') + t.is(conf.get('heading'), 'npm', 'config name is as expected') t.end() }) }) diff --git a/deps/npm/test/tap/config-certfile.js b/deps/npm/test/tap/config-certfile.js index 223ff34196..4b960672ad 100644 --- a/deps/npm/test/tap/config-certfile.js +++ b/deps/npm/test/tap/config-certfile.js @@ -12,7 +12,8 @@ test('cafile loads as ca', function (t) { if (er) throw er t.same(conf.get('cafile'), cafile) - t.same(conf.get('ca').join('\n'), fs.readFileSync(cafile, 'utf8').trim()) + var ca = fs.readFileSync(cafile, 'utf8').trim() + t.same(conf.get('ca').join(ca.match(/\r/g) ? '\r\n' : '\n'), ca) t.end() }) }) diff --git a/deps/npm/test/tap/config-edit.js b/deps/npm/test/tap/config-edit.js index f9e09aba3a..7d6eb2588d 100644 --- a/deps/npm/test/tap/config-edit.js +++ b/deps/npm/test/tap/config-edit.js @@ -8,7 +8,7 @@ var common = require('../common-tap.js') var pkg = path.resolve(__dirname, 'npm-global-edit') -var editorSrc = function () {/* +var editorSrc = function () { /* #!/usr/bin/env node var fs = require('fs') if (fs.existsSync(process.argv[2])) { @@ -17,7 +17,7 @@ if (fs.existsSync(process.argv[2])) { console.log('error') process.exit(1) } -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') var editorPath = path.join(pkg, 'editor') test('setup', function (t) { @@ -38,7 +38,9 @@ test('saving configs', function (t) { cwd: pkg, env: { PATH: process.env.PATH, - EDITOR: editorPath + // We rely on the cwd + relative path combo here because otherwise, + // this test will break if there's spaces in the editorPath + EDITOR: 'node editor' } } common.npm( diff --git a/deps/npm/test/tap/dedupe-scoped.js b/deps/npm/test/tap/dedupe-scoped.js index bc352356d4..bcd520420b 100644 --- a/deps/npm/test/tap/dedupe-scoped.js +++ b/deps/npm/test/tap/dedupe-scoped.js @@ -11,12 +11,12 @@ var modules = join(pkg, 'node_modules') var EXEC_OPTS = { cwd: pkg } -var body = function () {/* -@scope/shared@2.1.6 node_modules/first/node_modules/@scope/shared -> node_modules/@scope/shared -firstUnique@0.6.0 node_modules/first/node_modules/firstUnique -> node_modules/firstUnique -secondUnique@1.2.0 node_modules/second/node_modules/secondUnique -> node_modules/secondUnique -- @scope/shared@2.1.6 node_modules/second/node_modules/@scope/shared -*/}.toString().split('\n').slice(1, -1) +var body = [ + '@scope/shared@2.1.6 node_modules/first/node_modules/@scope/shared -> node_modules/@scope/shared', + 'firstUnique@0.6.0 node_modules/first/node_modules/firstUnique -> node_modules/firstUnique', + 'secondUnique@1.2.0 node_modules/second/node_modules/secondUnique -> node_modules/secondUnique', + '- @scope/shared@2.1.6 node_modules/second/node_modules/@scope/shared' +] var deduper = { 'name': 'dedupe', @@ -79,7 +79,7 @@ test('dedupe finds the common scoped modules and moves it up one level', functio t.notOk(code, 'npm ran without issue') t.notOk(stderr, 'npm printed no errors') t.same( - stdout.trim().split('\n').map(ltrimm), + stdout.trim().replace(/\\/g, '/').split('\n').map(ltrimm), body.map(ltrimm), 'got expected output' ) diff --git a/deps/npm/test/tap/do-not-remove-other-bins.js b/deps/npm/test/tap/do-not-remove-other-bins.js index af6de62305..6fec728d43 100644 --- a/deps/npm/test/tap/do-not-remove-other-bins.js +++ b/deps/npm/test/tap/do-not-remove-other-bins.js @@ -93,7 +93,7 @@ test('verify bins', function (t) { var bin = path.dirname( path.resolve( installBin, - fs.readlinkSync(path.join(installBin, 'testbin')))) + common.readBinLink(path.join(installBin, 'testbin')))) t.is(bin, path.join(installPath, 'node_modules', 'b')) t.end() }) @@ -114,7 +114,7 @@ test('verify postremoval bins', function (t) { var bin = path.dirname( path.resolve( installBin, - fs.readlinkSync(path.join(installBin, 'testbin')))) + common.readBinLink(path.join(installBin, 'testbin')))) t.is(bin, path.join(installPath, 'node_modules', 'b')) t.end() }) diff --git a/deps/npm/test/tap/extraneous-dep-cycle-ls-ok.js b/deps/npm/test/tap/extraneous-dep-cycle-ls-ok.js index 23b7519361..767cb6d7ff 100644 --- a/deps/npm/test/tap/extraneous-dep-cycle-ls-ok.js +++ b/deps/npm/test/tap/extraneous-dep-cycle-ls-ok.js @@ -57,7 +57,7 @@ var expected = pkg + '\n' + ' └── moduleB@1.0.0\n\n' test('extraneous-dep-cycle', function (t) { - common.npm(['ls'], {cwd: pkg}, function (er, code, stdout, stderr) { + common.npm(['ls', '--unicode=true'], {cwd: pkg}, function (er, code, stdout, stderr) { t.ifErr(er, 'install finished successfully') t.is(stdout, expected, 'ls output shows module') t.end() diff --git a/deps/npm/test/tap/gently-rm-linked-module.js b/deps/npm/test/tap/gently-rm-linked-module.js index 1ffe7a8208..aeae71eee0 100644 --- a/deps/npm/test/tap/gently-rm-linked-module.js +++ b/deps/npm/test/tap/gently-rm-linked-module.js @@ -1,28 +1,52 @@ +var common = require('../common-tap.js') + var basename = require('path').basename var resolve = require('path').resolve var fs = require('graceful-fs') var test = require('tap').test -var mkdirp = require('mkdirp') var rimraf = require('rimraf') - -var common = require('../common-tap.js') +var Tacks = require('tacks') +var File = Tacks.File +var Dir = Tacks.Dir +var Symlink = Tacks.Symlink +var extend = Object.assign || require('util')._extend +var isWindows = require('../../lib/utils/is-windows.js') var base = resolve(__dirname, basename(__filename, '.js')) -var pkg = resolve(base, 'gently-rm-linked') -var dep = resolve(base, 'test-linked') -var glb = resolve(base, 'test-global') -var lnk = resolve(base, 'test-global-link') +var fixture = new Tacks(Dir({ + 'working-dir': Dir({ + 'node_modules': Dir({}) // so it doesn't try to install into npm's own node_modules + }), + 'test-module': Dir({ + 'package.json': File({ + name: '@test/linked', + version: '1.0.0', + bin: { + linked: './index.js' + } + }), + 'index.js': File("module.exports = function () { console.log('whoop whoop') }") + }), + 'global-dir': Dir({}), + 'linked-global-dir': Symlink('global-dir') +})) -var EXEC_OPTS = { cwd: pkg } +var workingDir = resolve(base, 'working-dir') +var toInstall = resolve(base, 'test-module') +var linkedGlobal = resolve(base, 'linked-global-dir') -var index = "module.exports = function () { console.log('whoop whoop') }" +var env = extend({}, process.env) -var fixture = { - name: '@test/linked', - version: '1.0.0', - bin: { - linked: './index.js' - } +// We set the global install location via env var here +// instead of passing it in via `--prefix` because +// `--prefix` ALSO changes the current package location. +// And we don't ue the PREFIX env var because +// npm_config_prefix takes precedence over it and is +// passed in when running from the npm test suite. +env.npm_config_prefix = linkedGlobal +var EXEC_OPTS = { + cwd: workingDir, + env: env } test('setup', function (t) { @@ -36,32 +60,41 @@ test('install and link', function (t) { // link our test module into the global folder common.npm( [ - '--prefix', lnk, '--loglevel', 'error', 'link', - dep + toInstall ], EXEC_OPTS, - function (er, code, stdout, stderr) { + function (er, code) { if (er) throw er t.is(code, 0, 'link succeeded') - t.is(stderr, '', 'no log output') - t.ok(doesModuleExist(), 'installed ok') + var globalBin = resolve(linkedGlobal, isWindows ? '.' : 'bin', 'linked') + var globalModule = resolve(linkedGlobal, isWindows ? '.' : 'lib', 'node_modules', '@test', 'linked') + var localBin = resolve(workingDir, 'node_modules', '.bin', 'linked') + var localModule = resolve(workingDir, 'node_modules', '@test', 'linked') + try { + t.ok(fs.statSync(globalBin), 'global bin exists') + t.is(fs.lstatSync(globalModule).isSymbolicLink(), true, 'global module is link') + t.ok(fs.statSync(localBin), 'local bin exists') + t.is(fs.lstatSync(localModule).isSymbolicLink(), true, 'local module is link') + } catch (ex) { + t.ifError(ex, 'linking happened') + } + if (code !== 0) return t.end() // and try removing it and make sure that succeeds common.npm( [ '--global', - '--prefix', lnk, '--loglevel', 'error', 'rm', '@test/linked' ], EXEC_OPTS, - function (er, code, stdout, stderr) { + function (er, code) { if (er) throw er t.is(code, 0, 'rm succeeded') - t.is(stderr, '', 'no log output') - t.notOk(doesModuleExist(), 'removed ok') + t.throws(function () { fs.statSync(globalBin) }, 'global bin removed') + t.throws(function () { fs.statSync(globalModule) }, 'global module removed') t.end() } ) @@ -75,32 +108,11 @@ test('cleanup', function (t) { t.end() }) -function doesModuleExist () { - var binPath = resolve(lnk, 'bin', 'linked') - var pkgPath = resolve(lnk, 'lib', 'node_modules', '@test', 'linked') - try { - fs.statSync(binPath) - fs.statSync(pkgPath) - return true - } catch (ex) { - return false - } -} - function cleanup () { - rimraf.sync(pkg) - rimraf.sync(dep) - rimraf.sync(lnk) - rimraf.sync(glb) + fixture.remove(base) + rimraf.sync(base) } function setup () { - mkdirp.sync(pkg) - mkdirp.sync(glb) - fs.symlinkSync(glb, lnk) - // so it doesn't try to install into npm's own node_modules - mkdirp.sync(resolve(pkg, 'node_modules')) - mkdirp.sync(dep) - fs.writeFileSync(resolve(dep, 'package.json'), JSON.stringify(fixture)) - fs.writeFileSync(resolve(dep, 'index.js'), index) + fixture.create(base) } diff --git a/deps/npm/test/tap/gently-rm-symlinked-global-dir.js b/deps/npm/test/tap/gently-rm-symlinked-global-dir.js index 93ed3edaa4..b159a4ec2f 100644 --- a/deps/npm/test/tap/gently-rm-symlinked-global-dir.js +++ b/deps/npm/test/tap/gently-rm-symlinked-global-dir.js @@ -1,10 +1,11 @@ +var common = require('../common-tap.js') + var resolve = require('path').resolve var fs = require('graceful-fs') var test = require('tap').test var mkdirp = require('mkdirp') var rimraf = require('rimraf') - -var common = require('../common-tap.js') +var isWindows = require('../../lib/utils/is-windows.js') var pkg = resolve(__dirname, 'gently-rm-linked') var dep = resolve(__dirname, 'test-linked') @@ -36,6 +37,7 @@ test('install and link', function (t) { '--global', '--prefix', lnk, '--loglevel', 'silent', + '--unicode', 'false', 'install', '../test-linked' ], EXEC_OPTS, @@ -52,6 +54,7 @@ test('install and link', function (t) { '--global', '--prefix', lnk, '--loglevel', 'silent', + '--unicode', 'false', 'install', '../test-linked' ], EXEC_OPTS, @@ -84,15 +87,20 @@ function removeBlank (line) { return line !== '' } +function resolvePath () { + return resolve.apply(null, Array.prototype.slice.call(arguments) + .filter(function (arg) { return arg })) +} + function verify (t, stdout) { - var binPath = resolve(lnk, 'bin', 'linked') - var pkgPath = resolve(lnk, 'lib', 'node_modules', '@test', 'linked') - var trgPath = resolve(pkgPath, 'index.js') + var binPath = resolvePath(lnk, !isWindows && 'bin', 'linked') + var pkgPath = resolvePath(lnk, !isWindows && 'lib', 'node_modules', '@test', 'linked') + var trgPath = resolvePath(pkgPath, 'index.js') t.deepEqual( stdout.split('\n').filter(removeBlank), [ binPath + ' -> ' + trgPath, - resolve(lnk, 'lib'), - '└── @test/linked@1.0.0 ' + resolvePath(lnk, !isWindows && 'lib'), + '`-- @test/linked@1.0.0 ' ], 'got expected install output' ) @@ -108,7 +116,7 @@ function cleanup () { function setup () { mkdirp.sync(pkg) mkdirp.sync(glb) - fs.symlinkSync(glb, lnk) + fs.symlinkSync(glb, lnk, 'junction') // so it doesn't try to install into npm's own node_modules mkdirp.sync(resolve(pkg, 'node_modules')) mkdirp.sync(dep) diff --git a/deps/npm/test/tap/git-cache-locking.js b/deps/npm/test/tap/git-cache-locking.js index e08c96e1b7..29ab5709b9 100644 --- a/deps/npm/test/tap/git-cache-locking.js +++ b/deps/npm/test/tap/git-cache-locking.js @@ -6,6 +6,7 @@ var mkdirp = require('mkdirp') var pkg = path.resolve(__dirname, 'git-cache-locking') var tmp = path.join(pkg, 'tmp') var cache = path.join(pkg, 'cache') +var shallowClone = Object.assign || require('util')._extend test('setup', function (t) { rimraf.sync(pkg) @@ -17,6 +18,12 @@ test('git-cache-locking: install a git dependency', function (t) { // disable git integration tests on Travis. if (process.env.TRAVIS) return t.end() + var gitEnv = shallowClone({}, process.env) + gitEnv.npm_config_cache = cache + gitEnv.npm_config_tmp = tmp + gitEnv.npm_config_prefix = pkg + gitEnv.npm_config_global = 'false' + // package c depends on a.git#master and b.git#master // package b depends on a.git#master common.npm([ @@ -24,17 +31,9 @@ test('git-cache-locking: install a git dependency', function (t) { 'git://github.com/nigelzor/npm-4503-c.git' ], { cwd: pkg, - env: { - npm_config_cache: cache, - npm_config_tmp: tmp, - npm_config_prefix: pkg, - npm_config_global: 'false', - HOME: process.env.HOME, - Path: process.env.PATH, - PATH: process.env.PATH - } + env: gitEnv }, function (err, code, stdout, stderr) { - t.ifErr(err, 'npm install finished without error') + if (err) throw err t.equal(0, code, 'npm install should succeed') t.end() }) diff --git a/deps/npm/test/tap/git-cache-no-hooks.js b/deps/npm/test/tap/git-cache-no-hooks.js index cfc2d1dc62..0021064cea 100644 --- a/deps/npm/test/tap/git-cache-no-hooks.js +++ b/deps/npm/test/tap/git-cache-no-hooks.js @@ -1,12 +1,11 @@ var test = require('tap').test var fs = require('fs') var path = require('path') +var common = require('../common-tap.js') var rimraf = require('rimraf') var mkdirp = require('mkdirp') -var spawn = require('child_process').spawn -var npmCli = require.resolve('../../bin/npm-cli.js') -var node = process.execPath var pkg = path.resolve(__dirname, 'git-cache-no-hooks') +var osenv = require('osenv') var tmp = path.join(pkg, 'tmp') var cache = path.join(pkg, 'cache') @@ -23,27 +22,15 @@ test('git-cache-no-hooks: install a git dependency', function (t) { // disable git integration tests on Travis. if (process.env.TRAVIS) return t.end() - var command = [ - npmCli, - 'install', - 'git://github.com/nigelzor/npm-4503-a.git' - ] - var child = spawn(node, command, { - cwd: pkg, - env: { - 'npm_config_cache': cache, - 'npm_config_tmp': tmp, - 'npm_config_prefix': pkg, - 'npm_config_global': 'false', - 'npm_config_umask': '00', - HOME: process.env.HOME, - Path: process.env.PATH, - PATH: process.env.PATH - }, - stdio: 'inherit' - }) - - child.on('close', function (code) { + common.npm([ + 'install', 'git://github.com/nigelzor/npm-4503-a.git', + '--cache', cache, + '--tmp', tmp + ], { + cwd: pkg + }, function (err, code, stdout, stderr) { + t.ifErr(err, 'npm completed') + t.equal(stderr, '', 'no error output') t.equal(code, 0, 'npm install should succeed') // verify permissions on git hooks @@ -57,6 +44,7 @@ test('git-cache-no-hooks: install a git dependency', function (t) { }) test('cleanup', function (t) { + process.chdir(osenv.tmpdir()) rimraf.sync(pkg) t.end() }) diff --git a/deps/npm/test/tap/git-dependency-install-link.js b/deps/npm/test/tap/git-dependency-install-link.js index 8af1b853ad..1bf839f302 100644 --- a/deps/npm/test/tap/git-dependency-install-link.js +++ b/deps/npm/test/tap/git-dependency-install-link.js @@ -13,6 +13,7 @@ var common = require('../common-tap.js') var pkg = resolve(__dirname, 'git-dependency-install-link') var repo = resolve(__dirname, 'git-dependency-install-link-repo') +var prefix = resolve(__dirname, 'git-dependency-install-link-prefix') var cache = resolve(pkg, 'cache') var daemon @@ -25,6 +26,7 @@ var EXEC_OPTS = { cwd: pkg, cache: cache } +process.env.npm_config_prefix = prefix var pjParent = JSON.stringify({ name: 'parent', @@ -63,7 +65,7 @@ test('setup', function (t) { test('install from git repo [no --link]', function (t) { process.chdir(pkg) - common.npm(['install', '--loglevel', 'error'], EXEC_OPTS, function (err, code, stdout, stderr) { + common.npm(['install'], EXEC_OPTS, function (err, code, stdout, stderr) { t.ifError(err, 'npm install failed') t.dissimilar(stderr, /Command failed:/, 'expect git to succeed') @@ -82,11 +84,13 @@ test('install from git repo [with --link]', function (t) { process.chdir(pkg) rimraf.sync(resolve(pkg, 'node_modules')) - common.npm(['install', '--link', '--loglevel', 'error'], EXEC_OPTS, function (err, code, stdout, stderr) { + common.npm(['install', '--link'], EXEC_OPTS, function (err, code, stdout, stderr) { t.ifError(err, 'npm install --link failed') + t.equal(code, 0, 'npm install --link returned non-0 code') t.dissimilar(stderr, /Command failed:/, 'expect git to succeed') t.dissimilar(stderr, /version not found/, 'should not go to repository') + t.equal(stderr, '', 'no actual output on stderr') readJson(resolve(pkg, 'node_modules', 'child', 'package.json'), function (err, data) { t.ifError(err, 'error reading child package.json') @@ -170,5 +174,6 @@ function setup (cb) { function cleanup () { process.chdir(osenv.tmpdir()) rimraf.sync(repo) + rimraf.sync(prefix) rimraf.sync(pkg) } diff --git a/deps/npm/test/tap/git-npmignore.js b/deps/npm/test/tap/git-npmignore.js index 4cd9898722..6b99bdf1fa 100644 --- a/deps/npm/test/tap/git-npmignore.js +++ b/deps/npm/test/tap/git-npmignore.js @@ -1,21 +1,50 @@ -var cat = require('graceful-fs').writeFileSync -var exec = require('child_process').exec +var child_process = require('child_process') var readdir = require('graceful-fs').readdirSync +var path = require('path') var resolve = require('path').resolve -var mkdirp = require('mkdirp') var rimraf = require('rimraf') var test = require('tap').test -var tmpdir = require('osenv').tmpdir var which = require('which') var common = require('../common-tap.js') +var escapeArg = require('../../lib/utils/escape-arg.js') +var Tacks = require('tacks') +var Dir = Tacks.Dir +var File = Tacks.File + +var fixture = new Tacks(Dir({ + deps: Dir({ + gitch: Dir({ + '.npmignore': File( + 't.js\n' + ), + '.gitignore': File( + 'node_modules/\n' + ), + 'a.js': File( + "console.log('hi');" + ), + 't.js': File( + "require('tap').test(function (t) { t.pass('I am a test!'); t.end(); });" + ), + 'package.json': File({ + name: 'gitch', + version: '1.0.0', + private: true, + main: 'a.js' + }) + }) + }), + 'node_modules': Dir({ + }) +})) -var pkg = resolve(__dirname, 'git-npmignore') -var dep = resolve(pkg, 'deps', 'gitch') +var testdir = resolve(__dirname, path.basename(__filename, '.js')) +var dep = resolve(testdir, 'deps', 'gitch') var packname = 'gitch-1.0.0.tgz' -var packed = resolve(pkg, packname) -var modules = resolve(pkg, 'node_modules') +var packed = resolve(testdir, packname) +var modules = resolve(testdir, 'node_modules') var installed = resolve(modules, 'gitch') var expected = [ 'a.js', @@ -23,18 +52,11 @@ var expected = [ '.npmignore' ].sort() -var EXEC_OPTS = { cwd: pkg } - -var gitignore = 'node_modules/\n' -var npmignore = 't.js\n' +var NPM_OPTS = { cwd: testdir } -var a = "console.log('hi');" -var t = "require('tap').test(function (t) { t.pass('I am a test!'); t.end(); });" -var fixture = { - 'name': 'gitch', - 'version': '1.0.0', - 'private': true, - 'main': 'a.js' +function exec (todo, opts, cb) { + console.log(' # EXEC:', todo) + child_process.exec(todo, opts, cb) } test('setup', function (t) { @@ -50,7 +72,10 @@ test('npm pack directly from directory', function (t) { }) test('npm pack via git', function (t) { - packInstallTest('git+file://' + dep, t) + var urlPath = dep + .replace(/\\/g, '/') // fixup slashes for Windows + .replace(/^\/+/, '') // remove any leading slashes + packInstallTest('git+file:///' + urlPath, t) }) test('cleanup', function (t) { @@ -60,31 +85,32 @@ test('cleanup', function (t) { }) function packInstallTest (spec, t) { + console.log(' # pack', spec) common.npm( [ - '--loglevel', 'silent', + '--loglevel', 'error', 'pack', spec ], - EXEC_OPTS, + NPM_OPTS, function (err, code, stdout, stderr) { - t.ifError(err, 'npm pack ran without error') - t.notOk(code, 'npm pack exited cleanly') - t.notOk(stderr, 'npm pack ran silently') - t.equal(stdout.trim(), packname, 'got expected package name') + if (err) throw err + t.is(code, 0, 'npm pack exited cleanly') + t.is(stderr, '', 'npm pack ran silently') + t.is(stdout.trim(), packname, 'got expected package name') common.npm( [ - '--loglevel', 'silent', + '--loglevel', 'error', 'install', packed ], - EXEC_OPTS, + NPM_OPTS, function (err, code, stdout, stderr) { - t.ifError(err, 'npm install ran without error') - t.notOk(code, 'npm install exited cleanly') - t.notOk(stderr, 'npm install ran silently') + if (err) throw err + t.is(code, 0, 'npm install exited cleanly') + t.is(stderr, '', 'npm install ran silently') var actual = readdir(installed).sort() - t.same(actual, expected, 'no unexpected files in packed directory') + t.isDeeply(actual, expected, 'no unexpected files in packed directory') rimraf(packed, function () { t.end() @@ -96,72 +122,71 @@ function packInstallTest (spec, t) { } function cleanup () { - process.chdir(tmpdir()) - rimraf.sync(pkg) + fixture.remove(testdir) + rimraf.sync(testdir) } function setup (cb) { cleanup() - mkdirp.sync(modules) - mkdirp.sync(dep) - - process.chdir(dep) - - cat(resolve(dep, '.npmignore'), npmignore) - cat(resolve(dep, '.gitignore'), gitignore) - cat(resolve(dep, 'a.js'), a) - cat(resolve(dep, 't.js'), t) - cat(resolve(dep, 'package.json'), JSON.stringify(fixture)) + fixture.create(testdir) common.npm( [ - '--loglevel', 'silent', + '--loglevel', 'error', 'cache', 'clean' ], - EXEC_OPTS, + NPM_OPTS, function (er, code, _, stderr) { if (er) return cb(er) if (code) return cb(new Error('npm cache nonzero exit: ' + code)) if (stderr) return cb(new Error('npm cache clean error: ' + stderr)) - which('git', function found (er, git) { + which('git', function found (er, gitPath) { if (er) return cb(er) - exec(git + ' init', init) + var git = escapeArg(gitPath) + + exec(git + ' init', {cwd: dep}, init) function init (er, _, stderr) { if (er) return cb(er) if (stderr) return cb(new Error('git init error: ' + stderr)) - exec(git + " config user.name 'Phantom Faker'", user) + exec(git + " config user.name 'Phantom Faker'", {cwd: dep}, user) } function user (er, _, stderr) { if (er) return cb(er) if (stderr) return cb(new Error('git config error: ' + stderr)) - exec(git + ' config user.email nope@not.real', email) + exec(git + ' config user.email nope@not.real', {cwd: dep}, email) } function email (er, _, stderr) { if (er) return cb(er) if (stderr) return cb(new Error('git config error: ' + stderr)) - exec(git + ' add .', addAll) + exec(git + ' config core.autocrlf input', {cwd: dep}, autocrlf) + } + + function autocrlf (er, _, stderr) { + if (er) return cb(er) + if (stderr) return cb(new Error('git config error: ' + stderr)) + + exec(git + ' add .', {cwd: dep}, addAll) } function addAll (er, _, stderr) { if (er) return cb(er) if (stderr) return cb(new Error('git add . error: ' + stderr)) - exec(git + ' commit -m boot', commit) + exec(git + ' commit -m boot', {cwd: dep}, commit) } function commit (er, _, stderr) { if (er) return cb(er) if (stderr) return cb(new Error('git commit error: ' + stderr)) - cb() } }) diff --git a/deps/npm/test/tap/github-shortcut.js b/deps/npm/test/tap/github-shortcut.js index 1b01de4cff..c0a67d21a4 100644 --- a/deps/npm/test/tap/github-shortcut.js +++ b/deps/npm/test/tap/github-shortcut.js @@ -32,10 +32,10 @@ test('github-shortcut', function (t) { 'child_process': { 'execFile': function (cmd, args, options, cb) { process.nextTick(function () { - if (args[0] !== 'clone') return cb(null, '', '') + if (args.indexOf('clone') === -1) return cb(null, '', '') var cloneUrl = cloneUrls.shift() if (cloneUrl) { - t.is(args[3], cloneUrl[0], cloneUrl[1]) + t.is(args[args.length - 2], cloneUrl[0], cloneUrl[1]) } else { t.fail('too many attempts to clone') } @@ -52,8 +52,8 @@ test('github-shortcut', function (t) { loglevel: 'silent' } t.plan(1 + cloneUrls.length) - npm.load(opts, function (er) { - t.ifError(er, 'npm loaded without error') + npm.load(opts, function (err) { + t.ifError(err, 'npm loaded without error') npm.commands.install(['foo/private'], function (er, result) { t.end() }) diff --git a/deps/npm/test/tap/graceful-restart.js b/deps/npm/test/tap/graceful-restart.js index 21da0d9904..56513fbf7e 100644 --- a/deps/npm/test/tap/graceful-restart.js +++ b/deps/npm/test/tap/graceful-restart.js @@ -70,7 +70,7 @@ test('graceless restart', function (t) { createChild(['run-script', 'restart'], function (err, code, out) { t.ifError(err, 'restart finished successfully') t.equal(code, 0, 'npm run-script exited with code') - t.equal(out, outGraceless, 'expected all scripts to run') + t.equal(out.replace(/\r/g, ''), outGraceless, 'expected all scripts to run') t.end() }) }) @@ -80,7 +80,7 @@ test('graceful restart', function (t) { createChild(['run-script', 'restart'], function (err, code, out) { t.ifError(err, 'restart finished successfully') t.equal(code, 0, 'npm run-script exited with code') - t.equal(out, outGraceful, 'expected only *restart scripts to run') + t.equal(out.replace(/\r/g, ''), outGraceful, 'expected only *restart scripts to run') t.end() }) }) diff --git a/deps/npm/test/tap/install-bad-man.js b/deps/npm/test/tap/install-bad-man.js index 756b4a5902..226d0b24fc 100644 --- a/deps/npm/test/tap/install-bad-man.js +++ b/deps/npm/test/tap/install-bad-man.js @@ -21,6 +21,8 @@ var json = { man: [ './install-bad-man.1.lol' ] } +common.pendIfWindows('man pages do not get installed on Windows') + test('setup', function (t) { setup() t.pass('setup ran') diff --git a/deps/npm/test/tap/install-link-scripts.js b/deps/npm/test/tap/install-link-scripts.js index 5ad2feafe8..acc88b4b2c 100644 --- a/deps/npm/test/tap/install-link-scripts.js +++ b/deps/npm/test/tap/install-link-scripts.js @@ -24,15 +24,15 @@ var dependency = { name: 'dep', version: '1.0.0', scripts: { - install: './bin/foo' + install: 'node ./bin/foo' } } -var foo = function () {/* +var foo = function () { /* #!/usr/bin/env node console.log('hey sup') -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') process.env.npm_config_prefix = tmp diff --git a/deps/npm/test/tap/install-man.js b/deps/npm/test/tap/install-man.js index d309788b25..d24819ca78 100644 --- a/deps/npm/test/tap/install-man.js +++ b/deps/npm/test/tap/install-man.js @@ -11,6 +11,8 @@ var common = require('../common-tap.js') var pkg = resolve(__dirname, 'install-man') var target = resolve(__dirname, 'install-man-target') +common.pendIfWindows('man pages do not get installed on Windows') + var EXEC_OPTS = { cwd: target } diff --git a/deps/npm/test/tap/install-save-local.js b/deps/npm/test/tap/install-save-local.js index a9de5ba194..1bc739cb89 100644 --- a/deps/npm/test/tap/install-save-local.js +++ b/deps/npm/test/tap/install-save-local.js @@ -53,7 +53,7 @@ test('\'npm install --save ../local/path\' should save to package.json', functio var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) t.is(Object.keys(pkgJson.dependencies).length, 1, 'only one dep') t.ok( - /file:.*?[/]package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), + /file:.*?[/\\]package-local-dependency$/.test(pkgJson.dependencies['package-local-dependency']), 'local package saved correctly' ) t.end() @@ -82,7 +82,7 @@ test('\'npm install --save-dev ../local/path\' should save to package.json', fun var pkgJson = JSON.parse(fs.readFileSync(pkg + '/package.json', 'utf8')) t.is(Object.keys(pkgJson.devDependencies).length, 1, 'only one dep') t.ok( - /file:.*?[/]package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), + /file:.*?[/\\]package-local-dev-dependency$/.test(pkgJson.devDependencies['package-local-dev-dependency']), 'local package saved correctly' ) diff --git a/deps/npm/test/tap/install-scoped-already-installed.js b/deps/npm/test/tap/install-scoped-already-installed.js index f3c191ddb0..58966b047c 100644 --- a/deps/npm/test/tap/install-scoped-already-installed.js +++ b/deps/npm/test/tap/install-scoped-already-installed.js @@ -125,7 +125,7 @@ test('cleanup', function (t) { }) function contains (list, element) { - var matcher = new RegExp(element + '$') + var matcher = new RegExp(element.replace(/\//g, '[\\\\/]') + '$') for (var i = 0; i < list.length; ++i) { if (matcher.test(list[i])) { return true diff --git a/deps/npm/test/tap/install-scoped-link.js b/deps/npm/test/tap/install-scoped-link.js index 029acb3813..9171b8f46f 100644 --- a/deps/npm/test/tap/install-scoped-link.js +++ b/deps/npm/test/tap/install-scoped-link.js @@ -8,6 +8,8 @@ var osenv = require('osenv') var rimraf = require('rimraf') var test = require('tap').test +var escapeExecPath = require('../../lib/utils/escape-exec-path') + var common = require('../common-tap.js') var pkg = path.join(__dirname, 'install-scoped-link') @@ -16,7 +18,7 @@ var modules = path.join(work, 'node_modules') var EXEC_OPTS = { cwd: work } -var world = 'console.log("hello blrbld")\n' +var world = '#!/usr/bin/env node\nconsole.log("hello blrbld")\n' var json = { name: '@scoped/package', @@ -61,7 +63,7 @@ test('installing package with links', function (t) { var hello = path.join(modules, '.bin', 'hello') t.ok(existsSync(hello), 'binary link exists') - exec('node ' + hello, function (err, stdout, stderr) { + exec(escapeExecPath(hello), function (err, stdout, stderr) { t.ifError(err, 'command ran fine') t.notOk(stderr, 'got no error output back') t.equal(stdout, 'hello blrbld\n', 'output was as expected') diff --git a/deps/npm/test/tap/legacy-bundled-git.js b/deps/npm/test/tap/legacy-bundled-git.js index 355f9467c1..15fbac84ea 100644 --- a/deps/npm/test/tap/legacy-bundled-git.js +++ b/deps/npm/test/tap/legacy-bundled-git.js @@ -69,8 +69,6 @@ test('bundled-git', function (t) { common.npm(['install', '--global-style', fixturepath], {cwd: basepath}, installCheckAndTest) function installCheckAndTest (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'install went ok') var actual = require(path.resolve(installedpath, 'node_modules/glob/node_modules/minimatch/package.json')) @@ -82,8 +80,6 @@ test('bundled-git', function (t) { } function removeCheckAndDone (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'remove went ok') t.done() } diff --git a/deps/npm/test/tap/legacy-missing-bindir.js b/deps/npm/test/tap/legacy-missing-bindir.js index a55703bebd..2285f8d2a7 100644 --- a/deps/npm/test/tap/legacy-missing-bindir.js +++ b/deps/npm/test/tap/legacy-missing-bindir.js @@ -48,8 +48,6 @@ test('missing-bindir', function (t) { function installCheckAndTest (err, code, stdout, stderr) { if (err) throw err - if (stderr) console.error(stderr) - console.log(stdout) t.is(code, 0, 'install went ok') t.is(installedExists('README'), true, 'README') t.is(installedExists('package.json'), true, 'package.json') @@ -58,8 +56,6 @@ test('missing-bindir', function (t) { function removeCheckAndDone (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'remove went ok') t.done() } diff --git a/deps/npm/test/tap/legacy-npm-self-install.js b/deps/npm/test/tap/legacy-npm-self-install.js index 313c059493..57880496c7 100644 --- a/deps/npm/test/tap/legacy-npm-self-install.js +++ b/deps/npm/test/tap/legacy-npm-self-install.js @@ -50,7 +50,7 @@ test('npm-self-install', function (t) { env.npm_config_user_agent = null env.npm_config_color = 'always' env.npm_config_progress = 'always' - var PATH = env.PATH.split(pathsep) + var PATH = env.PATH ? env.PATH.split(pathsep) : [] var binpath = isWin32 ? globalpath : path.join(globalpath, 'bin') var cmdname = isWin32 ? 'npm.cmd' : 'npm' PATH.unshift(binpath) @@ -63,7 +63,7 @@ test('npm-self-install', function (t) { if (err) throw err t.is(code, 0, 'install went ok') t.is(exists(binpath, cmdname), true, 'binary was installed') - t.is(exists(globalpath, 'lib', 'node_modules', 'npm'), true, 'module path exists') + t.is(exists(globalpath, isWin32 ? '' : 'lib', 'node_modules', 'npm'), true, 'module path exists') common.npm(['ls', '--json', '--depth=0'], {cwd: basepath, env: env}, lsCheckAndRemove) } function lsCheckAndRemove (err, code, stdout, stderr) { @@ -73,7 +73,7 @@ test('npm-self-install', function (t) { var installed = JSON.parse(stdout.trim()) t.is(Object.keys(installed.dependencies).length, 1, 'one thing installed') t.is(path.resolve(globalpath, installed.dependencies.npm.from), tarball, 'and it was our npm tarball') - common.npm(['rm', 'npm'], {cwd: basepath, env: env, stdio: 'inherit'}, removeCheck) + common.npm(['rm', 'npm'], {cwd: basepath, env: env}, removeCheck) } function removeCheck (err, code) { if (err) throw err diff --git a/deps/npm/test/tap/legacy-test-package.js b/deps/npm/test/tap/legacy-test-package.js index b0cbaa01a5..d94666b43e 100644 --- a/deps/npm/test/tap/legacy-test-package.js +++ b/deps/npm/test/tap/legacy-test-package.js @@ -36,24 +36,18 @@ test('test-package', function (t) { function installCheckAndTest (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'install went ok') common.npm(['test'], {cwd: installedpath}, testCheckAndRemove) } function testCheckAndRemove (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'npm test w/o test is ok') common.npm(['rm', fixturepath], {cwd: basepath}, removeCheckAndDone) } function removeCheckAndDone (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'remove went ok') t.done() } diff --git a/deps/npm/test/tap/legacy-url-dep.js b/deps/npm/test/tap/legacy-url-dep.js index 9807d6916a..46378cd3ef 100644 --- a/deps/npm/test/tap/legacy-url-dep.js +++ b/deps/npm/test/tap/legacy-url-dep.js @@ -37,8 +37,6 @@ test('url-dep', function (t) { common.npm(['install', fixturepath], {cwd: basepath}, installCheckAndTest) function installCheckAndTest (err, code, stdout, stderr) { if (err) throw err - console.error(stderr) - console.log(stdout) t.is(code, 0, 'install went ok') t.done() } diff --git a/deps/npm/test/tap/lifecycle-path.js b/deps/npm/test/tap/lifecycle-path.js index 39761b48d7..3264fe87be 100644 --- a/deps/npm/test/tap/lifecycle-path.js +++ b/deps/npm/test/tap/lifecycle-path.js @@ -7,54 +7,45 @@ var rimraf = require('rimraf') var test = require('tap').test var common = require('../common-tap.js') +var isWindows = require('../../lib/utils/is-windows.js') var pkg = path.resolve(__dirname, 'lifecycle-path') -var link = path.resolve(pkg, 'node-bin') var PATH -if (process.platform === 'win32') { +if (isWindows) { // On Windows the 'comspec' environment variable is used, // so cmd.exe does not need to be on the path. - PATH = 'C:\\foo\\bar' + PATH = path.dirname(process.env.ComSpec) } else { // On non-Windows, without the path to the shell, nothing usually works. PATH = '/bin:/usr/bin' } -var printPath = 'console.log(process.env.PATH)\n' - -var json = { - name: 'glorb', - version: '1.2.3', - scripts: { - path: './node-bin/node print-path.js' - } -} - test('setup', function (t) { cleanup() mkdirp.sync(pkg) fs.writeFileSync( path.join(pkg, 'package.json'), - JSON.stringify(json, null, 2) + JSON.stringify({}, null, 2) ) - fs.writeFileSync(path.join(pkg, 'print-path.js'), printPath) - fs.symlinkSync(path.dirname(process.execPath), link, 'dir') t.end() }) test('make sure the path is correct', function (t) { - common.npm(['run-script', 'path'], { + common.npm(['run-script', 'env'], { cwd: pkg, env: { - PATH: PATH, - stdio: [ 0, 'pipe', 2 ] - } + PATH: PATH + }, + stdio: [ 0, 'pipe', 2 ] }, function (er, code, stdout) { if (er) throw er t.equal(code, 0, 'exit code') - // remove the banner, we just care about the last line - stdout = stdout.trim().split(/\r|\n/).pop() + var lineMatch = function (line) { + return /^PATH=/i.test(line) + } + // extract just the path value + stdout = stdout.split(/\r?\n/).filter(lineMatch).pop().replace(/^PATH=/, '') var pathSplit = process.platform === 'win32' ? ';' : ':' var root = path.resolve(__dirname, '../..') var actual = stdout.split(pathSplit).map(function (p) { @@ -63,15 +54,19 @@ test('make sure the path is correct', function (t) { } return p.replace(/\\/g, '/') }) + // spawn-wrap adds itself to the path when coverage is enabled + actual = actual.filter(function (p) { + return !p.match(/\.node-spawn-wrap/) + }) // 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) { + ].concat(PATH.split(pathSplit)).map(function (p) { return p.replace(/\\/g, '/') - })) + }) t.same(actual, expect) t.end() }) diff --git a/deps/npm/test/tap/logout-scoped.js b/deps/npm/test/tap/logout-scoped.js index 1323a4d32e..db99320478 100644 --- a/deps/npm/test/tap/logout-scoped.js +++ b/deps/npm/test/tap/logout-scoped.js @@ -12,11 +12,11 @@ var pkg = path.resolve(__dirname, 'logout') var outfile = path.join(pkg, '_npmrc') var opts = { cwd: pkg } -var contents = function () {/* +var contents = function () { /* foo=boo @bar:registry=http://localhost:1337 //localhost:1337/:_authToken=glarb -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') function mocks (server) { server.delete('/-/user/token/glarb') @@ -47,7 +47,7 @@ test('npm logout', function (t) { t.notOk(code, 'exited OK') var config = fs.readFileSync(outfile, 'utf8') - t.equal(config, 'foo=boo\n', 'creds gone') + t.equal(config.trim(), 'foo=boo', 'creds gone') s.close() t.end() } diff --git a/deps/npm/test/tap/logout.js b/deps/npm/test/tap/logout.js index ebe0f51ba1..d62cb4fffc 100644 --- a/deps/npm/test/tap/logout.js +++ b/deps/npm/test/tap/logout.js @@ -12,10 +12,10 @@ var pkg = path.resolve(__dirname, 'logout') var outfile = path.join(pkg, '_npmrc') var opts = { cwd: pkg } -var contents = function () {/* +var contents = function () { /* foo=boo //localhost:1337/:_authToken=glarb -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') function mocks (server) { server.delete('/-/user/token/glarb') @@ -45,7 +45,7 @@ test('npm logout', function (t) { t.notOk(code, 'exited OK') var config = fs.readFileSync(outfile, 'utf8') - t.equal(config, 'foo=boo\n', 'creds gone') + t.notMatch(config, /localhost/, 'creds gone') s.close() t.end() } diff --git a/deps/npm/test/tap/ls-l-depth-0.js b/deps/npm/test/tap/ls-l-depth-0.js index 24fa062908..3958520943 100644 --- a/deps/npm/test/tap/ls-l-depth-0.js +++ b/deps/npm/test/tap/ls-l-depth-0.js @@ -53,6 +53,7 @@ test('#6311: npm ll --depth=0 duplicates listing', function (t) { [ '--loglevel', 'silent', '--registry', common.registry, + '--unicode=true', 'install', dep ], EXEC_OPTS, @@ -72,6 +73,7 @@ test('#6311: npm ll --depth=0 duplicates listing', function (t) { [ '--loglevel', 'silent', 'ls', '--long', + '--unicode=true', '--depth', '0' ], EXEC_OPTS, diff --git a/deps/npm/test/tap/ls.js b/deps/npm/test/tap/ls.js new file mode 100644 index 0000000000..acec723afb --- /dev/null +++ b/deps/npm/test/tap/ls.js @@ -0,0 +1,188 @@ +'use strict' +var test = require('tap').test +var path = require('path') +var rimraf = require('rimraf') +var common = require('../common-tap.js') +var basepath = path.resolve(__dirname, path.basename(__filename, '.js')) +var fixturepath = path.resolve(basepath, 'npm-test-files') +var pkgpath = path.resolve(fixturepath, 'npm-test-ls') +var Tacks = require('tacks') +var File = Tacks.File +var Dir = Tacks.Dir + +test('ls without arg', function (t) { + var fixture = new Tacks( + Dir({ + 'npm-test-ls': Dir({ + 'package.json': File({ + name: 'npm-test-ls', + version: '1.0.0', + dependencies: { + 'dep': 'file:../dep' + } + }) + }), + 'dep': Dir({ + 'package.json': File({ + name: 'dep', + version: '1.0.0' + }) + }) + }) + ) + withFixture(t, fixture, function (done) { + common.npm([ + 'ls', '--json' + ], { + cwd: pkgpath + }, function (err, code, stdout, stderr) { + t.ifErr(err, 'ls succeeded') + t.equal(0, code, 'exit 0 on ls') + var pkg = JSON.parse(stdout) + var deps = pkg.dependencies + t.ok(deps.dep, 'dep present') + done() + }) + }) +}) + +test('ls with filter arg', function (t) { + var fixture = new Tacks( + Dir({ + 'npm-test-ls': Dir({ + 'package.json': File({ + name: 'npm-test-ls', + version: '1.0.0', + dependencies: { + 'dep': 'file:../dep' + } + }) + }), + 'dep': Dir({ + 'package.json': File({ + name: 'dep', + version: '1.0.0' + }) + }), + 'otherdep': Dir({ + 'package.json': File({ + name: 'otherdep', + version: '1.0.0' + }) + }) + }) + ) + withFixture(t, fixture, function (done) { + common.npm([ + 'ls', 'dep', + '--json' + ], { + cwd: path.join(fixturepath, 'npm-test-ls') + }, function (err, code, stdout, stderr) { + t.ifErr(err, 'ls succeeded') + t.equal(0, code, 'exit 0 on ls') + var pkg = JSON.parse(stdout) + var deps = pkg.dependencies + t.ok(deps.dep, 'dep present') + t.notOk(deps.otherdep, 'other dep not present') + done() + }) + }) +}) + +test('ls with missing filtered arg', function (t) { + var fixture = new Tacks( + Dir({ + 'npm-test-ls': Dir({ + 'package.json': File({ + name: 'npm-test-ls', + version: '1.0.0', + dependencies: { + 'dep': 'file:../dep' + } + }) + }), + 'dep': Dir({ + 'package.json': File({ + name: 'dep', + version: '1.0.0' + }) + }) + }) + ) + withFixture(t, fixture, function (done) { + common.npm([ + 'ls', 'notadep', + '--json' + ], { + cwd: path.join(fixturepath, 'npm-test-ls') + }, function (err, code, stdout, stderr) { + t.ifErr(err, 'ls succeeded') + t.equal(1, code, 'exit 1 on ls') + var pkg = JSON.parse(stdout) + var deps = pkg.dependencies + t.notOk(deps, 'deps missing') + t.done() + }) + }) +}) + +test('ls with prerelease pkg', function (t) { + var fixture = new Tacks( + Dir({ + 'npm-test-ls': Dir({ + 'package.json': File({ + name: 'npm-test-ls', + version: '1.0.0', + dependencies: { + 'dep': 'file:../dep' + } + }) + }), + 'dep': Dir({ + 'package.json': File({ + name: 'dep', + version: '1.0.0-pre' + }) + }) + }) + ) + withFixture(t, fixture, function (done) { + common.npm([ + 'ls', 'dep', + '--json' + ], { + cwd: path.join(fixturepath, 'npm-test-ls') + }, function (err, code, stdout, stderr) { + t.ifErr(err, 'ls succeeded') + t.equal(0, code, 'exit 0 on ls') + var pkg = JSON.parse(stdout) + var deps = pkg.dependencies + t.ok(deps.dep, 'dep present') + t.done() + }) + }) +}) + +test('cleanup', function (t) { + rimraf.sync(basepath) + t.done() +}) + +function withFixture (t, fixture, tester) { + fixture.create(fixturepath) + common.npm(['install'], { + cwd: path.join(fixturepath, 'npm-test-ls') + }, checkAndTest) + function checkAndTest (err, code) { + if (err) throw err + t.is(code, 0, 'install went ok') + tester(removeAndDone) + } + function removeAndDone (err) { + if (err) throw err + fixture.remove(fixturepath) + rimraf.sync(basepath) + t.done() + } +} diff --git a/deps/npm/test/tap/no-global-warns.js b/deps/npm/test/tap/no-global-warns.js index 2d831eaae9..cae62fff99 100644 --- a/deps/npm/test/tap/no-global-warns.js +++ b/deps/npm/test/tap/no-global-warns.js @@ -14,13 +14,7 @@ var toInstall = path.join(base, 'to-install') var config = 'prefix = ' + base var configPath = path.join(base, '_npmrc') -var extend = Object.assign || require('util')._extend - -var OPTS = { - env: extend({ - 'npm_config_userconfig': configPath - }, process.env) -} +var OPTS = { } var installJSON = { name: 'to-install', @@ -40,11 +34,18 @@ test('setup', function (t) { }) test('no-global-warns', function (t) { - common.npm(['install', '-g', toInstall], OPTS, function (err, code, stdout, stderr) { - t.ifError(err, 'installed w/o error') - t.is(stderr, '', 'no warnings printed to stderr') - t.end() - }) + common.npm( + [ + 'install', '-g', + '--userconfig=' + configPath, + toInstall + ], + OPTS, + function (err, code, stdout, stderr) { + t.ifError(err, 'installed w/o error') + t.is(stderr, '', 'no warnings printed to stderr') + t.end() + }) }) test('cleanup', function (t) { diff --git a/deps/npm/test/tap/optional-metadep-rollback-collision.js b/deps/npm/test/tap/optional-metadep-rollback-collision.js index d5116f30fc..a9294858d2 100644 --- a/deps/npm/test/tap/optional-metadep-rollback-collision.js +++ b/deps/npm/test/tap/optional-metadep-rollback-collision.js @@ -63,7 +63,7 @@ var opdep_json = { } } -var badServer = function () {/* +var badServer = function () { /* var createServer = require('http').createServer var spawn = require('child_process').spawn var fs = require('fs') @@ -98,9 +98,9 @@ if (process.argv[2]) { fs.writeFileSync(pidfile, child.pid + '\n') } -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') -var blart = function () {/* +var blart = function () { /* var rando = require('crypto').randomBytes var resolve = require('path').resolve @@ -152,7 +152,7 @@ mkdirp(BASEDIR, function go () { keepItGoingLouder = {} }, 3 * 1000) }) -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') test('setup', function (t) { cleanup() diff --git a/deps/npm/test/tap/outdated-depth-deep.js b/deps/npm/test/tap/outdated-depth-deep.js index 27c5f3e9fc..682b1ca958 100644 --- a/deps/npm/test/tap/outdated-depth-deep.js +++ b/deps/npm/test/tap/outdated-depth-deep.js @@ -2,7 +2,6 @@ var common = require('../common-tap') var path = require('path') var test = require('tap').test var rimraf = require('rimraf') -var npm = require('../../') var mr = require('npm-registry-mock') var pkg = path.resolve(__dirname, 'outdated-depth-deep') var cache = path.resolve(pkg, 'cache') @@ -41,38 +40,50 @@ test('setup', function (t) { }) test('outdated depth deep (9999)', function (t) { - var underscoreOutdated = ['underscore', '1.3.1', '1.3.1', '1.5.1', '1.3.1'] - var childPkg = path.resolve(pkg, 'node_modules', 'npm-test-peer-deps') + var conf = [ + '--registry', common.registry, + '--cache', cache + ] - var expected = [ [childPkg].concat(underscoreOutdated).concat([null]), - [pkg].concat(underscoreOutdated).concat([null]) ] + var server + mr({ port: common.port }, thenTopLevelInstall) - process.chdir(pkg) + function thenTopLevelInstall (err, s) { + if (err) throw err + server = s + common.npm(conf.concat(['install', '.']), {cwd: pkg}, thenDeepInstall) + } + + function thenDeepInstall (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'install completed successfully') + t.is('', stderr, 'no error output') + var depPath = path.join(pkg, 'node_modules', 'npm-test-peer-deps') + common.npm(conf.concat(['install', 'underscore']), {cwd: depPath}, thenRunOutdated) + } + + function thenRunOutdated (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'deep install completed successfully') + t.is('', stderr, 'no error output') + common.npm(conf.concat(['outdated', '--depth', 9999]), {cwd: pkg}, thenValidateOutput) + } - mr({ port: common.port }, function (er, s) { - npm.load({ - cache: cache, - loglevel: 'silent', - registry: common.registry, - depth: 9999 - }, - function () { - npm.install('.', function (er) { - if (er) throw new Error(er) - var nodepath = process.env.npm_node_execpath || process.env.NODE || process.execPath - var clibin = path.resolve(__dirname, '../../bin/npm-cli.js') - npm.explore('npm-test-peer-deps', nodepath, clibin, 'install', 'underscore', function (er) { - if (er) throw new Error(er) - npm.outdated(function (err, d) { - if (err) throw new Error(err) - t.deepEqual(d, expected) - s.close() - t.end() - }) - }) - }) - }) - }) + function thenValidateOutput (err, code, stdout, stderr) { + if (err) throw err + t.is(code, 0, 'outdated completed successfully') + t.is('', stderr, 'no error output') + t.match( + stdout, + /underscore.*1\.3\.1.*1\.3\.1.*1\.5\.1.*whatever\n/g, + 'child package listed') + t.match( + stdout, + /underscore.*1\.3\.1.*1\.3\.1.*1\.5\.1.*whatever > npm-test-peer-deps/g, + 'child package listed') + server.close() + t.end() + } }) test('cleanup', function (t) { diff --git a/deps/npm/test/tap/outdated-depth-integer.js b/deps/npm/test/tap/outdated-depth-integer.js index a1fc2b99d2..32bf785f27 100644 --- a/deps/npm/test/tap/outdated-depth-integer.js +++ b/deps/npm/test/tap/outdated-depth-integer.js @@ -3,7 +3,8 @@ var test = require('tap').test var rimraf = require('rimraf') var npm = require('../../') var mr = require('npm-registry-mock') -var pkg = __dirname + '/outdated-depth-integer' +var path = require('path') +var pkg = path.resolve('outdated-depth-integer') var osenv = require('osenv') var mkdirp = require('mkdirp') diff --git a/deps/npm/test/tap/outdated.js b/deps/npm/test/tap/outdated.js index c5ce8d182f..3a46705e38 100644 --- a/deps/npm/test/tap/outdated.js +++ b/deps/npm/test/tap/outdated.js @@ -104,7 +104,7 @@ test('it should not throw', function (t) { } npm.outdated(function (er, d) { t.ifError(er, 'outdated success') - + output = output.map(function (x) { return x.replace(/\r/g, '') }) console.log = originalLog t.same(output, expOut) diff --git a/deps/npm/test/tap/publish-access-unscoped-restricted-fails.js b/deps/npm/test/tap/publish-access-unscoped-restricted-fails.js index 4c7fce7351..660d0f48d7 100644 --- a/deps/npm/test/tap/publish-access-unscoped-restricted-fails.js +++ b/deps/npm/test/tap/publish-access-unscoped-restricted-fails.js @@ -4,59 +4,35 @@ var path = require('path') var test = require('tap').test var mkdirp = require('mkdirp') var rimraf = require('rimraf') - -var npm = require('../../') var common = require('../common-tap.js') var pkg = path.join(__dirname, 'publish-access-unscoped') test('setup', function (t) { - mkdirp(path.join(pkg, 'cache'), function () { - var configuration = { - cache: path.join(pkg, 'cache'), - loglevel: 'silent', - registry: common.registry - } - - npm.load(configuration, next) - }) - - function next (er) { - t.ifError(er, 'npm loaded successfully') - - process.chdir(pkg) - fs.writeFile( - path.join(pkg, 'package.json'), - JSON.stringify({ - name: 'publish-access', - version: '1.2.5' - }), - 'ascii', - function (er) { - t.ifError(er) - - t.pass('setup done') - t.end() - } - ) - } + mkdirp.sync(pkg) + fs.writeFileSync( + path.join(pkg, 'package.json'), + JSON.stringify({ + name: 'publish-access', + version: '1.2.5' + })) + t.pass('setup done') + t.end() }) test('unscoped packages cannot be restricted', function (t) { - npm.config.set('access', 'restricted') - npm.commands.publish([], false, function (er) { - t.ok(er, 'got an error back') - t.equal(er.message, "Can't restrict access to unscoped packages.") + var args = ['--access=restricted', '--loglevel=warn', '--registry=' + common.registry] + var opts = {stdio: [0, 1, 'pipe'], cwd: pkg} + common.npm(['publish'].concat(args), opts, function (err, code, stdout, stderr) { + if (err) throw err + t.notEqual(code, 0, 'publish not successful') + t.match(stderr, "Can't restrict access to unscoped packages.") t.end() }) }) test('cleanup', function (t) { - process.chdir(__dirname) - rimraf(pkg, function (er) { - t.ifError(er) - - t.end() - }) + rimraf.sync(pkg) + t.end() }) diff --git a/deps/npm/test/tap/publish-config.js b/deps/npm/test/tap/publish-config.js index 57070f78ba..399fd0f93b 100644 --- a/deps/npm/test/tap/publish-config.js +++ b/deps/npm/test/tap/publish-config.js @@ -29,7 +29,7 @@ test(function (t) { res.end(JSON.stringify({ error: 'sshhh. naptime nao. \\^O^/ <(YAWWWWN!)' })) - child.kill('SIGHUP') + child.kill('SIGINT') }).listen(common.port, function () { t.pass('server is listening') diff --git a/deps/npm/test/tap/registry.js b/deps/npm/test/tap/registry.js index 7b17192f66..d8ec4a204e 100644 --- a/deps/npm/test/tap/registry.js +++ b/deps/npm/test/tap/registry.js @@ -31,6 +31,8 @@ var extend = Object.assign || require('util')._extend function runTests () { var env = extend({ TAP: 1 }, process.env) env.npm = npmExec + // TODO: fix tap and / or nyc to handle nested invocations properly + env.COVERALLS_REPO_TOKEN = '' var opts = { cwd: ca, @@ -49,7 +51,7 @@ function runTests () { env: env, stdio: 'inherit' } - common.npm(['test', '--', '-Rtap'], opts, function (err, code) { + common.npm(['test', '--', '-Rtap', '--no-coverage'], opts, function (err, code) { if (err) { throw err } if (code) { return test('need test to work', function (t) { diff --git a/deps/npm/test/tap/repo.js b/deps/npm/test/tap/repo.js index 292415705e..e2751573d0 100644 --- a/deps/npm/test/tap/repo.js +++ b/deps/npm/test/tap/repo.js @@ -1,8 +1,3 @@ -if (process.platform === 'win32') { - console.error('skipping test, because windows and shebangs') - process.exit(0) -} - var common = require('../common-tap.js') var mr = require('npm-registry-mock') @@ -10,15 +5,18 @@ var test = require('tap').test var rimraf = require('rimraf') var fs = require('fs') var path = require('path') +var fakeBrowser = path.join(__dirname, '_script.sh') var outFile = path.join(__dirname, '/_output') var opts = { cwd: __dirname } +common.pendIfWindows('This is trickier to convert without opening new shells') + test('setup', function (t) { var s = '#!/usr/bin/env bash\n' + 'echo \"$@\" > ' + JSON.stringify(__dirname) + '/_output\n' - fs.writeFileSync(__dirname + '/_script.sh', s, 'ascii') - fs.chmodSync(__dirname + '/_script.sh', '0755') + fs.writeFileSync(fakeBrowser, s, 'ascii') + fs.chmodSync(fakeBrowser, '0755') t.pass('made script') t.end() }) @@ -29,7 +27,7 @@ test('npm repo underscore', function (t) { 'repo', 'underscore', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 0, 'exit ok') @@ -48,7 +46,7 @@ test('npm repo optimist - github (https://)', function (t) { 'repo', 'optimist', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 0, 'exit ok') @@ -67,7 +65,7 @@ test('npm repo npm-test-peer-deps - no repo', function (t) { 'repo', 'npm-test-peer-deps', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 1, 'exit not ok') @@ -83,7 +81,7 @@ test('npm repo test-repo-url-http - non-github (http://)', function (t) { 'repo', 'test-repo-url-http', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 0, 'exit ok') @@ -102,7 +100,7 @@ test('npm repo test-repo-url-https - non-github (https://)', function (t) { 'repo', 'test-repo-url-https', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 0, 'exit ok') @@ -121,7 +119,7 @@ test('npm repo test-repo-url-ssh - non-github (ssh://)', function (t) { 'repo', 'test-repo-url-ssh', '--registry=' + common.registry, '--loglevel=silent', - '--browser=' + __dirname + '/_script.sh' + '--browser=' + fakeBrowser ], opts, function (err, code, stdout, stderr) { t.ifError(err, 'repo command ran without error') t.equal(code, 0, 'exit ok') @@ -135,7 +133,7 @@ test('npm repo test-repo-url-ssh - non-github (ssh://)', function (t) { }) test('cleanup', function (t) { - fs.unlinkSync(__dirname + '/_script.sh') + fs.unlinkSync(fakeBrowser) t.pass('cleaned up') t.end() }) diff --git a/deps/npm/test/tap/retry-on-stale-cache.js b/deps/npm/test/tap/retry-on-stale-cache.js new file mode 100644 index 0000000000..3a7f5c206c --- /dev/null +++ b/deps/npm/test/tap/retry-on-stale-cache.js @@ -0,0 +1,195 @@ +var path = require('path') + +var mr = require('npm-registry-mock') +var test = require('tap').test +var common = require('../common-tap') +var extend = Object.assign || require('util')._extend +var Tacks = require('tacks') +var Dir = Tacks.Dir +var File = Tacks.File + +var workdir = path.join(__dirname, path.basename(__filename, '.js')) +var cachedir = path.join(workdir, 'cache') +var modulesdir = path.join(workdir, 'modules') +var oldModule = path.join(modulesdir, 'good-night-0.1.0.tgz') +var newModule = path.join(modulesdir, 'good-night-1.0.0.tgz') + +var config = [ + '--cache', cachedir, + '--prefix', workdir, + '--registry', common.registry +] + +var fixture = new Tacks(Dir({ + 'cache': Dir(), + 'modules': Dir({ + 'good-night-0.1.0.tgz': File(new Buffer( + '1f8b0800000000000003ed934f4bc43010c57beea7187a59056dd36eff80' + + 'de85050541c1f3d8c634da4e4a925a8af8dd6db7bb8ba0e0c15559e9eff2' + + '206f929909bc06f327143c6826f51f8d2267cf30c6d2388641c32c61ef75' + + '4d9426e084519a25491645cbcc61e192c5d1e0ef7b90cf688d453d8cf2dd' + + '77a65d60a707c28b0b031e61cdbd33f08452c52949515aef64729eb93652' + + 'd168323ff4d9f6bce026d7b2b11bafef11b1eb3a221a2aa6126c6da9f4e8' + + '5e691f6e908a1a697b5ff346196995eec7023399c1c7fe95cc3999f57077' + + 'b717d7979efbeafef5a7fd2336b90f6a943484ff477a7c917f96c5bbfc87' + + '493ae63f627138e7ff37c815195571bf52e268b1820e0d0825498055d069' + + '6939d8521ab86f2dace0815715a0a9386f16c7e7730c676666660e9837c0' + + 'f6795d000c0000', + 'hex' + )), + 'good-night-1.0.0.tgz': File(new Buffer( + '1f8b0800000000000003ed954d6bc24010863dfb2bb6b9a8503793b849a0' + + 'eda5979efa052d484184252e495a331b76d78a94fef76e8cf683163cd42a' + + '957d2e03796777268187543c7de299f0aba6d2472db1b5650020668cd81a' + + '24117cae4bc23822ad208c93284a1208c216040318c436dff6223f31d386' + + '2bbbca6fef69de85bcd77fc24b9b583ce4a5f04e88974939e96391e5c63b' + + '6e9267a17421b10e030a14d6cf2742a7aaa8cc2a5b2c38e7f3f91c116d47' + + 'd3c2672697aa4eaf1425771c2725c7f579252aa90b23d5a26ed04de87f9f' + + '3f2d52817ab9dcf0fee2f6d26bbfb6f7fdd10e8895f77ec90bb4f2ffc98c' + + '0dfe439c7cf81fc4b5ff213070feef8254a2965341a732eb76b4cef39c12' + + 'e456eb52d82a29198dc637639f9c751fce8796eba35ea777ea0c3c14d6fe' + + '532314f62ba9ccf6676cf21fbefcff59ed3f4b22e7ff2e60110bc37d2fe1' + + '70381c8e9df306642df14500100000', + 'hex' + )) + }) +})) + +var server + +// In this test we mock a situation where the user has a package in his cache, +// a newer version of the package is published, and the user tried to install +// said new version while requestion that the cache be used. +// npm should see that it doesn't have the package in its cache and hit the +// registry. +var onlyOldMetadata = { + 'name': 'good-night', + 'dist-tags': { + 'latest': '0.1.0' + }, + 'versions': { + '0.1.0': { + 'name': 'good-night', + 'version': '0.1.0', + 'dist': { + 'shasum': '2a746d49dd074ba0ec2d6ff13babd40c658d89eb', + 'tarball': 'http://localhost:' + common.port + '/good-night/-/good-night-0.1.0.tgz' + } + } + } +} + +var oldAndNewMetadata = extend({}, onlyOldMetadata) +oldAndNewMetadata['dist-tags'] = { latest: '1.0.0' } +oldAndNewMetadata.versions = extend({ + '1.0.0': { + 'name': 'good-night', + 'version': '1.0.0', + 'dist': { + 'shasum': 'f377bf002a0a8fc4085d347a160a790b76896bc3', + 'tarball': 'http://localhost:' + common.port + '/good-night/-/good-night-1.0.0.tgz' + } + } +}, oldAndNewMetadata.versions) + +function setup () { + cleanup() + fixture.create(workdir) +} + +function cleanup () { + fixture.remove(workdir) +} + +test('setup', function (t) { + setup() + t.end() +}) + +test('setup initial server', function (t) { + mr({ + port: common.port, + throwOnUnmatched: true + }, function (err, s) { + t.ifError(err, 'registry mocked successfully') + server = s + + server.get('/good-night') + .many({ min: 1, max: 1 }) + .reply(200, onlyOldMetadata) + server.get('/good-night/-/good-night-0.1.0.tgz') + .many({ min: 1, max: 1 }) + .replyWithFile(200, oldModule) + + t.end() + }) +}) + +test('install initial version', function (t) { + common.npm(config.concat([ + 'install', 'good-night' + ]), {stdio: 'inherit'}, function (err, code) { + if (err) throw err + t.is(code, 0, 'initial install succeeded') + server.done() + t.end() + }) +}) + +test('cleanup initial server', function (t) { + server.close() + t.end() +}) + +test('setup new server', function (t) { + mr({ + port: common.port, + throwOnUnmatched: true + }, function (err, s) { + t.ifError(err, 'registry mocked successfully') + server = s + + server.get('/good-night') + .many({ min: 1, max: 1 }) + .reply(200, oldAndNewMetadata) + + server.get('/good-night/-/good-night-1.0.0.tgz') + .many({ min: 1, max: 1 }) + .replyWithFile(200, newModule) + + t.end() + }) +}) + +test('install new version', function (t) { + common.npm(config.concat([ + '--cache-min', 'Infinity', + 'install', 'good-night@1.0.0' + ]), {stdio: 'inherit'}, function (err, code) { + if (err) throw err + t.is(code, 0, 'install succeeded') + + t.end() + }) +}) + +test('install does not hit server again', function (t) { + // The mock server route definitions ensure we don't hit the server again + common.npm(config.concat([ + '--cache-min', 'Infinity', + 'install', 'good-night' + ]), {stdio: [0, 'pipe', 2]}, function (err, code, stdout) { + if (err) throw err + t.is(code, 0, 'install succeeded') + + t.match(stdout, /@1\.0\.0/, 'installed latest version') + server.done() + t.end() + }) +}) + +test('cleanup', function (t) { + server.close() + cleanup() + t.end() +}) diff --git a/deps/npm/test/tap/scripts-whitespace-windows.js b/deps/npm/test/tap/scripts-whitespace-windows.js index bff0e534ef..27a04601c7 100644 --- a/deps/npm/test/tap/scripts-whitespace-windows.js +++ b/deps/npm/test/tap/scripts-whitespace-windows.js @@ -37,12 +37,12 @@ var dependency = { var extend = Object.assign || require('util')._extend -var foo = function () {/* +var foo = function () { /* #!/usr/bin/env node if (process.argv.length === 8) console.log('npm-test-fine') -*/}.toString().split('\n').slice(1, -1).join('\n') +*/ }.toString().split('\n').slice(1, -1).join('\n') test('setup', function (t) { cleanup() diff --git a/deps/npm/test/tap/shrinkwrap-nested.js b/deps/npm/test/tap/shrinkwrap-nested.js new file mode 100644 index 0000000000..92c81f29e3 --- /dev/null +++ b/deps/npm/test/tap/shrinkwrap-nested.js @@ -0,0 +1,153 @@ +'use strict' +var test = require('tap').test +var Tacks = require('tacks') +var File = Tacks.File +var Dir = Tacks.Dir +var fs = require('fs') +var path = require('path') +var common = require('../common-tap.js') + +var testdir = path.resolve(__dirname, path.basename(__filename, '.js')) +var modAdir = path.resolve(testdir, 'modA') +var modB1dir = path.resolve(testdir, 'modB@1') +var modB2dir = path.resolve(testdir, 'modB@2') +var modCdir = path.resolve(testdir, 'modC') + +var fixture = new Tacks(Dir({ + 'package.json': File({ + dependencies: { + modA: 'file://' + modAdir, + modC: 'file://' + modCdir + } + }), + 'npm-shrinkwrap.json': File({ + dependencies: { + modA: { + version: '1.0.0', + from: 'modA', + resolved: 'file://' + modAdir + }, + modB: { + version: '1.0.0', + from: 'modB@1', + resolved: 'file://' + modB1dir + } + } + }), + 'modA': Dir({ + 'package.json': File({ + name: 'modA', + version: '1.0.0', + dependencies: { + 'modB': 'file://' + modB1dir + } + }) + }), + 'modB@1': Dir({ + 'package.json': File({ + name: 'modB', + version: '1.0.0' + }), + 'B1': File('') + }), + 'modB@2': Dir({ + 'package.json': File({ + name: 'modB', + version: '2.0.0' + }), + 'B2': File('') + }), + 'modC': Dir({ + 'package.json': File({ + name: 'modC', + version: '1.0.0', + dependencies: { + 'modB': 'file://' + modB2dir + } + }) + }) +})) + +var newShrinkwrap = new Tacks(Dir({ + 'npm-shrinkwrap.json': File({ + dependencies: { + modA: { + version: '1.0.0', + from: 'modA', + resolved: 'file://' + modAdir + }, + modB: { + version: '1.0.0', + from: 'modB@1', + resolved: 'file://' + modB1dir + }, + modC: { + version: '1.0.0', + from: 'modC', + resolved: 'file://' + modCdir, + dependencies: { + modB: { + version: '1.0.0', + from: 'modB@1', + resolved: 'file://' + modB1dir + } + } + } + } + }), + 'node_modules': Dir({ + 'modB@1': Dir({ + 'package.json': File({ + _requested: { + name: 'modB', + raw: 'modB@file:' + modB1dir, + rawSpec: 'file:' + modB1dir, + scope: null, + spec: modB1dir, + type: 'directory' + }, + dependencies: { }, + devDependencies: { }, + name: 'modB', + optionalDependencies: { }, + readme: 'ERROR: No README data found!', + version: '1.0.0' + }) + }) + }) +})) + +function setup () { + fixture.create(testdir) +} + +function cleanup () { + fixture.remove(testdir) +} + +test('setup', function (t) { + cleanup() + setup() + common.npm(['install'], {cwd: testdir, stdio: [0, 2, 2]}, function (err, code) { + if (err) throw err + t.is(code, 0) + t.end() + }) +}) + +test('incremental install', function (t) { + newShrinkwrap.create(testdir) + common.npm(['install'], {cwd: testdir, stdio: [0, 2, 2]}, function (err, code) { + if (err) throw err + t.is(code, 0, 'npm itself completed ok') + fs.stat(path.join(testdir, 'node_modules', 'modC', 'node_modules', 'modB', 'B1'), function (missing) { + t.ok(!missing, 'modC got the updated version of modB') + t.end() + }) + }) +}) + +test('cleanup', function (t) { + cleanup() + t.end() +}) diff --git a/deps/npm/test/tap/shrinkwrap-version-match.js b/deps/npm/test/tap/shrinkwrap-version-match.js index cb4e925504..7d9fed729a 100644 --- a/deps/npm/test/tap/shrinkwrap-version-match.js +++ b/deps/npm/test/tap/shrinkwrap-version-match.js @@ -1,8 +1,9 @@ 'use strict' var test = require('tap').test +var Tacks = require('tacks') +var File = Tacks.File +var Dir = Tacks.Dir var fs = require('fs') -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') var path = require('path') var common = require('../common-tap.js') @@ -11,77 +12,68 @@ var modAdir = path.resolve(testdir, 'modA') var modB1dir = path.resolve(testdir, 'modB@1') var modB2dir = path.resolve(testdir, 'modB@2') var modCdir = path.resolve(testdir, 'modC') -var testjson = { - dependencies: { - modA: 'file://' + modAdir, - modC: 'file://' + modCdir - } -} -var testshrinkwrap = { - dependencies: { - modA: { + +var fixture = new Tacks(Dir({ + 'package.json': File({ + dependencies: { + modA: 'file://' + modAdir, + modC: 'file://' + modCdir + } + }), + 'npm-shrinkwrap.json': File({ + dependencies: { + modA: { + version: '1.0.0', + from: 'modA', + resolved: 'file://' + modAdir + }, + modB: { + version: '1.0.0', + from: 'modB@1', + resolved: 'file://' + modB1dir + } + } + }), + 'modA': Dir({ + 'package.json': File({ + name: 'modA', version: '1.0.0', - from: 'modA', - resolved: 'file://' + modAdir - }, - modB: { + dependencies: { + 'modB': 'file://' + modB1dir + } + }) + }), + 'modB@1': Dir({ + 'package.json': File({ + name: 'modB', + version: '1.0.0' + }), + 'B1': File('') + }), + 'modB@2': Dir({ + 'package.json': File({ + name: 'modB', + version: '2.0.0' + }), + 'B2': File('') + }), + 'modC': Dir({ + 'package.json': File({ + name: 'modC', version: '1.0.0', - from: 'modB@1', - resolved: 'file://' + modB1dir - } - } -} -var modAjson = { - name: 'modA', - version: '1.0.0', - dependencies: { - 'modB': 'file://' + modB1dir - } -} -var modCjson = { - name: 'modC', - version: '1.0.0', - dependencies: { - 'modB': 'file://' + modB2dir - } -} -var modB1json = { - name: 'modB', - version: '1.0.0' -} -var modB2json = { - name: 'modB', - version: '2.0.0' -} - -function writepjson (dir, content) { - writejson(dir, 'package.json', content) -} -function writejson (dir, file, content) { - writefile(dir, file, JSON.stringify(content, null, 2)) -} -function writefile (dir, file, content) { - fs.writeFileSync(path.join(dir, file), content) -} + dependencies: { + 'modB': 'file://' + modB2dir + } + }) + }) +})) function setup () { - mkdirp.sync(testdir) - writepjson(testdir, testjson) - writejson(testdir, 'npm-shrinkwrap.json', testshrinkwrap) - mkdirp.sync(modAdir) - writepjson(modAdir, modAjson) - mkdirp.sync(modB1dir) - writepjson(modB1dir, modB1json) - writefile(modB1dir, 'B1', '') - mkdirp.sync(modB2dir) - writepjson(modB2dir, modB2json) - writefile(modB2dir, 'B2', '') - mkdirp.sync(modCdir) - writepjson(modCdir, modCjson) + fixture.create(testdir) } function cleanup () { - rimraf.sync(testdir) + fixture.remove(testdir) } test('setup', function (t) { diff --git a/deps/npm/test/tap/sorted-package-json.js b/deps/npm/test/tap/sorted-package-json.js index 427212ff56..557f3dc53d 100644 --- a/deps/npm/test/tap/sorted-package-json.js +++ b/deps/npm/test/tap/sorted-package-json.js @@ -2,9 +2,6 @@ var test = require('tap').test var path = require('path') var rimraf = require('rimraf') var mkdirp = require('mkdirp') -var spawn = require('child_process').spawn -var npm = require.resolve('../../bin/npm-cli.js') -var node = process.execPath var pkg = path.resolve(__dirname, 'sorted-package-json') var tmp = path.join(pkg, 'tmp') var cache = path.join(pkg, 'cache') @@ -12,36 +9,31 @@ var fs = require('fs') var common = require('../common-tap.js') var mr = require('npm-registry-mock') var osenv = require('osenv') +var packageJson = path.resolve(pkg, 'package.json') -test('sorting dependencies', function (t) { - var packageJson = path.resolve(pkg, 'package.json') - - cleanup() - mkdirp.sync(cache) - mkdirp.sync(tmp) +test('setup', function (t) { setup() + t.pass('setup success') + t.done() +}) +test('sorting dependencies', function (t) { var before = JSON.parse(fs.readFileSync(packageJson).toString()) mr({ port: common.port }, function (er, s) { // underscore is already in the package.json, // but --save will trigger a rewrite with sort - var child = spawn(node, [npm, 'install', '--save', 'underscore@1.3.3', '--no-progress', '--loglevel=error'], { - cwd: pkg, - env: { - 'npm_config_registry': common.registry, - 'npm_config_cache': cache, - 'npm_config_tmp': tmp, - 'npm_config_prefix': pkg, - 'npm_config_global': 'false', - HOME: process.env.HOME, - Path: process.env.PATH, - PATH: process.env.PATH - }, - stdio: ['ignore', 'ignore', process.stderr] - }) - - child.on('close', function (code) { + common.npm([ + 'install', + '--save', 'underscore@1.3.3', + '--no-progress', + '--cache', cache, + '--tmp', tmp, + '--registry', common.registry + ], { + cwd: pkg + }, function (err, code, stdout, stderr) { + t.ifError(err, 'no error') t.equal(code, 0, 'npm install exited with code') var result = fs.readFileSync(packageJson).toString() var resultAsJson = JSON.parse(result) @@ -68,9 +60,10 @@ test('cleanup', function (t) { }) function setup () { + cleanup() mkdirp.sync(pkg) - fs.writeFileSync(path.resolve(pkg, 'package.json'), JSON.stringify({ + fs.writeFileSync(packageJson, JSON.stringify({ 'name': 'sorted-package-json', 'version': '0.0.0', 'description': '', @@ -91,4 +84,6 @@ function cleanup () { process.chdir(osenv.tmpdir()) rimraf.sync(cache) rimraf.sync(pkg) + mkdirp.sync(cache) + mkdirp.sync(tmp) } diff --git a/deps/npm/test/tap/spawn-enoent-help.js b/deps/npm/test/tap/spawn-enoent-help.js index 716f6ebd15..d4a6fcdd83 100644 --- a/deps/npm/test/tap/spawn-enoent-help.js +++ b/deps/npm/test/tap/spawn-enoent-help.js @@ -6,6 +6,8 @@ var common = require('../common-tap.js') var pkg = path.resolve(__dirname, 'spawn-enoent-help') +common.pendIfWindows('man pages are not built on Windows') + test('setup', function (t) { rimraf.sync(pkg) mkdirp.sync(pkg) diff --git a/deps/npm/test/tap/symlink-cycle.js b/deps/npm/test/tap/symlink-cycle.js index b09b25acc8..62aa8e0674 100644 --- a/deps/npm/test/tap/symlink-cycle.js +++ b/deps/npm/test/tap/symlink-cycle.js @@ -57,5 +57,5 @@ function setup () { path.join(cycle, 'package.json'), JSON.stringify(cycleJSON, null, 2) ) - fs.symlinkSync(cycle, path.join(cycle, 'node_modules', 'cycle')) + fs.symlinkSync(cycle, path.join(cycle, 'node_modules', 'cycle'), 'junction') } diff --git a/deps/npm/test/tap/umask-lifecycle.js b/deps/npm/test/tap/umask-lifecycle.js index aa07084f15..c4c3233637 100644 --- a/deps/npm/test/tap/umask-lifecycle.js +++ b/deps/npm/test/tap/umask-lifecycle.js @@ -6,24 +6,30 @@ var rimraf = require('rimraf') var test = require('tap').test var sprintf = require('sprintf-js').sprintf +var escapeExecPath = require('../../lib/utils/escape-exec-path.js') +var escapeArg = require('../../lib/utils/escape-arg.js') var common = require('../common-tap.js') var pkg = path.resolve(__dirname, 'umask-lifecycle') +var nodeCmd = escapeExecPath(common.nodeBin) +var npmCmd = nodeCmd + ' ' + escapeArg(common.bin) +var umaskScript = npmCmd + ' config get umask && ' + nodeCmd + ' -pe "[process.env.npm_config_umask, process.umask()]"' + var pj = JSON.stringify({ name: 'x', version: '1.2.3', - scripts: { umask: '$npm_execpath config get umask && echo "$npm_config_umask" && node -pe "process.umask()"' } + scripts: { umask: umaskScript } }, null, 2) + '\n' var umask = process.umask() var expected = [ '', '> x@1.2.3 umask ' + path.join(__dirname, 'umask-lifecycle'), - '> $npm_execpath config get umask && echo "$npm_config_umask" && node -pe "process.umask()"', + '> ' + umaskScript, '', sprintf('%04o', umask), - sprintf('%04o', umask), - sprintf('%d', umask), + "[ '" + sprintf('%04o', umask) + "', " + + sprintf('%d', umask) + ' ]', '' ].join('\n') diff --git a/deps/npm/test/tap/unit-child-path.js b/deps/npm/test/tap/unit-child-path.js index 5e9b452a38..902e8f5ec7 100644 --- a/deps/npm/test/tap/unit-child-path.js +++ b/deps/npm/test/tap/unit-child-path.js @@ -1,9 +1,16 @@ 'use strict' var test = require('tap').test var childPath = require('../../lib/utils/child-path.js') +var path = require('path') test('childPath', function (t) { - t.is(childPath('/path/to', {name: 'abc'}), '/path/to/node_modules/abc', 'basic use') - t.is(childPath('/path/to', {package: {name: '@zed/abc'}}), '/path/to/node_modules/@zed/abc', 'scoped use') + t.is( + path.resolve(childPath('/path/to', {name: 'abc'})), + path.resolve('/path/to/node_modules/abc'), + 'basic use') + t.is( + path.resolve(childPath('/path/to', {package: {name: '@zed/abc'}})), + path.resolve('/path/to/node_modules/@zed/abc'), + 'scoped use') t.end() }) diff --git a/deps/npm/test/tap/unit-gentlyrm.js b/deps/npm/test/tap/unit-gentlyrm.js index 8e61be1964..8ea0a11fc2 100644 --- a/deps/npm/test/tap/unit-gentlyrm.js +++ b/deps/npm/test/tap/unit-gentlyrm.js @@ -1,6 +1,7 @@ 'use strict' var test = require('tap').test var requireInject = require('require-inject') +var path = require('path') function error (code) { var er = new Error() @@ -8,11 +9,54 @@ function error (code) { return er } +function platformPath (unixPath) { + if (unixPath[0] === '/') { + return path.resolve(unixPath) + } else { + return path.join.apply(path, unixPath.split('/')) + } +} + +function makeObjUsePlatformPaths (obj) { + if (typeof obj === 'string') { + return platformPath(obj) + } else if (obj == null || typeof obj !== 'object') { + return obj + } else { + Object.keys(obj).forEach(function (key) { + var newKey = platformPath(key) + obj[key] = makeObjUsePlatformPaths(obj[key]) + if (newKey !== key) { + obj[newKey] = obj[key] + delete obj[key] + } + }) + } + return obj +} + +function makeArgsUsePlatformPaths (fn) { + return function () { + var args = Array.prototype.slice.call(arguments) + return fn.apply(null, makeObjUsePlatformPaths(args)) + } +} + +function pathIs (t, arg1, arg2, msg) { + t.is(arg1, makeObjUsePlatformPaths(arg2), msg) +} + +function pathIsDeeply (t, arg1, arg2, msg) { + t.isDeeply(arg1, makeObjUsePlatformPaths(arg2), msg) +} + function mockWith (fixture) { + makeObjUsePlatformPaths(fixture) return { '../../lib/npm.js': {}, 'graceful-fs': { lstat: function (path, cb) { + path = platformPath(path) var entry = fixture[path] if (!entry) return cb(error('ENOENT')) cb(null, { @@ -22,6 +66,7 @@ function mockWith (fixture) { }) }, readlink: function (path, cb) { + path = platformPath(path) var entry = fixture[path] if (!entry) return cb(error('ENOENT')) if (entry.type !== 'symlink') return cb(error('EINVAL')) @@ -29,6 +74,7 @@ function mockWith (fixture) { } }, 'read-cmd-shim': function (path, cb) { + path = platformPath(path) var entry = fixture[path] if (!entry) return cb(error('ENOENT')) if (entry.type === 'directory') return cb(error('EISDIR')) @@ -51,7 +97,7 @@ test('readLinkOrShim', function (t) { }) var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mocks) - var readLinkOrShim = gentlyRm._readLinkOrShim + var readLinkOrShim = makeArgsUsePlatformPaths(gentlyRm._readLinkOrShim) readLinkOrShim('/path/to/nowhere', function (er, path) { t.is(er && er.code, 'ENOENT', 'missing files are errors') @@ -61,19 +107,19 @@ test('readLinkOrShim', function (t) { }) readLinkOrShim('/path/to/directory', function (er, path) { t.ifError(er, "reading dirs isn't an error") - t.is(path, null, 'reading non links/cmdshims gives us null') + pathIs(t, path, null, 'reading non links/cmdshims gives us null') }) readLinkOrShim('/path/to/file', function (er, path) { t.ifError(er, "reading non-cmdshim files isn't an error") - t.is(path, null, 'reading non links/cmdshims gives us null') + pathIs(t, path, null, 'reading non links/cmdshims gives us null') }) readLinkOrShim('/path/to/link', function (er, path) { t.ifError(er, "reading links isn't an error") - t.is(path, '../to/file', 'reading links works') + pathIs(t, path, '../to/file', 'reading links works') }) readLinkOrShim('/path/to/cmdshim', function (er, path) { t.ifError(er, "reading cmdshims isn't an error") - t.is(path, '../to/file', 'reading cmdshims works') + pathIs(t, path, '../to/file', 'reading cmdshims works') }) t.done() }) @@ -89,26 +135,30 @@ test('resolveSymlink', function (t) { }) var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mocks) - var resolveSymlink = gentlyRm._resolveSymlink + var resolveSymlink = makeArgsUsePlatformPaths(gentlyRm._resolveSymlink) resolveSymlink('/path/to/nowhere', function (er, path) { t.is(er && er.code, 'ENOENT', 'missing files are errors') }) + + // these aren't symlinks so we get back what we passed in resolveSymlink('/path/to/directory', function (er, path) { t.ifError(er, "reading dirs isn't an error") - t.is(path, '/path/to/directory', 'reading non links/cmdshims gives us path we passed in') + pathIs(t, path, '/path/to/directory', 'reading non links/cmdshims gives us path we passed in') }) resolveSymlink('/path/to/file', function (er, path) { t.ifError(er, "reading non-cmdshim files isn't an error") - t.is(path, '/path/to/file', 'reading non links/cmdshims gives us the path we passed in') + pathIs(t, path, '/path/to/file', 'reading non links/cmdshims gives us the path we passed in') }) + + // these are symlinks so the resolved version is platform specific resolveSymlink('/path/to/link', function (er, path) { t.ifError(er, "reading links isn't an error") - t.is(path, '/path/to/file', 'reading links works') + pathIs(t, path, '/path/to/file', 'reading links works') }) resolveSymlink('/path/to/cmdshim', function (er, path) { t.ifError(er, "reading cmdshims isn't an error") - t.is(path, '/path/to/file', 'reading cmdshims works') + pathIs(t, path, '/path/to/file', 'reading cmdshims works') }) t.done() }) @@ -128,48 +178,48 @@ test('readAllLinks', function (t) { }) var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mocks) - var readAllLinks = gentlyRm._readAllLinks + var readAllLinks = makeArgsUsePlatformPaths(gentlyRm._readAllLinks) readAllLinks('/path/to/nowhere', function (er, path) { t.is(er && er.code, 'ENOENT', 'missing files are errors') }) readAllLinks('/path/to/directory', function (er, path) { t.ifError(er, "reading dirs isn't an error") - t.isDeeply(path, ['/path/to/directory'], 'reading non links/cmdshims gives us path we passed in') + pathIsDeeply(t, path, ['/path/to/directory'], 'reading non links/cmdshims gives us path we passed in') }) readAllLinks('/path/to/file', function (er, path) { t.ifError(er, "reading non-cmdshim files isn't an error") - t.isDeeply(path, ['/path/to/file'], 'reading non links/cmdshims gives us the path we passed in') + pathIsDeeply(t, path, ['/path/to/file'], 'reading non links/cmdshims gives us the path we passed in') }) readAllLinks('/path/to/linktobad', function (er, path) { t.is(er && er.code, 'ENOENT', 'links to missing files are errors') }) - readAllLinks('/path/to/link', function (er, path) { + readAllLinks('/path/to/link', function (er, results) { t.ifError(er, "reading links isn't an error") - t.isDeeply(path, ['/path/to/link', '/path/to/file'], 'reading links works') + pathIsDeeply(t, results, ['/path/to/link', '/path/to/file'], 'reading links works') }) readAllLinks('/path/to/cmdshim', function (er, path) { t.ifError(er, "reading cmdshims isn't an error") - t.isDeeply(path, ['/path/to/cmdshim', '/path/to/file'], 'reading cmdshims works') + pathIsDeeply(t, path, ['/path/to/cmdshim', '/path/to/file'], 'reading cmdshims works') }) readAllLinks('/path/to/linktolink', function (er, path) { t.ifError(er, "reading link to link isn't an error") - t.isDeeply(path, ['/path/to/linktolink', '/path/to/link', '/path/to/file'], 'reading link to link works') + pathIsDeeply(t, path, ['/path/to/linktolink', '/path/to/link', '/path/to/file'], 'reading link to link works') }) readAllLinks('/path/to/linktolink^2', function (er, path) { t.ifError(er, "reading link to link to link isn't an error") - t.isDeeply(path, ['/path/to/linktolink^2', '/path/to/linktolink', '/path/to/link', '/path/to/file'], 'reading link to link to link works') + pathIsDeeply(t, path, ['/path/to/linktolink^2', '/path/to/linktolink', '/path/to/link', '/path/to/file'], 'reading link to link to link works') }) readAllLinks('/path/to/linktocmdshim', function (er, path) { t.ifError(er, "reading link to cmdshim isn't an error") - t.isDeeply(path, ['/path/to/linktocmdshim', '/path/to/cmdshim', '/path/to/file'], 'reading link to cmdshim works') + pathIsDeeply(t, path, ['/path/to/linktocmdshim', '/path/to/cmdshim', '/path/to/file'], 'reading link to cmdshim works') }) t.done() }) test('areAnyInsideAny', function (t) { var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mockWith({})) - var areAnyInsideAny = gentlyRm._areAnyInsideAny + var areAnyInsideAny = makeArgsUsePlatformPaths(gentlyRm._areAnyInsideAny) var noneOneToOne = areAnyInsideAny(['/abc'], ['/xyz']) t.is(noneOneToOne, false, 'none inside: one to one') @@ -181,42 +231,42 @@ test('areAnyInsideAny', function (t) { t.is(noneManyToMany, false, 'none inside: many to many') var oneToOne = areAnyInsideAny(['/one/toOne'], ['/one']) - t.isDeeply(oneToOne, {target: '/one/toOne', path: '/one'}, 'first: one to one') + pathIsDeeply(t, oneToOne, {target: '/one/toOne', path: '/one'}, 'first: one to one') var firstOneToMany = areAnyInsideAny(['/abc/def'], ['/abc', '/def', '/ghi']) - t.isDeeply(firstOneToMany, {target: '/abc/def', path: '/abc'}, 'first: one to many') + pathIsDeeply(t, firstOneToMany, {target: '/abc/def', path: '/abc'}, 'first: one to many') var secondOneToMany = areAnyInsideAny(['/def/ghi'], ['/abc', '/def', '/ghi']) - t.isDeeply(secondOneToMany, {target: '/def/ghi', path: '/def'}, 'second: one to many') + pathIsDeeply(t, secondOneToMany, {target: '/def/ghi', path: '/def'}, 'second: one to many') var lastOneToMany = areAnyInsideAny(['/ghi/jkl'], ['/abc', '/def', '/ghi']) - t.isDeeply(lastOneToMany, {target: '/ghi/jkl', path: '/ghi'}, 'last: one to many') + pathIsDeeply(t, lastOneToMany, {target: '/ghi/jkl', path: '/ghi'}, 'last: one to many') var firstManyToOne = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/abc']) - t.isDeeply(firstManyToOne, {target: '/abc/def', path: '/abc'}, 'first: many to one') + pathIsDeeply(t, firstManyToOne, {target: '/abc/def', path: '/abc'}, 'first: many to one') var secondManyToOne = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/uvw']) - t.isDeeply(secondManyToOne, {target: '/uvw/def', path: '/uvw'}, 'second: many to one') + pathIsDeeply(t, secondManyToOne, {target: '/uvw/def', path: '/uvw'}, 'second: many to one') var lastManyToOne = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/xyz']) - t.isDeeply(lastManyToOne, {target: '/xyz/def', path: '/xyz'}, 'last: many to one') + pathIsDeeply(t, lastManyToOne, {target: '/xyz/def', path: '/xyz'}, 'last: many to one') var firstToFirst = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/abc', '/uvw', '/xyz']) - t.isDeeply(firstToFirst, {target: '/abc/def', path: '/abc'}, 'first to first: many to many') + pathIsDeeply(t, firstToFirst, {target: '/abc/def', path: '/abc'}, 'first to first: many to many') var firstToSecond = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/nope', '/abc', '/xyz']) - t.isDeeply(firstToSecond, {target: '/abc/def', path: '/abc'}, 'first to second: many to many') + pathIsDeeply(t, firstToSecond, {target: '/abc/def', path: '/abc'}, 'first to second: many to many') var firstToLast = areAnyInsideAny(['/abc/def', '/uvw/def', '/xyz/def'], ['/nope', '/nooo', '/abc']) - t.isDeeply(firstToLast, {target: '/abc/def', path: '/abc'}, 'first to last: many to many') + pathIsDeeply(t, firstToLast, {target: '/abc/def', path: '/abc'}, 'first to last: many to many') var secondToFirst = areAnyInsideAny(['/!!!', '/abc/def', '/xyz/def'], ['/abc', '/uvw', '/xyz']) - t.isDeeply(secondToFirst, {target: '/abc/def', path: '/abc'}, 'second to first: many to many') + pathIsDeeply(t, secondToFirst, {target: '/abc/def', path: '/abc'}, 'second to first: many to many') var secondToSecond = areAnyInsideAny(['/!!!', '/abc/def', '/xyz/def'], ['/nope', '/abc', '/xyz']) - t.isDeeply(secondToSecond, {target: '/abc/def', path: '/abc'}, 'second to second: many to many') + pathIsDeeply(t, secondToSecond, {target: '/abc/def', path: '/abc'}, 'second to second: many to many') var secondToLast = areAnyInsideAny(['/!!!', '/abc/def', '/uvw/def'], ['/nope', '/nooo', '/abc']) - t.isDeeply(secondToLast, {target: '/abc/def', path: '/abc'}, 'second to last: many to many') + pathIsDeeply(t, secondToLast, {target: '/abc/def', path: '/abc'}, 'second to last: many to many') var lastToFirst = areAnyInsideAny(['/!!!', '/???', '/abc/def'], ['/abc', '/uvw', '/xyz']) - t.isDeeply(lastToFirst, {target: '/abc/def', path: '/abc'}, 'last to first: many to many') + pathIsDeeply(t, lastToFirst, {target: '/abc/def', path: '/abc'}, 'last to first: many to many') var lastToSecond = areAnyInsideAny(['/!!!', '/???', '/abc/def'], ['/nope', '/abc', '/xyz']) - t.isDeeply(lastToSecond, {target: '/abc/def', path: '/abc'}, 'last to second: many to many') + pathIsDeeply(t, lastToSecond, {target: '/abc/def', path: '/abc'}, 'last to second: many to many') var lastToLast = areAnyInsideAny(['/!!!', '/???', '/abc/def'], ['/nope', '/nooo', '/abc']) - t.isDeeply(lastToLast, {target: '/abc/def', path: '/abc'}, 'last to last: many to many') + pathIsDeeply(t, lastToLast, {target: '/abc/def', path: '/abc'}, 'last to last: many to many') t.done() }) @@ -233,11 +283,11 @@ test('isEverInside', function (t) { }) var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mocks) - var isEverInside = gentlyRm._isEverInside + var isEverInside = makeArgsUsePlatformPaths(gentlyRm._isEverInside) isEverInside('/path/to/file', ['/path/to', '/path/to/invalid'], function (er, inside) { t.ifError(er) - t.isDeeply(inside, {target: '/path/to/file', path: '/path/to'}, 'bad paths are ignored if something matches') + pathIsDeeply(t, inside, {target: '/path/to/file', path: '/path/to'}, 'bad paths are ignored if something matches') }) isEverInside('/path/to/invalid', ['/path/to/invalid'], function (er, inside) { @@ -255,20 +305,20 @@ test('isEverInside', function (t) { isEverInside('/path/to/file', ['/path/to'], function (er, inside) { t.ifError(er) - t.isDeeply(inside, {target: '/path/to/file', path: '/path/to'}, 'plain file in plain path') + pathIsDeeply(t, inside, {target: '/path/to/file', path: '/path/to'}, 'plain file in plain path') }) isEverInside('/path/other/link', ['/path/to'], function (er, inside) { t.ifError(er) - t.isDeeply(inside, {target: '/path/to/file', path: '/path/to'}, 'link in plain path') + pathIsDeeply(t, inside, {target: '/path/to/file', path: '/path/to'}, 'link in plain path') }) isEverInside('/path/to/file', ['/linkpath'], function (er, inside) { t.ifError(er) - t.isDeeply(inside, {target: '/path/to/file', path: '/path/to'}, 'plain file in link path') + pathIsDeeply(t, inside, {target: '/path/to/file', path: '/path/to'}, 'plain file in link path') }) isEverInside('/path/other/link', ['/linkpath'], function (er, inside) { t.ifError(er) - t.isDeeply(inside, {target: '/path/to/file', path: '/path/to'}, 'link in link path') + pathIsDeeply(t, inside, {target: '/path/to/file', path: '/path/to'}, 'link in link path') }) t.done() @@ -276,15 +326,15 @@ test('isEverInside', function (t) { test('isSafeToRm', function (t) { var gentlyRm = requireInject('../../lib/utils/gently-rm.js', mockWith({})) - var isSafeToRm = gentlyRm._isSafeToRm + var isSafeToRm = makeArgsUsePlatformPaths(gentlyRm._isSafeToRm) t.plan(12) function testIsSafeToRm (t, parent, target, shouldPath, shouldBase, msg) { isSafeToRm(parent, target, function (er, path, base) { t.ifError(er, msg + ' no error') - t.is(path, shouldPath, msg + ' path') - t.is(base, shouldBase, msg + ' base') + pathIs(t, path, shouldPath, msg + ' path') + pathIs(t, base, shouldBase, msg + ' base') }) } diff --git a/deps/npm/test/tap/unit-link.js b/deps/npm/test/tap/unit-link.js new file mode 100644 index 0000000000..e4b9094068 --- /dev/null +++ b/deps/npm/test/tap/unit-link.js @@ -0,0 +1,281 @@ +'use strict' +var util = require('util') +var test = require('tap').test +var requireInject = require('require-inject') +var dezalgo = require('dezalgo') +var mkdirp = require('mkdirp') +var path = require('path') + +test('gently/force', function (t) { + t.plan(5) + + linkOk(t, 'gently=true, force=false, works', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: true, + abs: true, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: true}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkNotOk(t, 'gently=true, force=false, does not work', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: true, + abs: true, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: false}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'gently=false, force=false, aok', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: false, + abs: true, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: false}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'gently=true, force=true, aok', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: true, + abs: true, + force: true, + + // expect + rm: {'/foo/bar/baz': {gently: false}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'gently=false, force=true, aok', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: false, + abs: true, + force: true, + + // expect + rm: {'/foo/bar/baz': {gently: false}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) +}) + +test('abs, noabs', function (t) { + t.plan(4) + + linkOk(t, 'abs', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: true, + abs: true, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: true}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'/foo/bar/wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'relative', { + // args + from: 'wibble', + to: '/foo/bar/baz', + gently: true, + abs: false, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: true}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/bar/wibble': {isLink: false}}, + stat: {'/foo/bar/wibble': true}, + symlink: {'wibble': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'relative ..', { + // args + from: '../wibble/bark/blump', + to: '/foo/bar/baz', + gently: true, + abs: false, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: true}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/wibble/bark/blump': {isLink: false}}, + stat: {'/foo/wibble/bark/blump': true}, + symlink: {'../wibble/bark/blump': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) + + linkOk(t, 'relative .. deep', { + // args + from: 'zib/zap/../../../wibble/bark/blump', + to: '/foo/bar/baz', + gently: true, + abs: false, + force: false, + + // expect + rm: {'/foo/bar/baz': {gently: true}}, + mkdir: {'/foo/bar': true}, + lstat: {'/foo/wibble/bark/blump': {isLink: false}}, + stat: {'/foo/wibble/bark/blump': true}, + symlink: {'../wibble/bark/blump': {'/foo/bar/baz': 'junction'}}, + readlink: {} + }) +}) + +function linkOk (t, msg, opts) { + testLink(opts, function (err) { + t.ifError(err, msg) + }) +} + +function linkNotOk (t, msg, opts) { + testLink(opts, function (err) { + t.ok(err, msg) + }) +} + +function platformPath (unixPath) { + if (unixPath[0] === '/') { + return path.resolve(unixPath) + } else { + return path.join.apply(path, unixPath.split('/')) + } +} + +function platformerize (obj) { + Object.keys(obj).forEach(function (key) { + var newKey = platformPath(key) + if (typeof obj[key] === 'object') { + platformerize(obj[key]) + } else if (typeof obj[key] === 'string') { + obj[key] = platformPath(obj[key]) + } + if (newKey !== key) { + obj[newKey] = obj[key] + delete obj[key] + } + }) +} + +function testLink (opts, cb) { + var mkdirpMock = dezalgo(function (dir, cb) { + if (opts.mkdir[dir]) { + cb() + } else { + cb(new Error('mkdirp failed: ' + util.inspect(dir))) + } + }) + // sync version used by istanbul for test coverage + // we shouldn't have to do this ;.; + // require-inject and/or instanbul will need patching + mkdirpMock.sync = mkdirp.sync + + // convert any paths in our opts into platform specific paths, for windows support. + platformerize(opts) + + var link = requireInject('../../lib/utils/link.js', { + '../../lib/npm.js': { + config: { + get: function (name) { + if (name !== 'force') return new Error('unknown config key: ' + name) + return opts.force + } + } + }, + '../../lib/utils/gently-rm.js': dezalgo(function (toRemove, gently, cb) { + if (opts.rm[toRemove] && opts.rm[toRemove].gently === gently) { + cb() + } else { + cb(new Error('Removing toRemove: ' + util.inspect(toRemove) + + ' gently: ' + util.inspect(gently) + + ' not allowed: ' + util.inspect(opts.rm))) + } + }), + 'mkdirp': mkdirpMock, + 'graceful-fs': { + 'stat': dezalgo(function (file, cb) { + if (opts.stat[file]) { + cb(null, {}) + } else { + cb(new Error('stat failed for: ' + util.inspect(file))) + } + }), + 'lstat': dezalgo(function (file, cb) { + if (opts.lstat[file]) { + var linkStat = opts.lstat[file] + cb(null, { + isSymbolicLink: function () { + return linkStat.isLink + } + }) + } else { + cb(new Error('lstat failed for: ' + util.inspect(file))) + } + }), + 'symlink': dezalgo(function (from, to, type, cb) { + if (!cb) { + cb = type + type = null + } + if (opts.symlink[from] && opts.symlink[from][to] === type) { + cb() + } else { + cb(new Error('symlink failed from: ' + util.inspect(from) + ' to: ' + util.inspect(to) + ' type: ' + util.inspect(type))) + } + }), + 'readlink': function (file, cb) { + if (opts.readlink[file]) { + cb() + } else { + cb(new Error('readlink failed for: ' + util.inspect(file))) + } + } + } + }) + link(opts.from, opts.to, opts.gently, opts.abs, cb) +} diff --git a/deps/npm/test/tap/unpack-foreign-tarball.js b/deps/npm/test/tap/unpack-foreign-tarball.js index 56d707c31a..d128e94d8c 100644 --- a/deps/npm/test/tap/unpack-foreign-tarball.js +++ b/deps/npm/test/tap/unpack-foreign-tarball.js @@ -21,8 +21,7 @@ var EXEC_OPTS = { 'npm_config_cache': cache, 'npm_config_tmp': tmp }, - cwd: pkg, - stdio: [ 'pipe', 'pipe', 2 ] + cwd: pkg } function verify (t, files, err, code) { diff --git a/deps/npm/test/tap/unpublish-config.js b/deps/npm/test/tap/unpublish-config.js index d6e18eb024..92a0c731fe 100644 --- a/deps/npm/test/tap/unpublish-config.js +++ b/deps/npm/test/tap/unpublish-config.js @@ -44,7 +44,7 @@ test('cursory test of unpublishing with config', function (t) { res.end(JSON.stringify({ error: 'shh no tears, only dreams now' })) - child.kill('SIGHUP') + child.kill('SIGINT') }).listen(common.port, function () { t.pass('server is listening') diff --git a/deps/npm/test/tap/verify-no-lifecycle-on-repo.js b/deps/npm/test/tap/verify-no-lifecycle-on-repo.js index 29f79e2983..eedaa756b8 100644 --- a/deps/npm/test/tap/verify-no-lifecycle-on-repo.js +++ b/deps/npm/test/tap/verify-no-lifecycle-on-repo.js @@ -4,7 +4,8 @@ var fs = require('graceful-fs') var mkdirp = require('mkdirp') var rimraf = require('rimraf') var test = require('tap').test -var common = require('../common-tap.js') +var requireInject = require('require-inject') +require('../common-tap.js') var base = path.join(__dirname, path.basename(__filename, '.js')) @@ -20,6 +21,17 @@ var baseJSON = { } } +var lastOpened +var npm = requireInject.installGlobally('../../lib/npm.js', { + '../../lib/utils/lifecycle.js': function (pkg, stage, wd, unsafe, failOk, cb) { + cb(new Error("Shouldn't be calling lifecycle scripts")) + }, + opener: function (url, options, cb) { + lastOpened = {url: url, options: options} + cb() + } +}) + test('setup', function (t) { cleanup() setup() @@ -27,11 +39,14 @@ test('setup', function (t) { }) test('repo', function (t) { - common.npm(['repo', '--browser=echo'], {cwd: base}, function (er, code, stdout, stderr) { - t.ifError(er, 'npm config ran without issue') - t.is(code, 0, 'exited with a non-error code') - t.is(stderr, '', 'Ran without errors') - t.end() + process.chdir(base) + npm.load({browser: 'echo'}, function () { + npm.commands.repo([], function (err) { + t.ifError(err, 'no errors') + t.match(lastOpened.url, baseJSON.repository.url, 'opened the right url') + t.is(lastOpened.options.command, 'echo', 'opened with a specified browser') + t.end() + }) }) }) diff --git a/deps/npm/test/tap/version-lifecycle.js b/deps/npm/test/tap/version-lifecycle.js index 5d78b71d59..3b4fb50b24 100644 --- a/deps/npm/test/tap/version-lifecycle.js +++ b/deps/npm/test/tap/version-lifecycle.js @@ -21,11 +21,10 @@ test('npm version <semver> with failing preversion lifecycle script', function ( version: '0.0.0', description: 'Test for npm version if preversion script fails', scripts: { - preversion: './fail.sh' + preversion: 'node ./fail.js' } }), 'utf8') - fs.writeFileSync(path.resolve(pkg, 'fail.sh'), 'exit 50', 'utf8') - fs.chmodSync(path.resolve(pkg, 'fail.sh'), 448) + fs.writeFileSync(path.resolve(pkg, 'fail.js'), 'process.exit(50)', 'utf8') npm.load({cache: cache, 'sign-git-tag': false, registry: common.registry}, function () { var version = require('../../lib/version') version(['patch'], function (err) { @@ -44,11 +43,10 @@ test('npm version <semver> with failing version lifecycle script', function (t) version: '0.0.0', description: 'Test for npm version if postversion script fails', scripts: { - version: './fail.sh' + version: 'node ./fail.js' } }), 'utf8') - fs.writeFileSync(path.resolve(pkg, 'fail.sh'), 'exit 50', 'utf8') - fs.chmodSync(path.resolve(pkg, 'fail.sh'), 448) + fs.writeFileSync(path.resolve(pkg, 'fail.js'), 'process.exit(50)', 'utf8') npm.load({cache: cache, 'sign-git-tag': false, registry: common.registry}, function () { var version = require('../../lib/version') version(['patch'], function (err) { @@ -67,11 +65,10 @@ test('npm version <semver> with failing postversion lifecycle script', function version: '0.0.0', description: 'Test for npm version if postversion script fails', scripts: { - postversion: './fail.sh' + postversion: 'node ./fail.js' } }), 'utf8') - fs.writeFileSync(path.resolve(pkg, 'fail.sh'), 'exit 50', 'utf8') - fs.chmodSync(path.resolve(pkg, 'fail.sh'), 448) + fs.writeFileSync(path.resolve(pkg, 'fail.js'), 'process.exit(50)', 'utf8') npm.load({cache: cache, 'sign-git-tag': false, registry: common.registry}, function () { var version = require('../../lib/version') version(['patch'], function (err) { @@ -90,9 +87,9 @@ test('npm version <semver> execution order', function (t) { version: '0.0.0', description: 'Test for npm version if postversion script fails', scripts: { - preversion: './preversion.sh', - version: './version.sh', - postversion: './postversion.sh' + preversion: 'node ./preversion.js', + version: 'node ./version.js', + postversion: 'node ./postversion.js' } }), 'utf8') makeScript('preversion') @@ -143,14 +140,31 @@ function setup () { } function makeScript (lifecycle) { - var contents = [ - 'cp package.json ' + lifecycle + '-package.json', - 'git add ' + lifecycle + '-package.json', - 'git status --porcelain > ' + lifecycle + '-git.txt' - ].join('\n') - var scriptPath = path.join(pkg, lifecycle + '.sh') - fs.writeFileSync(scriptPath, contents, 'utf-8') - fs.chmodSync(scriptPath, 448) + function contents (lifecycle) { + var fs = require('fs') + var exec = require('child_process').exec + fs.createReadStream('package.json') + .pipe(fs.createWriteStream(lifecycle + '-package.json')) + .on('close', function () { + exec( + 'git add ' + lifecycle + '-package.json', + function () { + exec( + 'git status --porcelain', + function (err, stdout) { + if (err) throw err + fs.writeFileSync(lifecycle + '-git.txt', stdout) + } + ) + } + ) + }) + } + var scriptPath = path.join(pkg, lifecycle + '.js') + fs.writeFileSync( + scriptPath, + '(' + contents.toString() + ')(\'' + lifecycle + '\')', + 'utf-8') } function readPackage (lifecycle) { diff --git a/deps/npm/test/tap/version-update-shrinkwrap.js b/deps/npm/test/tap/version-update-shrinkwrap.js index c51ab2cb0d..d9f54d6872 100644 --- a/deps/npm/test/tap/version-update-shrinkwrap.js +++ b/deps/npm/test/tap/version-update-shrinkwrap.js @@ -110,15 +110,12 @@ test('npm version <semver> updates shrinkwrap and updates git', function (t) { }) test('cleanup', function (t) { - // windows fix for locked files - process.chdir(osenv.tmpdir()) - - rimraf.sync(pkg) + cleanup() t.end() }) function setup () { - rimraf.sync(pkg) + cleanup() mkdirp.sync(pkg) mkdirp.sync(cache) var contents = { @@ -132,3 +129,10 @@ function setup () { fs.writeFileSync(path.resolve(pkg, 'npm-shrinkwrap.json'), JSON.stringify(contents), 'utf8') process.chdir(pkg) } + +function cleanup () { + // windows fix for locked files + process.chdir(osenv.tmpdir()) + rimraf.sync(cache) + rimraf.sync(pkg) +} |