1'use strict'; 2// Flags: --expose-internals 3 4const common = require('../common'); 5 6if (!common.hasCrypto) common.skip('missing crypto'); 7common.requireNoPackageJSONAbove(); 8 9const Manifest = require('internal/policy/manifest').Manifest; 10 11 12const assert = require('assert'); 13 14const { debuglog } = require('util'); 15const debug = debuglog('test'); 16 17const conditionTreePermutations = [ 18 ['default'], 19 ['import'], 20 ['node'], 21 ['require'], 22 ['require', 'import'], 23 ['import', 'require'], 24 ['default', 'require'], 25 ['require', 'default'], 26 ['node', 'require'], 27 ['require', 'node'], 28]; 29for (const totalDepth of [1, 2, 3]) { 30 const conditionTrees = []; 31 function calc(depthLeft = 0, path = []) { 32 if (depthLeft) { 33 for (const conditions of conditionTreePermutations) { 34 calc(depthLeft - 1, [...path, conditions]); 35 } 36 } else { 37 conditionTrees.push(path); 38 } 39 } 40 calc(totalDepth, []); 41 let nextURLId = 1; 42 function getUniqueHREF() { 43 const id = nextURLId++; 44 return `test:${id}`; 45 } 46 for (const tree of conditionTrees) { 47 const root = {}; 48 const targets = [root]; 49 const offsets = [-1]; 50 const order = []; 51 while (offsets.length) { 52 const depth = offsets.length - 1; 53 offsets[depth]++; 54 const conditionOffset = offsets[depth]; 55 const conditionsForDepth = tree[depth]; 56 if (conditionOffset >= conditionsForDepth.length) { 57 offsets.pop(); 58 continue; 59 } 60 let target; 61 if (depth === tree.length - 1) { 62 target = getUniqueHREF(); 63 order.push({ 64 target, 65 conditions: new Set( 66 offsets.map( 67 (conditionOffset, depth) => tree[depth][conditionOffset] 68 ) 69 ) 70 }); 71 } else { 72 target = {}; 73 targets[depth + 1] = target; 74 offsets.push(-1); 75 } 76 const condition = tree[depth][conditionOffset]; 77 targets[depth][condition] = target; 78 } 79 const manifest = new Manifest({ 80 resources: { 81 'test:_': { 82 dependencies: { 83 _: root 84 } 85 } 86 } 87 }); 88 const redirector = manifest.getDependencyMapper('test:_'); 89 for (const { target, conditions } of order) { 90 const result = redirector.resolve('_', conditions).href; 91 if (result !== target) { 92 // If we didn't hit the target, make sure a target prior to this one 93 // matched, including conditions 94 searchPriorTargets: 95 for (const { target: preTarget, conditions: preConditions } of order) { 96 if (result === preTarget) { 97 // Ensure that the current conditions are a super set of the 98 // prior target 99 for (const preCondition of preConditions) { 100 if (conditions.has(preCondition) !== true) { 101 continue searchPriorTargets; 102 } 103 } 104 break searchPriorTargets; 105 } 106 if (preTarget === target) { 107 debug( 108 'dependencies %O expected ordering %O and trying for %j ' + 109 'no prior targets matched', 110 root, 111 order, 112 target 113 ); 114 // THIS WILL ALWAYS FAIL, but we want that error message 115 assert.strictEqual( 116 result, target 117 ); 118 } 119 } 120 } 121 } 122 } 123} 124