• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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