mirror of https://gitee.com/openkylin/npm.git
218 lines
5.2 KiB
JavaScript
218 lines
5.2 KiB
JavaScript
const t = require('tap')
|
|
|
|
// turn on debug mode, or this does nothing
|
|
const treeCheck = t.mock('../lib/tree-check.js', {
|
|
'../lib/debug.js': fn => fn(),
|
|
})
|
|
|
|
const { resolve } = require('path')
|
|
|
|
const Node = require('../lib/node.js')
|
|
const Link = require('../lib/link.js')
|
|
const Edge = require('../lib/edge.js')
|
|
|
|
t.test('basic tree that is a-ok', t => {
|
|
const tree = new Node({
|
|
path: '/some/path',
|
|
pkg: {},
|
|
children: [
|
|
{ pkg: { name: 'foo', version: '1.2.3' } },
|
|
],
|
|
})
|
|
const link = new Link({
|
|
parent: tree,
|
|
name: 'glorb',
|
|
target: new Node({
|
|
fsParent: tree,
|
|
path: '/some/path/glorb',
|
|
pkg: { name: 'glorb', version: '1.2.3' },
|
|
}),
|
|
})
|
|
link.parent = tree
|
|
t.equal(treeCheck(tree), tree)
|
|
t.equal(treeCheck(link), link)
|
|
t.equal(treeCheck(link.target), link.target)
|
|
const nonTree = {}
|
|
t.equal(treeCheck(nonTree), nonTree)
|
|
nonTree.root = {}
|
|
t.equal(treeCheck(nonTree), nonTree)
|
|
t.end()
|
|
})
|
|
|
|
t.test('break some stuff', t => {
|
|
const tree = new Node({
|
|
path: '/some/path',
|
|
pkg: {},
|
|
children: [
|
|
{ pkg: { name: 'foo', version: '1.2.3' } },
|
|
{ pkg: { name: 'disowned', version: '1.2.3' } },
|
|
],
|
|
})
|
|
new Link({
|
|
parent: tree,
|
|
name: 'glorb',
|
|
target: new Node({
|
|
fsParent: tree,
|
|
path: '/some/path/glorb',
|
|
pkg: { name: 'glorb', version: '1.2.3' },
|
|
}),
|
|
})
|
|
const disowned = tree.children.get('disowned')
|
|
disowned.parent = null
|
|
|
|
// oops...
|
|
Map.prototype.set.call(tree.inventory, 'xyz', disowned)
|
|
t.equal(treeCheck(tree, false), tree, 'unreachable allowed')
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'unreachable in inventory',
|
|
node: resolve('/some/path/node_modules/disowned'),
|
|
realpath: resolve('/some/path/node_modules/disowned'),
|
|
location: '',
|
|
name: 'Error',
|
|
log: Array,
|
|
})
|
|
|
|
Map.prototype.delete.call(tree.inventory, 'xyz')
|
|
disowned.parent = tree
|
|
tree.inventory.delete(disowned)
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'not in inventory',
|
|
node: resolve('/some/path/node_modules/disowned'),
|
|
name: 'Error',
|
|
log: Array,
|
|
})
|
|
|
|
disowned.root = null
|
|
tree.children.set('wtf', disowned)
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'double root',
|
|
node: resolve('/some/path/node_modules/disowned'),
|
|
realpath: resolve('/some/path/node_modules/disowned'),
|
|
tree: tree.path,
|
|
name: 'Error',
|
|
log: Array,
|
|
})
|
|
|
|
const otherTree = new Node({
|
|
name: 'other',
|
|
parent: disowned,
|
|
})
|
|
tree.children.set('wtf', otherTree)
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'node from other root in tree',
|
|
node: resolve('/some/path/node_modules/disowned/node_modules/other'),
|
|
realpath: resolve('/some/path/node_modules/disowned/node_modules/other'),
|
|
tree: tree.path,
|
|
name: 'Error',
|
|
log: Array,
|
|
})
|
|
|
|
tree.children.delete('wtf')
|
|
Map.prototype.set.call(otherTree.inventory, 'othertree', disowned)
|
|
t.throws(() => treeCheck(otherTree), {
|
|
message: 'non-root has non-zero inventory',
|
|
node: disowned.path,
|
|
tree: otherTree.path,
|
|
inventory: [[disowned.path, disowned.location]],
|
|
name: 'Error',
|
|
log: Array,
|
|
})
|
|
Map.prototype.delete.call(tree.inventory, 'othertree')
|
|
|
|
t.end()
|
|
})
|
|
|
|
t.test('just return the tree if not in debug mode', t => {
|
|
const treeCheck = t.mock('../lib/tree-check.js', {
|
|
'../lib/debug.js': () => {},
|
|
})
|
|
const tree = new Node({
|
|
path: '/some/path',
|
|
pkg: {},
|
|
children: [
|
|
{ pkg: { name: 'foo', version: '1.2.3' } },
|
|
{ pkg: { name: 'disowned', version: '1.2.3' } },
|
|
],
|
|
})
|
|
const disowned = tree.children.get('disowned')
|
|
disowned.parent = null
|
|
// oops...
|
|
Map.prototype.set.call(tree.inventory, 'xyz', disowned)
|
|
t.equal(treeCheck(tree), tree, 'error suppressed outside of debug mode')
|
|
t.end()
|
|
})
|
|
|
|
t.test('tree with dev edges on a nested dep node', t => {
|
|
const tree = new Node({
|
|
path: '/some/path',
|
|
pkg: {},
|
|
children: [
|
|
{ pkg: { name: 'foo', version: '1.2.3', devDependencies: { x: '' } } },
|
|
],
|
|
})
|
|
// ensure it actually gets added
|
|
new Edge({
|
|
type: 'dev',
|
|
name: 'x',
|
|
spec: '',
|
|
from: tree.children.get('foo'),
|
|
})
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'dev edges on non-top node',
|
|
node: tree.children.get('foo').path,
|
|
tree: tree.path,
|
|
root: tree.root.path,
|
|
via: tree.path,
|
|
viaType: 'children',
|
|
devEdges: [['dev', 'x', '', 'MISSING']],
|
|
log: Array,
|
|
})
|
|
t.end()
|
|
})
|
|
|
|
t.test('node with same path as root', t => {
|
|
const root = new Node({
|
|
path: '/path/to/root',
|
|
pkg: {
|
|
dependencies: {
|
|
foo: '1',
|
|
},
|
|
},
|
|
})
|
|
const tree = new Node({
|
|
parent: root,
|
|
pkg: {
|
|
name: 'foo',
|
|
version: '1.2.3',
|
|
},
|
|
})
|
|
const child = new Node({
|
|
parent: tree,
|
|
pkg: {
|
|
name: 'not-root',
|
|
version: '1.2.3',
|
|
},
|
|
})
|
|
child.path = root.path
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'node with same path as root',
|
|
node: child.path,
|
|
tree: tree.path,
|
|
root: root.path,
|
|
via: tree.path,
|
|
viaType: 'children',
|
|
log: Array,
|
|
})
|
|
child.path = root.path + '/some/where/else'
|
|
t.throws(() => treeCheck(tree), {
|
|
message: 'non-link with mismatched path/realpath',
|
|
node: child.path,
|
|
tree: tree.path,
|
|
root: root.path,
|
|
via: tree.path,
|
|
viaType: 'children',
|
|
log: Array,
|
|
})
|
|
t.end()
|
|
})
|