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.
 
 
 
 
 
 

281 lines
7.0 KiB

'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)
}