mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
630 lines
20 KiB
630 lines
20 KiB
'use strict'
|
|
var path = require('path')
|
|
var test = require('tap').test
|
|
var fs = require('fs')
|
|
var rimraf = require('rimraf')
|
|
var mr = require('npm-registry-mock')
|
|
var Tacks = require('tacks')
|
|
var File = Tacks.File
|
|
var Symlink = Tacks.Symlink
|
|
var Dir = Tacks.Dir
|
|
var common = require('../common-tap.js')
|
|
var isWindows = require('../../lib/utils/is-windows.js')
|
|
|
|
var basedir = path.join(__dirname, path.basename(__filename, '.js'))
|
|
var testdir = path.join(basedir, 'testdir')
|
|
var cachedir = path.join(basedir, 'cache')
|
|
var globaldir = path.join(basedir, 'global')
|
|
var tmpdir = path.join(basedir, 'tmp')
|
|
|
|
var conf = {
|
|
cwd: testdir,
|
|
env: common.emptyEnv().extend({
|
|
npm_config_cache: cachedir,
|
|
npm_config_tmp: tmpdir,
|
|
npm_config_prefix: globaldir,
|
|
npm_config_registry: common.registry,
|
|
npm_config_loglevel: 'error'
|
|
}),
|
|
stdio: [0, 'pipe', 2]
|
|
}
|
|
var confE = {
|
|
cwd: testdir,
|
|
env: conf.env,
|
|
stdio: [0, 'pipe', 'pipe']
|
|
}
|
|
|
|
function readJson (file) {
|
|
return JSON.parse(fs.readFileSync(file))
|
|
}
|
|
|
|
function isSymlink (t, file, message) {
|
|
try {
|
|
var info = fs.lstatSync(file)
|
|
t.is(info.isSymbolicLink(), true, message)
|
|
} catch (ex) {
|
|
if (ex.code === 'ENOENT') {
|
|
t.fail(message, {found: null, wanted: 'symlink', compare: 'fs.lstat(' + file + ')'})
|
|
} else {
|
|
t.fail(message, {found: ex, wanted: 'symlink', compare: 'fs.lstat(' + file + ')'})
|
|
}
|
|
}
|
|
}
|
|
|
|
function fileExists (t, file, message) {
|
|
try {
|
|
fs.statSync(file)
|
|
t.pass(message)
|
|
} catch (ex) {
|
|
if (ex.code === 'ENOENT') {
|
|
t.fail(message, {found: null, wanted: 'exists', compare: 'fs.stat(' + file + ')'})
|
|
} else {
|
|
t.fail(message, {found: ex, wanted: 'exists', compare: 'fs.stat(' + file + ')'})
|
|
}
|
|
}
|
|
}
|
|
|
|
function noFileExists (t, file, message) {
|
|
try {
|
|
fs.statSync(file)
|
|
t.fail(message, {found: 'exists', wanted: 'not exists', compare: 'fs.stat(' + file + ')'})
|
|
} catch (ex) {
|
|
if (ex.code === 'ENOENT') {
|
|
t.pass(message)
|
|
} else {
|
|
t.fail(message, {found: ex, wanted: 'not exists', compare: 'fs.stat(' + file + ')'})
|
|
}
|
|
}
|
|
}
|
|
|
|
var server
|
|
var testdirContent = {
|
|
node_modules: Dir({}),
|
|
pkga: Dir({
|
|
'package.json': File({
|
|
name: 'pkga',
|
|
version: '1.0.0'
|
|
})
|
|
}),
|
|
pkgb: Dir({
|
|
'package.json': File({
|
|
name: 'pkgb',
|
|
version: '1.0.0'
|
|
})
|
|
}),
|
|
pkgc: Dir({
|
|
'package.json': File({
|
|
name: 'pkgc',
|
|
version: '1.0.0'
|
|
})
|
|
}),
|
|
pkgd: Dir({
|
|
'package.json': File({
|
|
name: 'pkgd',
|
|
version: '1.0.0'
|
|
})
|
|
})
|
|
}
|
|
|
|
var fixture
|
|
function setup () {
|
|
fixture = new Tacks(Dir({
|
|
cache: Dir(),
|
|
global: Dir(),
|
|
tmp: Dir(),
|
|
testdir: Dir(testdirContent)
|
|
}))
|
|
cleanup()
|
|
fixture.create(basedir)
|
|
}
|
|
|
|
function cleanup () {
|
|
fixture.remove(basedir)
|
|
}
|
|
|
|
test('setup', function (t) {
|
|
process.nextTick(function () {
|
|
setup()
|
|
mr({port: common.port, throwOnUnmatched: true}, function (err, s) {
|
|
if (err) throw err
|
|
server = s
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
|
|
var installOk = []
|
|
var slashes = [ 'unix', 'win' ]
|
|
slashes.forEach(function (os) {
|
|
var slash = os === 'unix'
|
|
? function (ss) { return ss.replace(/\\/g, '/') }
|
|
: function (ss) { return ss.replace(/\//g, '\\') }
|
|
installOk.push(os + '-file-abs-f')
|
|
testdirContent[os + '-file-abs-f'] = Dir({
|
|
'package.json': File({
|
|
name: os + '-file-abs-f',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file:' + slash(testdir + '/pkga')
|
|
}
|
|
})
|
|
})
|
|
installOk.push(os + '-file-abs-fff')
|
|
testdirContent[os + '-file-abs-fff'] = Dir({
|
|
'package.json': File({
|
|
name: os + '-file-abs-fff',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file://' + slash(testdir + '/pkga')
|
|
}
|
|
})
|
|
})
|
|
installOk.push(os + '-file-rel')
|
|
testdirContent[os + '-file-rel'] = Dir({
|
|
'package.json': File({
|
|
name: os + '-file-rel',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file:' + slash('../pkga')
|
|
}
|
|
})
|
|
})
|
|
installOk.push(os + '-file-rel-fffff')
|
|
testdirContent[os + '-file-rel-fffff'] = Dir({
|
|
'package.json': File({
|
|
name: os + '-file-rel-fffff',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file:' + slash('/////../pkga')
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
testdirContent['win-abs-drive-win'] = Dir({
|
|
'package.json': File({
|
|
name: 'win-abs-drive-win',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file:D:\\thing\\pkga'
|
|
}
|
|
})
|
|
})
|
|
|
|
testdirContent['win-abs-drive-unix'] = Dir({
|
|
'package.json': File({
|
|
name: 'win-abs-drive-unix',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
pkga: 'file://D:/thing/pkga'
|
|
}
|
|
})
|
|
})
|
|
|
|
test('specifiers', function (t) {
|
|
t.plan(installOk.length + 2)
|
|
installOk.forEach(function (mod) {
|
|
t.test(mod, function (t) {
|
|
common.npm(['install', '--dry-run', '--json', 'file:' + mod], conf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
t.comment(stdout.trim())
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
slashes.forEach(function (os) {
|
|
t.test('win-abs-drive-' + os, function (t) {
|
|
common.npm(['install', '--dry-run', '--json', 'file:win-abs-drive-' + os], confE, function (err, code, stdout, stderr) {
|
|
if (err) throw err
|
|
t.not(code, 0, 'command errored ok')
|
|
t.comment(stderr.trim())
|
|
if (isWindows) {
|
|
t.test('verify failure of file-not-found or wrong drive letter on windows')
|
|
} else {
|
|
var result = JSON.parse(stdout)
|
|
t.is(result.error && result.error.code, 'EWINDOWSPATH', 'verify failure due to windows paths not supported on non-Windows')
|
|
}
|
|
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
testdirContent['mkdirp'] = Dir({
|
|
'package.json': File({
|
|
name: 'mkdirp',
|
|
version: '9.9.9'
|
|
})
|
|
})
|
|
testdirContent['example'] = Dir({
|
|
'minimist': Dir({
|
|
'package.json': File({
|
|
name: 'minimist',
|
|
version: '9.9.9'
|
|
})
|
|
})
|
|
})
|
|
testdirContent['wordwrap'] = Dir({
|
|
})
|
|
testdirContent['prefer-pkg'] = Dir({
|
|
'package.json': File({
|
|
name: 'perfer-pkg',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'mkdirp': 'latest'
|
|
}
|
|
}),
|
|
'latest': Dir({
|
|
'package.json': File({
|
|
name: 'mkdirp',
|
|
version: '9.9.9'
|
|
})
|
|
})
|
|
})
|
|
|
|
test('ambiguity', function (t) {
|
|
t.plan(5)
|
|
t.test('arg: looks like package name, is dir', function (t) {
|
|
common.npm(['install', 'mkdirp', '--dry-run', '--json'], conf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
const result = JSON.parse(stdout.trim())
|
|
t.like(result, {added: [{name: 'mkdirp', version: '9.9.9'}]}, 'got local dir')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('arg: looks like package name, is package', function (t) {
|
|
common.npm(['install', 'wordwrap', '--dry-run', '--json'], conf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
const result = JSON.parse(stdout.trim())
|
|
t.like(result, {added: [{name: 'wordwrap', version: '0.0.2'}]}, 'even with local dir w/o package.json, got global')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('arg: looks like github repo, is dir', function (t) {
|
|
common.npm(['install', 'example/minimist', '--dry-run', '--json'], conf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
const result = JSON.parse(stdout.trim())
|
|
t.like(result, {added: [{name: 'minimist', version: '9.9.9'}]}, 'got local dir')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('package: looks like tag, has dir, use tag', function (t) {
|
|
common.npm(['install', '--dry-run', '--json'], {cwd: path.join(testdir, 'prefer-pkg'), env: conf.env}, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
const result = JSON.parse(stdout.trim())
|
|
t.like(result, {added: [{name: 'mkdirp', version: '0.3.5'}]}, 'got local dir')
|
|
t.done()
|
|
})
|
|
})
|
|
|
|
t.test('test ambiguity for github repos')
|
|
})
|
|
testdirContent['existing-matches'] = Dir({
|
|
'package.json': File({
|
|
name: 'existing-matches',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'pkga': 'file:../pkga',
|
|
'pkgb': 'file:' + testdir + '/pkgb',
|
|
'pkgc': 'file:../pkgc',
|
|
'pkgd': 'file:' + testdir + '/pkgd'
|
|
}
|
|
}),
|
|
'node_modules': Dir({
|
|
'pkga': Symlink('../../pkga'),
|
|
'pkgd': Symlink('../../pkgd')
|
|
})
|
|
})
|
|
|
|
test('existing install matches', function (t) {
|
|
t.plan(1)
|
|
// have to make these by hand because tacks doesn't support absolute paths in symlinks
|
|
fs.symlinkSync(testdir + '/pkgb', testdir + '/existing-matches/node_modules/pkgb', 'junction')
|
|
fs.symlinkSync(testdir + '/pkgc', testdir + '/existing-matches/node_modules/pkgc', 'junction')
|
|
t.test('relative symlink counts as match of relative symlink in package.json', function (t) {
|
|
common.npm(['ls', '--json'], {cwd: path.join(testdir, 'existing-matches'), env: conf.env}, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
if (stdout) t.comment(stdout.trim())
|
|
t.test('specifically test that output is valid')
|
|
// relative symlink counts as match of relative symlink in package.json (pkga)
|
|
// relative symlink counts as match of abs symlink in package.json (pkgc)
|
|
// abs symlink counts as match of relative symlink in package.json (pkgb)
|
|
// abs symlink counts as match of abs symlink in package.json (pkgd)
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
var ibdir = testdir + '/install-behavior'
|
|
testdirContent['ib-out'] = Dir({
|
|
'package.json': File({
|
|
name: 'ib-out',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'minimist': '*'
|
|
}
|
|
})
|
|
})
|
|
|
|
testdirContent['install-behavior'] = Dir({
|
|
'package.json': File({
|
|
name: 'install-behavior',
|
|
version: '1.0.0'
|
|
}),
|
|
'ib-in': Dir({
|
|
'package.json': File({
|
|
name: 'ib-in',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'mkdirp': '*'
|
|
}
|
|
})
|
|
}),
|
|
'noext': File(new Buffer(
|
|
'1f8b08000000000000032b484cce4e4c4fd52f80d07a59c5f9790c540606' +
|
|
'06066626260a20dadccc144c1b1841f86000923334363037343536343732' +
|
|
'633000728c0c80f2d4760836505a5c925804740aa5e640bca200a78708a8' +
|
|
'56ca4bcc4d55b252cacb4fad2851d251502a4b2d2acecccf030a19ea19e8' +
|
|
'1928d5720db41b47c1281805a36014501f00005012007200080000',
|
|
'hex'
|
|
)),
|
|
'tarball-1.0.0.tgz': File(new Buffer(
|
|
'1f8b08000000000000032b484cce4e4c4fd52f80d07a59c5f9790c540606' +
|
|
'06066626260a20dadccc144c1b1841f8606062a6c060686c606e686a6c68' +
|
|
'666ec26000e480e5a9ed106ca0b4b824b108e8144acd817845014e0f1150' +
|
|
'ad9497989baa64a5040c85a4c49c1c251d05a5b2d4a2e2ccfc3ca0a0a19e' +
|
|
'819e81522dd740bb72148c8251300a4601b50100473dd15800080000',
|
|
'hex'
|
|
)),
|
|
'not-module': Dir({}),
|
|
'test-preinstall': Dir({
|
|
'preinstall.js': File('console.log("CWD:" + process.cwd())'),
|
|
'package.json': File({
|
|
name: 'test-preinstall',
|
|
version: '1.0.0',
|
|
scripts: {
|
|
'preinstall': 'node ' + ibdir + '/test-preinstall/preinstall.js'
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
test('install behavior', function (t) {
|
|
var ibconf = {cwd: ibdir, env: conf.env.extend({npm_config_loglevel: 'silent'}), stdio: conf.stdio}
|
|
t.plan(7)
|
|
t.test('transitive deps for in-larger-module cases', function (t) {
|
|
common.npm(['install', 'file:ib-in'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
if (stdout) t.comment(stdout.trim())
|
|
fileExists(t, ibdir + '/node_modules/mkdirp', 'transitive dep flattened')
|
|
isSymlink(t, ibdir + '/node_modules/ib-in', 'dep is symlink')
|
|
noFileExists(t, ibdir + '/ib-in/node_modules/mkdirp', 'transitive dep not nested')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('transitive deps for out-of-larger module cases', function (t) {
|
|
common.npm(['install', 'file:../ib-out'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
if (stdout) t.comment(stdout.trim())
|
|
noFileExists(t, ibdir + '/node_modules/minimist', 'transitive dep not flattened')
|
|
fileExists(t, testdir + '/ib-out/node_modules/minimist', 'transitive dep nested')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('transitive deps for out-of-larger module cases w/ --preserve-symlinks', function (t) {
|
|
rimraf.sync(ibdir + '/node_modules')
|
|
rimraf.sync(testdir + '/ib-out/node_modules')
|
|
var env = conf.env.extend({NODE_PRESERVE_SYMLINKS: '1'})
|
|
common.npm(['install', 'file:../ib-out'], {cwd: ibdir, env: env}, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
if (stdout) t.comment(stdout.trim())
|
|
fileExists(t, ibdir + '/node_modules/minimist', 'transitive dep flattened')
|
|
noFileExists(t, testdir + '/ib-out/node_modules/minimist', 'transitive dep not nested')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('tar/tgz/tar.gz should install a tarball', function (t) {
|
|
common.npm(['install', 'file:tarball-1.0.0.tgz'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
if (stdout) t.comment(stdout.trim())
|
|
fileExists(t, ibdir + '/node_modules/tarball')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('non tar/tgz/tar.gz files should give good error message', function (t) {
|
|
common.npm(['install', 'file:noext', '--json'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.not(code, 0, 'do not install files w/o extensions')
|
|
noFileExists(t, ibdir + '/node_modules/noext')
|
|
var result = JSON.parse(stdout)
|
|
t.like(result, {error: {code: 'ENOLOCAL'}}, 'new type of error')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('directories without package.json should give good error message', function (t) {
|
|
common.npm(['install', 'file:not-module', '--json'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.not(code, 0, 'error on dir w/o module')
|
|
var result = JSON.parse(stdout)
|
|
t.like(result, {error: {code: 'ENOLOCAL'}}, 'new type of error')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('verify preinstall step runs after finalize, such that cwd is as expected', function (t) {
|
|
common.npm(['install', 'file:test-preinstall'], ibconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
isSymlink(t, `${ibdir}/node_modules/test-preinstall`, 'installed as symlink')
|
|
t.notLike(stdout, /CWD:.*[.]staging/, 'cwd should not be in staging')
|
|
|
|
t.test('verify that env is as expected')
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
var sbdir = testdir + '/save-behavior'
|
|
testdirContent['save-behavior'] = Dir({
|
|
'package.json': File({
|
|
name: 'save-behavior',
|
|
version: '1.0.0'
|
|
}),
|
|
'npm-shrinkwrap.json': File({
|
|
name: 'save-behavior',
|
|
version: '1.0.0',
|
|
dependencies: {}
|
|
}),
|
|
'transitive': Dir({
|
|
'package.json': File({
|
|
name: 'transitive',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'pkgc': 'file:../../pkgc'
|
|
}
|
|
})
|
|
})
|
|
})
|
|
testdirContent['sb-transitive'] = Dir({
|
|
'package.json': File({
|
|
name: 'sb-transitive',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'sbta': 'file:sbta'
|
|
}
|
|
}),
|
|
'sbta': Dir({
|
|
'package.json': File({
|
|
name: 'sbta',
|
|
version: '1.0.0'
|
|
})
|
|
})
|
|
})
|
|
var sbdirp = testdir + '/save-behavior-pre'
|
|
testdirContent['save-behavior-pre'] = Dir({
|
|
'package.json': File({
|
|
name: 'save-behavior',
|
|
version: '1.0.0'
|
|
}),
|
|
'npm-shrinkwrap.json': File({
|
|
name: 'save-behavior',
|
|
version: '1.0.0',
|
|
dependencies: {}
|
|
})
|
|
})
|
|
testdirContent['sb-transitive-preserve'] = Dir({
|
|
'package.json': File({
|
|
name: 'sb-transitive-preserve',
|
|
version: '1.0.0',
|
|
dependencies: {
|
|
'sbtb': 'file:sbtb'
|
|
}
|
|
}),
|
|
'sbtb': Dir({
|
|
'package.json': File({
|
|
name: 'sbtb',
|
|
version: '1.0.0'
|
|
})
|
|
})
|
|
})
|
|
test('save behavior', function (t) {
|
|
t.plan(6)
|
|
var sbconf = {cwd: sbdir, env: conf.env, stdio: conf.stdio}
|
|
t.test('to package.json and npm-shrinkwrap.json w/ abs', function (t) {
|
|
common.npm(['install', '--save', 'file:' + testdir + '/pkga'], sbconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
var pjson = readJson(sbdir + '/package.json')
|
|
var shrinkwrap = readJson(sbdir + '/npm-shrinkwrap.json')
|
|
t.is(pjson.dependencies.pkga, 'file:../pkga', 'package.json')
|
|
var sdep = shrinkwrap.dependencies
|
|
t.like(sdep, {pkga: {version: 'file:../pkga', resolved: null}}, 'npm-shrinkwrap.json')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('to package.json and npm-shrinkwrap.json w/ drive abs')
|
|
t.test('to package.json and npm-shrinkwrap.json w/ rel', function (t) {
|
|
common.npm(['install', '--save', 'file:../pkgb'], sbconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
var pjson = readJson(sbdir + '/package.json')
|
|
var shrinkwrap = readJson(sbdir + '/npm-shrinkwrap.json')
|
|
t.is(pjson.dependencies.pkgb, 'file:../pkgb', 'package.json')
|
|
var sdep = shrinkwrap.dependencies
|
|
t.like(sdep, {pkgb: {version: 'file:../pkgb', resolved: null}}, 'npm-shrinkwrap.json')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('internal transitive dependencies of shrinkwraps', function (t) {
|
|
common.npm(['install', '--save', 'file:transitive'], sbconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
var pjson = readJson(sbdir + '/package.json')
|
|
var shrinkwrap = readJson(sbdir + '/npm-shrinkwrap.json')
|
|
t.is(pjson.dependencies.transitive, 'file:transitive', 'package.json')
|
|
var sdep = shrinkwrap.dependencies.transitive || {}
|
|
var tdep = shrinkwrap.dependencies.pkgc
|
|
t.is(sdep.version, 'file:transitive', 'npm-shrinkwrap.json direct dep')
|
|
t.is(tdep.version, 'file:../pkgc', 'npm-shrinkwrap.json transitive dep')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('external transitive dependencies of shrinkwraps', function (t) {
|
|
common.npm(['install', '--save', 'file:../sb-transitive'], sbconf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
var pjson = readJson(sbdir + '/package.json')
|
|
var shrinkwrap = readJson(sbdir + '/npm-shrinkwrap.json')
|
|
var deps = pjson.dependencies || {}
|
|
t.is(deps['sb-transitive'], 'file:../sb-transitive', 'package.json')
|
|
var sdep = shrinkwrap.dependencies['sb-transitive'] || {}
|
|
var tdep = sdep.dependencies.sbta
|
|
t.like(tdep, {bundled: true, version: 'file:../sb-transitive/sbta'}, 'npm-shrinkwrap.json transitive dep')
|
|
t.like(sdep, {bundled: null, version: 'file:../sb-transitive'}, 'npm-shrinkwrap.json direct dep')
|
|
t.done()
|
|
})
|
|
})
|
|
t.test('external transitive dependencies of shrinkwraps > preserve symlinks', function (t) {
|
|
var preserveEnv = conf.env.extend({NODE_PRESERVE_SYMLINKS: '1'})
|
|
var preserveConf = {cwd: sbdirp, env: preserveEnv, stdio: conf.stdio}
|
|
common.npm(['install', '--save', 'file:../sb-transitive-preserve'], preserveConf, function (err, code, stdout) {
|
|
if (err) throw err
|
|
t.is(code, 0, 'command ran ok')
|
|
var pjson = readJson(sbdirp + '/package.json')
|
|
var shrinkwrap = readJson(sbdirp + '/npm-shrinkwrap.json')
|
|
t.is(pjson.dependencies['sb-transitive-preserve'], 'file:../sb-transitive-preserve', 'package.json')
|
|
var sdep = shrinkwrap.dependencies['sb-transitive-preserve'] || {}
|
|
var tdep = shrinkwrap.dependencies.sbtb
|
|
t.like(sdep, {bundled: null, version: 'file:../sb-transitive-preserve'}, 'npm-shrinkwrap.json direct dep')
|
|
t.like(tdep, {bundled: null, version: 'file:../sb-transitive-preserve/sbtb'}, 'npm-shrinkwrap.json transitive dep')
|
|
t.done()
|
|
})
|
|
})
|
|
})
|
|
|
|
test('removal', function (t) {
|
|
t.plan(3)
|
|
t.test('should remove the symlink')
|
|
t.test('should not remove the transitive deps if it was not a `link:` type specifier.')
|
|
t.test("should not remove transitive deps if it's outside the package and --preserver-symlinks isn't set")
|
|
})
|
|
|
|
test('misc', function (t) {
|
|
t.plan(3)
|
|
t.test('listing: should look right, not include version')
|
|
t.test('outdated: show LOCAL for wanted / latest')
|
|
t.test('update: if specifier exists, do nothing. otherwise as if `npm install`.')
|
|
})
|
|
|
|
test('cleanup', function (t) {
|
|
server.close()
|
|
cleanup()
|
|
t.done()
|
|
})
|
|
|