tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

params_builder.js (8357B)


      1 /**
      2 * AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
      3 **/import { mergeParams, mergeParamsChecked } from '../internal/params_utils.js';import { comparePublicParamsPaths, Ordering } from '../internal/query/compare.js';import { stringifyPublicParams } from '../internal/query/stringify_params.js';
      4 
      5 import { assert, mapLazy, objectEquals } from '../util/util.js';
      6 
      7 
      8 
      9 // ================================================================
     10 // "Public" ParamsBuilder API / Documentation
     11 // ================================================================
     12 
     13 /**
     14 * Provides doc comments for the methods of CaseParamsBuilder and SubcaseParamsBuilder.
     15 * (Also enforces rough interface match between them.)
     16 */
     17 
     18 
     19 
     20 
     21 
     22 
     23 
     24 
     25 
     26 
     27 
     28 
     29 
     30 
     31 
     32 
     33 
     34 
     35 
     36 
     37 
     38 
     39 
     40 
     41 
     42 
     43 
     44 
     45 
     46 
     47 
     48 
     49 
     50 
     51 
     52 
     53 
     54 
     55 
     56 
     57 
     58 
     59 
     60 
     61 
     62 
     63 
     64 
     65 
     66 
     67 
     68 
     69 
     70 
     71 
     72 
     73 
     74 
     75 
     76 
     77 
     78 
     79 /**
     80 * Determines the resulting parameter object type which would be generated by an object of
     81 * the given ParamsBuilder type.
     82 */
     83 
     84 
     85 
     86 
     87 
     88 
     89 
     90 
     91 
     92 // ================================================================
     93 // Implementation
     94 // ================================================================
     95 
     96 /**
     97 * Iterable over pairs of either:
     98 * - `[case params, Iterable<subcase params>]` if there are subcases.
     99 * - `[case params, undefined]` if not.
    100 */
    101 
    102 
    103 
    104 
    105 /**
    106 * Base class for `CaseParamsBuilder` and `SubcaseParamsBuilder`.
    107 */
    108 export class ParamsBuilderBase {
    109 
    110 
    111  constructor(cases) {
    112    this.cases = cases;
    113  }
    114 
    115  /**
    116   * Hidden from test files. Use `builderIterateCasesWithSubcases` to access this.
    117   */
    118 
    119 
    120 
    121 }
    122 
    123 /**
    124 * Calls the (normally hidden) `iterateCasesWithSubcases()` method.
    125 */
    126 export function builderIterateCasesWithSubcases(
    127 builder,
    128 caseFilter)
    129 {
    130 
    131 
    132 
    133 
    134  return builder.iterateCasesWithSubcases(caseFilter);
    135 }
    136 
    137 /**
    138 * Builder for combinatorial test **case** parameters.
    139 *
    140 * CaseParamsBuilder is immutable. Each method call returns a new, immutable object,
    141 * modifying the list of cases according to the method called.
    142 *
    143 * This means, for example, that the `unit` passed into `TestBuilder.params()` can be reused.
    144 */
    145 export class CaseParamsBuilder extends
    146 ParamsBuilderBase
    147 
    148 {
    149  *iterateCasesWithSubcases(caseFilter) {
    150    for (const caseP of this.cases(caseFilter)) {
    151      if (caseFilter) {
    152        // this.cases() only filters out cases which conflict with caseFilter. Now that we have
    153        // the final caseP, filter out cases which are missing keys that caseFilter requires.
    154        const ordering = comparePublicParamsPaths(caseP, caseFilter);
    155        if (ordering === Ordering.StrictSuperset || ordering === Ordering.Unordered) {
    156          continue;
    157        }
    158      }
    159 
    160      yield [caseP, undefined];
    161    }
    162  }
    163 
    164  [Symbol.iterator]() {
    165    return this.cases(null);
    166  }
    167 
    168  /** @inheritDoc */
    169  expandWithParams(
    170  expander)
    171  {
    172    const baseGenerator = this.cases;
    173    return new CaseParamsBuilder(function* (caseFilter) {
    174      for (const a of baseGenerator(caseFilter)) {
    175        for (const b of expander(a)) {
    176          if (caseFilter) {
    177            // If the expander generated any key-value pair that conflicts with caseFilter, skip.
    178            const kvPairs = Object.entries(b);
    179            if (kvPairs.some(([k, v]) => k in caseFilter && !objectEquals(caseFilter[k], v))) {
    180              continue;
    181            }
    182          }
    183 
    184          yield mergeParamsChecked(a, b);
    185        }
    186      }
    187    });
    188  }
    189 
    190  /** @inheritDoc */
    191  expand(
    192  key,
    193  expander)
    194  {
    195    const baseGenerator = this.cases;
    196    return new CaseParamsBuilder(function* (caseFilter) {
    197      for (const a of baseGenerator(caseFilter)) {
    198        assert(!(key in a), `New key '${key}' already exists in ${JSON.stringify(a)}`);
    199 
    200        for (const v of expander(a)) {
    201          // If the expander generated a value for this key that conflicts with caseFilter, skip.
    202          if (caseFilter && key in caseFilter) {
    203            if (!objectEquals(caseFilter[key], v)) {
    204              continue;
    205            }
    206          }
    207          yield { ...a, [key]: v };
    208        }
    209      }
    210    });
    211  }
    212 
    213  /** @inheritDoc */
    214  combineWithParams(
    215  newParams)
    216  {
    217    assertNotGenerator(newParams);
    218    const seenValues = new Set();
    219    for (const params of newParams) {
    220      const paramsStr = stringifyPublicParams(params);
    221      assert(!seenValues.has(paramsStr), `Duplicate entry in combine[WithParams]: ${paramsStr}`);
    222      seenValues.add(paramsStr);
    223    }
    224 
    225    return this.expandWithParams(() => newParams);
    226  }
    227 
    228  /** @inheritDoc */
    229  combine(
    230  key,
    231  values)
    232  {
    233    assertNotGenerator(values);
    234    const mapped = mapLazy(values, (v) => ({ [key]: v }));
    235    return this.combineWithParams(mapped);
    236  }
    237 
    238  /** @inheritDoc */
    239  filter(pred) {
    240    const baseGenerator = this.cases;
    241    return new CaseParamsBuilder(function* (caseFilter) {
    242      for (const a of baseGenerator(caseFilter)) {
    243        if (pred(a)) yield a;
    244      }
    245    });
    246  }
    247 
    248  /** @inheritDoc */
    249  unless(pred) {
    250    return this.filter((x) => !pred(x));
    251  }
    252 
    253  /**
    254   * "Finalize" the list of cases and begin defining subcases.
    255   * Returns a new SubcaseParamsBuilder. Methods called on SubcaseParamsBuilder
    256   * generate new subcases instead of new cases.
    257   */
    258  beginSubcases() {
    259    return new SubcaseParamsBuilder(this.cases, function* () {
    260      yield {};
    261    });
    262  }
    263 }
    264 
    265 /**
    266 * The unit CaseParamsBuilder, representing a single case with no params: `[ {} ]`.
    267 *
    268 * `punit` is passed to every `.params()`/`.paramsSubcasesOnly()` call, so `kUnitCaseParamsBuilder`
    269 * is only explicitly needed if constructing a ParamsBuilder outside of a test builder.
    270 */
    271 export const kUnitCaseParamsBuilder = new CaseParamsBuilder(function* () {
    272  yield {};
    273 });
    274 
    275 /**
    276 * Builder for combinatorial test _subcase_ parameters.
    277 *
    278 * SubcaseParamsBuilder is immutable. Each method call returns a new, immutable object,
    279 * modifying the list of subcases according to the method called.
    280 */
    281 export class SubcaseParamsBuilder extends
    282 ParamsBuilderBase
    283 
    284 {
    285 
    286 
    287  constructor(
    288  cases,
    289  generator)
    290  {
    291    super(cases);
    292    this.subcases = generator;
    293  }
    294 
    295  *iterateCasesWithSubcases(caseFilter) {
    296    for (const caseP of this.cases(caseFilter)) {
    297      if (caseFilter) {
    298        // this.cases() only filters out cases which conflict with caseFilter. Now that we have
    299        // the final caseP, filter out cases which are missing keys that caseFilter requires.
    300        const ordering = comparePublicParamsPaths(caseP, caseFilter);
    301        if (ordering === Ordering.StrictSuperset || ordering === Ordering.Unordered) {
    302          continue;
    303        }
    304      }
    305 
    306      const subcases = Array.from(this.subcases(caseP));
    307      if (subcases.length) {
    308        yield [
    309        caseP,
    310        subcases];
    311 
    312      }
    313    }
    314  }
    315 
    316  /** @inheritDoc */
    317  expandWithParams(
    318  expander)
    319  {
    320    const baseGenerator = this.subcases;
    321    return new SubcaseParamsBuilder(this.cases, function* (base) {
    322      for (const a of baseGenerator(base)) {
    323        for (const b of expander(mergeParams(base, a))) {
    324          yield mergeParamsChecked(a, b);
    325        }
    326      }
    327    });
    328  }
    329 
    330  /** @inheritDoc */
    331  expand(
    332  key,
    333  expander)
    334  {
    335    const baseGenerator = this.subcases;
    336    return new SubcaseParamsBuilder(this.cases, function* (base) {
    337      for (const a of baseGenerator(base)) {
    338        const before = mergeParams(base, a);
    339        assert(!(key in before), () => `Key '${key}' already exists in ${JSON.stringify(before)}`);
    340 
    341        for (const v of expander(before)) {
    342          yield { ...a, [key]: v };
    343        }
    344      }
    345    });
    346  }
    347 
    348  /** @inheritDoc */
    349  combineWithParams(
    350  newParams)
    351  {
    352    assertNotGenerator(newParams);
    353    return this.expandWithParams(() => newParams);
    354  }
    355 
    356  /** @inheritDoc */
    357  combine(
    358  key,
    359  values)
    360  {
    361    assertNotGenerator(values);
    362    return this.expand(key, () => values);
    363  }
    364 
    365  /** @inheritDoc */
    366  filter(pred) {
    367    const baseGenerator = this.subcases;
    368    return new SubcaseParamsBuilder(this.cases, function* (base) {
    369      for (const a of baseGenerator(base)) {
    370        if (pred(mergeParams(base, a))) yield a;
    371      }
    372    });
    373  }
    374 
    375  /** @inheritDoc */
    376  unless(pred) {
    377    return this.filter((x) => !pred(x));
    378  }
    379 }
    380 
    381 /** Assert an object is not a Generator (a thing returned from a generator function). */
    382 function assertNotGenerator(x) {
    383  if ('constructor' in x) {
    384    assert(
    385      x.constructor !== function* () {}().constructor,
    386      'Argument must not be a generator, as generators are not reusable'
    387    );
    388  }
    389 }