npm/workspaces/arborist/test/printable.js

441 lines
10 KiB
JavaScript

const t = require('tap')
const Node = require('../lib/node.js')
const Link = require('../lib/link.js')
const Edge = require('../lib/edge.js')
const printable = require('../lib/printable.js')
const util = require('util')
t.cleanSnapshot = str => str
// normalize paths
.split(process.cwd()).join('{CWD}')
.replace(/[A-Z]:/g, '')
.replace(/\\+/g, '/')
// FIXME: once we drop support to node10 we can remove some of this
.replace(/:\n? +/g, ':')
.replace(/\n +/g, '\n')
.replace(/\n\}/g, ' }')
.replace(/\n\]/g, ']')
.replace(/\n\[/g, '[')
.replace(/\n\{\n/g, ' { ')
.replace(/Map\([0-9]\)/g, 'Map')
.replace(/Set\([0-9]\)/g, 'Set')
.replace(/:\n *Map/g, ':Map')
.replace(/:\n *Set/g, ':Set')
.replace(/ArboristNode /g, '')
.replace(/Edge /g, '')
.replace(/ *([[\]{}]) */g, '$1')
t.test('printable Node', t => {
t.test('extraneous tree', t => {
const tree = new Node({
name: 'printable-node',
pkg: {
name: 'printable-node',
version: '1.1.1',
dependencies: { prod: '1.x', b: '', missing: '' },
},
path: '/home/user/projects/root',
realpath: '/home/user/projects/root',
children: [{
pkg: {
name: 'prod',
version: '1.2.3',
dependencies: { meta: '', b: '' },
peerDependencies: { peer: '' },
},
fsChildren: [{
realpath: '/home/user/projects/root/node_modules/prod/foo',
path: '/home/user/projects/root/node_modules/prod/foo',
name: 'foo',
pkg: { name: 'foo', version: '1.2.3', dependencies: { meta: '' } },
}, {
realpath: '/home/user/projects/root/node_modules/prod/bar',
path: '/home/user/projects/root/node_modules/prod/bar',
name: 'bar',
pkg: { name: 'bar', version: '1.0.0' },
}],
resolved: 'prod',
integrity: 'prod',
}, {
pkg: {
name: 'b',
version: '1.2.3',
},
resolved: 'b',
integrity: 'b',
}, {
pkg: {
name: 'c',
},
resolved: 'c',
integrity: 'c',
}],
})
tree.error = { code: 'ERR', path: '/' }
tree.edgesOut.get('prod').peerConflicted = true
t.matchSnapshot(util.inspect(tree, { depth: 6 }),
'should print human readable representation of node tree')
t.end()
})
t.test('variations', t => {
// manually tweaked variations in the tree to reach for
// possible different trees output
const tree = new Node({
name: 'variations',
pkg: {
name: 'variations',
version: '1.0.0',
dependencies: { a: '^1.0.0', b: '^1.0.0' },
},
extraneous: false,
path: '/home/user/projects/root',
realpath: '/home/user/projects/root',
})
// append nodes
const a = new Node({
name: 'a',
pkg: {
name: 'a',
version: '1.1.1',
},
path: '/home/users/projects/root/node_modules/a',
realpath: '/home/users/projects/root/node_modules/a',
parent: tree,
})
a.extraneous = false
a.dev = true
a.optional = true
a.getBundler = () => true
a.errors = [Object.assign(new Error('ERR'), { code: 'ERR' })]
const b = new Link({
name: 'b',
pkg: {
name: 'b',
version: '1.0.0',
},
optional: true,
path: '/home/users/projects/root/c-link',
realpath: '/home/users/projects/root/c',
parent: tree,
})
const c = new Node({
name: 'c',
pkg: { name: 'c', version: '1.0.0' },
path: '/home/user/projects/root/c',
realpath: '/home/user/projects/root/c',
fsParent: tree,
})
b.target = c
b.extraneous = false
b.dev = false
b.optional = false
b.peer = false
b.errors = [Object.assign(new Error('ERR'), {
code: 'ERR',
path: '/home/users/projects/root/node_modules/b',
})]
// another link to c
new Link({
name: 'd',
realpath: '/home/users/projects/root/c',
target: c,
parent: tree,
})
tree.error = a.errors[0]
t.matchSnapshot(util.inspect(tree, { depth: 6 }),
'should match non-extraneous tree representation')
t.end()
})
t.test('do not recurse forever', t => {
const flags = {
extraneous: false,
dev: false,
devOptional: false,
optional: false,
peer: false,
}
const tree = new Node({
name: 'recursive',
pkg: {
name: 'recursive',
version: '1.0.0',
dependencies: { a: '^1.0.0', b: '^1.0.0' },
},
path: '/home/user/projects/root',
realpath: '/home/user/projects/root',
...flags,
})
new Node({
name: 'a',
pkg: {
name: 'a',
version: '1.2.3',
},
parent: tree,
...flags,
})
const target = new Node({
fsParent: tree,
path: tree.path + '/b',
pkg: {
name: 'b',
version: '1.2.3',
dependencies: { c: '' },
},
...flags,
})
const c = new Node({
parent: target,
pkg: {
name: 'c',
version: '1.2.3',
dependencies: { b: '9.9.9999', notfound: '' },
},
...flags,
})
new Link({
parent: c,
target,
...flags,
})
new Link({
parent: tree,
target,
...flags,
})
const s = util.inspect(printable(tree), { depth: Infinity })
t.matchSnapshot(s)
t.end()
})
t.end()
})
t.test('virtual roots are shown with their sourceReference', t => {
const node = new Node({
path: '/foo/bar/baz',
pkg: {
name: 'baz',
version: '1.2.3',
},
})
const virtual = new Node({ sourceReference: node })
t.matchSnapshot(printable(virtual))
t.end()
})
t.test('broken links dont break the printing', t => {
const tree = new Node({
path: '/home/user/projects/root',
})
// a link with no target
const brokenLink = new Link({
name: 'devnull',
realpath: '/home/user/projects/root/no/thing/here',
parent: tree,
})
brokenLink.target.root = null
t.matchSnapshot(printable(tree))
t.end()
})
t.test('show workspaces in printable node output', t => {
const tree = new Node({
path: '/home/user/projects/root',
pkg: {
workspaces: ['packages/*'],
},
})
new Edge({
from: tree,
type: 'workspace',
name: 'a',
spec: 'file:/home/user/projects/root/packages/a',
})
new Edge({
from: tree,
type: 'workspace',
name: 'b',
spec: 'file:/home/user/projects/root/packages/b',
})
new Link({
pkg: {
name: 'a',
version: '1.2.3',
},
realpath: '/home/user/projects/root/packages/a',
parent: tree,
})
new Link({
pkg: {
name: 'b',
version: '1.2.3',
},
realpath: '/home/user/projects/root/packages/b',
parent: tree,
})
tree.workspaces = new Map([
['a', tree.children.get('a').realpath],
['b', tree.children.get('b').realpath],
])
t.matchSnapshot(printable(tree))
t.end()
})
t.test('show bundle/shrinkwrap info', t => {
const tree = new Node({
path: '/path/to/root',
pkg: {
name: 'root',
version: '1.2.3',
dependencies: {
bundler: '',
wrapper: '',
a: '1',
b: '2',
c: '3',
},
},
children: [
{
pkg: {
name: 'bundler',
version: '1.2.3',
bundleDependencies: ['a'],
dependencies: {
a: '1',
},
},
children: [
{
pkg: { name: 'a', version: '1.2.3' },
integrity: 'a123',
},
],
},
{
pkg: {
name: 'wrapper',
version: '1.2.3',
dependencies: {
a: '1',
},
_hasShrinkwrap: true,
},
hasShrinkwrap: true,
children: [
{
pkg: { name: 'a', version: '1.2.3' },
integrity: 'a123',
},
],
},
{
pkg: { name: 'a', version: '1.2.3' },
integrity: 'a123',
},
{
pkg: { name: 'c', version: '3.4.5', dependencies: { a: '1' } },
children: [
{
pkg: { name: 'a', version: '1.2.3' },
integrity: 'a123',
},
],
},
{
pkg: {
name: 'b',
version: '2.3.4',
dependencies: {
a: '1',
c: '2',
d: '3',
},
},
children: [
{ pkg: { name: 'a', version: '1.9.99' } },
{ pkg: { name: 'e', version: '2.3.4' }, integrity: 'y' },
{
pkg: {
name: 'c',
version: '2.3.4',
dependencies: { a: '2' },
},
children: [
{
pkg: {
name: 'a',
version: '2.3.99',
dependencies: { e: '2' },
},
integrity: 'a2399',
children: [
{ pkg: { name: 'e', version: '2.0.1' }, integrity: 'x' },
],
},
],
},
{
pkg: {
name: 'd',
version: '3.4.5',
dependencies: {
a: '3',
},
},
children: [{ pkg: { name: 'a', version: '3.4.5' } }],
},
],
},
{ pkg: { name: 'extraneous', version: '1.2.3' } },
],
})
t.matchSnapshot(printable(tree))
t.end()
})
t.test('show overrides', (t) => {
const flags = {
extraneous: false,
dev: false,
peer: false,
optional: false,
devOptional: false,
}
const tree = new Node({
path: '/some/path',
loadOverrides: true,
pkg: {
name: 'root',
version: '1.0.0',
dependencies: {
foo: '^1.0.0',
bar: '^1.0.0',
},
overrides: {
'foo@1': '2.0.0',
bar: '2.0.0',
},
},
children: [
{ pkg: { name: 'foo', version: '2.0.0' }, ...flags },
{ pkg: { name: 'bar', version: '2.0.0' }, ...flags },
],
...flags,
})
t.matchSnapshot(util.inspect(printable(tree), { depth: 5 }))
t.end()
})