diff --git a/lib/arborist/load-actual.js b/lib/arborist/load-actual.js index 0d260858d..f70983f87 100644 --- a/lib/arborist/load-actual.js +++ b/lib/arborist/load-actual.js @@ -430,7 +430,7 @@ module.exports = cls => class ActualLoader extends cls { if (d.dummy) { // it's a placeholder, so likely would not have loaded this dep, // unless another dep in the tree also needs it. - const depPath = `${p}/node_modules/${name}` + const depPath = normalize(`${p}/node_modules/${name}`) const cached = this[_cache].get(depPath) if (!cached || cached.dummy) { depPromises.push(this[_loadFSNode]({ diff --git a/test/arborist/load-actual.js b/test/arborist/load-actual.js index 0da044c5a..13203c402 100644 --- a/test/arborist/load-actual.js +++ b/test/arborist/load-actual.js @@ -422,3 +422,48 @@ t.test('load global space with link deps', async t => { }, }) }) + +t.test('no edge errors for nested deps', async t => { + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'a', + version: '1.0.0', + dependencies: { + b: '1.0.0', + }, + }), + node_modules: { + b: { + 'package.json': JSON.stringify({ + name: 'b', + version: '1.0.0', + dependencies: { + c: '1.0.0', + }, + }), + }, + c: { + 'package.json': JSON.stringify({ + name: 'c', + version: '1.0.0', + }), + }, + }, + }) + + // disable treeCheck since it prevents the original issue from occuring + const ArboristNoTreeCheck = t.mock('../../lib/arborist', { + '../../lib/tree-check.js': tree => tree, + }) + const loadActualNoTreeCheck = (path, opts) => + new ArboristNoTreeCheck({ path, ...opts }).loadActual(opts) + + const tree = await loadActualNoTreeCheck(path) + + // assert that no outgoing edges have errors + for (const node of tree.inventory.values()) { + for (const [name, edge] of node.edgesOut.entries()) { + t.equal(edge.error, null, `node ${node.name} has outgoing edge to ${name} with error ${edge.error}`) + } + } +})