tor-browser

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

iterator-zip-iteration.js (3808B)


      1 // Copyright (C) 2025 André Bargull. All rights reserved.
      2 // This code is governed by the BSD license found in the LICENSE file.
      3 
      4 /*---
      5 esid: sec-iterator.zipkeyed
      6 description: >
      7  Perform iteration in IteratorZip.
      8 info: |
      9  Iterator.zipKeyed ( iterables [ , options ] )
     10    ...
     11    16. Return IteratorZip(iters, mode, padding, finishResults).
     12 
     13  IteratorZip ( iters, mode, padding, finishResults )
     14    3. Let closure be a new Abstract Closure with no parameters that captures
     15       iters, iterCount, openIters, mode, padding, and finishResults, and
     16       performs the following steps when called:
     17      ...
     18      b. Repeat,
     19        ...
     20        iii. For each integer i such that 0 ≤ i < iterCount, in ascending order, do
     21          ...
     22          3. Else,
     23            a. Let result be Completion(IteratorStepValue(iter)).
     24          ...
     25 includes: [compareArray.js]
     26 features: [joint-iteration]
     27 ---*/
     28 
     29 var modes = [
     30  "shortest",
     31  "longest",
     32  "strict",
     33 ];
     34 
     35 function makeIterator(log, name, elements) {
     36  var elementsIter = elements.values();
     37  var iterator = {
     38    next() {
     39      log.push(`call ${name} next`);
     40 
     41      // Called with the correct receiver and no arguments.
     42      assert.sameValue(this, iterator);
     43      assert.sameValue(arguments.length, 0);
     44 
     45      var result = elementsIter.next();
     46      return {
     47        get done() {
     48          log.push(`get ${name}.result.done`);
     49          return result.done;
     50        },
     51        get value() {
     52          log.push(`get ${name}.result.value`);
     53          return result.value;
     54        },
     55      };
     56    },
     57    return() {
     58      log.push(`call ${name} return`);
     59 
     60      // Called with the correct receiver and no arguments.
     61      assert.sameValue(this, iterator);
     62      assert.sameValue(arguments.length, 0);
     63 
     64      return {
     65        get done() {
     66          log.push(`unexpected get ${name}.result.done`);
     67          return result.done;
     68        },
     69        get value() {
     70          log.push(`unexpected get ${name}.result.value`);
     71          return result.value;
     72        },
     73      };
     74    }
     75  };
     76  return iterator;
     77 }
     78 
     79 for (var mode of modes) {
     80  var log = [];
     81  var iterables = {
     82    first: makeIterator(log, "first", [1, 2, 3]),
     83    second: makeIterator(log, "second", [4, 5, 6]),
     84    third: makeIterator(log, "third", [7, 8, 9]),
     85  };
     86  var it = Iterator.zipKeyed(iterables, {mode});
     87 
     88  log.push("start");
     89  for (var v of it) {
     90    log.push("loop");
     91  }
     92 
     93  var expected = [
     94    "start",
     95 
     96    "call first next",
     97      "get first.result.done",
     98      "get first.result.value",
     99    "call second next",
    100      "get second.result.done",
    101      "get second.result.value",
    102    "call third next",
    103      "get third.result.done",
    104      "get third.result.value",
    105    "loop",
    106 
    107    "call first next",
    108      "get first.result.done",
    109      "get first.result.value",
    110    "call second next",
    111      "get second.result.done",
    112      "get second.result.value",
    113    "call third next",
    114      "get third.result.done",
    115      "get third.result.value",
    116    "loop",
    117 
    118    "call first next",
    119      "get first.result.done",
    120      "get first.result.value",
    121    "call second next",
    122      "get second.result.done",
    123      "get second.result.value",
    124    "call third next",
    125      "get third.result.done",
    126      "get third.result.value",
    127    "loop",
    128  ];
    129 
    130  switch (mode) {
    131    case "shortest": {
    132      expected.push(
    133        "call first next",
    134          "get first.result.done",
    135        "call third return",
    136        "call second return",
    137      );
    138      break;
    139    }
    140    case "longest":
    141    case "strict": {
    142      expected.push(
    143        "call first next",
    144          "get first.result.done",
    145        "call second next",
    146          "get second.result.done",
    147        "call third next",
    148          "get third.result.done",
    149      );
    150      break;
    151    }
    152  }
    153 
    154  assert.compareArray(log, expected);
    155 }
    156 
    157 reportCompare(0, 0);