| 'use strict'; |
| // Flags: --expose-internals |
| |
| const common = require('../common'); |
| |
| if (!common.hasCrypto) common.skip('missing crypto'); |
| common.requireNoPackageJSONAbove(); |
| |
| const Manifest = require('internal/policy/manifest').Manifest; |
| |
| |
| const assert = require('assert'); |
| |
| const { debuglog } = require('util'); |
| const debug = debuglog('test'); |
| |
| const conditionTreePermutations = [ |
| ['default'], |
| ['import'], |
| ['node'], |
| ['require'], |
| ['require', 'import'], |
| ['import', 'require'], |
| ['default', 'require'], |
| ['require', 'default'], |
| ['node', 'require'], |
| ['require', 'node'], |
| ]; |
| for (const totalDepth of [1, 2, 3]) { |
| const conditionTrees = []; |
| function calc(depthLeft = 0, path = []) { |
| if (depthLeft) { |
| for (const conditions of conditionTreePermutations) { |
| calc(depthLeft - 1, [...path, conditions]); |
| } |
| } else { |
| conditionTrees.push(path); |
| } |
| } |
| calc(totalDepth, []); |
| let nextURLId = 1; |
| function getUniqueHREF() { |
| const id = nextURLId++; |
| return `test:${id}`; |
| } |
| for (const tree of conditionTrees) { |
| const root = {}; |
| const targets = [root]; |
| const offsets = [-1]; |
| const order = []; |
| while (offsets.length) { |
| const depth = offsets.length - 1; |
| offsets[depth]++; |
| const conditionOffset = offsets[depth]; |
| const conditionsForDepth = tree[depth]; |
| if (conditionOffset >= conditionsForDepth.length) { |
| offsets.pop(); |
| continue; |
| } |
| let target; |
| if (depth === tree.length - 1) { |
| target = getUniqueHREF(); |
| order.push({ |
| target, |
| conditions: new Set( |
| offsets.map( |
| (conditionOffset, depth) => tree[depth][conditionOffset] |
| ) |
| ) |
| }); |
| } else { |
| target = {}; |
| targets[depth + 1] = target; |
| offsets.push(-1); |
| } |
| const condition = tree[depth][conditionOffset]; |
| targets[depth][condition] = target; |
| } |
| const manifest = new Manifest({ |
| resources: { |
| 'test:_': { |
| dependencies: { |
| _: root |
| } |
| } |
| } |
| }); |
| const redirector = manifest.getDependencyMapper('test:_'); |
| for (const { target, conditions } of order) { |
| const result = redirector.resolve('_', conditions).href; |
| if (result !== target) { |
| // If we didn't hit the target, make sure a target prior to this one |
| // matched, including conditions |
| searchPriorTargets: |
| for (const { target: preTarget, conditions: preConditions } of order) { |
| if (result === preTarget) { |
| // Ensure that the current conditions are a super set of the |
| // prior target |
| for (const preCondition of preConditions) { |
| if (conditions.has(preCondition) !== true) { |
| continue searchPriorTargets; |
| } |
| } |
| break searchPriorTargets; |
| } |
| if (preTarget === target) { |
| debug( |
| 'dependencies %O expected ordering %O and trying for %j ' + |
| 'no prior targets matched', |
| root, |
| order, |
| target |
| ); |
| // THIS WILL ALWAYS FAIL, but we want that error message |
| assert.strictEqual( |
| result, target |
| ); |
| } |
| } |
| } |
| } |
| } |
| } |