tor-browser

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

observable-take.any.js (4186B)


      1 test(() => {
      2  const results = [];
      3  const source = new Observable(subscriber => {
      4    subscriber.addTeardown(() => results.push("source teardown"));
      5    subscriber.next(1);
      6    subscriber.next(2);
      7    subscriber.next(3);
      8    subscriber.complete();
      9  });
     10 
     11  const result = source.take(2);
     12 
     13  result.subscribe({
     14    next: v => results.push(v),
     15    error: e => results.push(e),
     16    complete: () => results.push("complete"),
     17  });
     18 
     19  assert_array_equals(results, [1, 2, "source teardown", "complete"]);
     20 }, "take(): Takes the first N values from the source observable, then completes");
     21 
     22 test(() => {
     23  const results = [];
     24  const source = new Observable(subscriber => {
     25    subscriber.addTeardown(() => results.push("source teardown"));
     26    subscriber.next(1);
     27    subscriber.next(2);
     28    subscriber.next(3);
     29    subscriber.complete();
     30  });
     31 
     32  const result = source.take(5);
     33 
     34  result.subscribe({
     35    next: v => results.push(v),
     36    error: e => results.push(e),
     37    complete: () => results.push("complete"),
     38  });
     39 
     40  assert_array_equals(results, [1, 2, 3, "source teardown", "complete"],
     41      "complete() is immediately forwarded");
     42 }, "take(): Forwards complete()s that happen before the take count is met, " +
     43   "and unsubscribes from source Observable");
     44 
     45 test(() => {
     46  const results = [];
     47  const error = new Error('source error');
     48  const source = new Observable(subscriber => {
     49    subscriber.next(1);
     50    subscriber.error(error);
     51  });
     52 
     53  const result = source.take(100);
     54 
     55  result.subscribe({
     56    next: v => results.push(v),
     57    error: e => results.push(e),
     58    complete: () => results.push("complete"),
     59  });
     60 
     61  assert_array_equals(results, [1, error], "Errors are forwarded");
     62 }, "take(): Should forward errors from the source observable");
     63 
     64 test(() => {
     65  const results = [];
     66  const source = new Observable((subscriber) => {
     67    results.push("source subscribe");
     68    subscriber.next(1);
     69    subscriber.next(2);
     70    subscriber.next(3);
     71    subscriber.complete();
     72  });
     73 
     74  const result = source.take(0);
     75 
     76  result.subscribe({
     77    next: v => results.push(v),
     78    error: e => results.push(e),
     79    complete: () => results.push("complete"),
     80  });
     81 
     82  assert_array_equals(results, ["complete"]);
     83 }, "take(): take(0) should not subscribe to the source observable, and " +
     84   "should return an observable that immediately completes");
     85 
     86 test(() => {
     87  const results = [];
     88  const source = new Observable((subscriber) => {
     89    results.push("source subscribe");
     90    subscriber.next(1);
     91    subscriber.next(2);
     92    subscriber.next(3);
     93    subscriber.complete();
     94  });
     95 
     96  // Per WebIDL, `-1` passed into an `unsigned long long` gets wrapped around
     97  // into the maximum value (18446744073709551615), which means the `result`
     98  // Observable captures everything that `source` does.
     99  const result = source.take(-1);
    100 
    101  result.subscribe({
    102    next: v => results.push(v),
    103    error: e => results.push(e),
    104    complete: () => results.push("complete"),
    105  });
    106 
    107  assert_array_equals(results, ["source subscribe", 1, 2, 3, "complete"]);
    108 }, "take(): Negative count is treated as maximum value");
    109 
    110 // This tests a regression in Chromium's implementation. In ref-counted
    111 // producers, when Subscriber#next() is called, the Subscriber iterates over all
    112 // of its "internal observers" [1] and calls "next" on them. However, "next" can
    113 // complete the subscription, and modify the "internal observers" list while
    114 // Subscriber is iterating over it. This mutation-during-iteration caused a
    115 // crash regression in Chromium, which this test covers.
    116 //
    117 // [1]: https://wicg.github.io/observable/#subscriber-internal-observers
    118 promise_test(async () => {
    119  async function* asyncNumbers() {
    120    yield* [1,2,3,4];
    121  }
    122 
    123  const source = Observable.from(asyncNumbers());
    124  const results = [];
    125 
    126  source.take(1).toArray().then(result => results.push(result));
    127  await source.take(3).toArray().then(result => results.push(result));
    128 
    129  assert_equals(results.length, 2);
    130  assert_array_equals(results[0], [1]);
    131  assert_array_equals(results[1], [1, 2, 3]);
    132 }, "take(): No crash when take(1) unsubscribes from its source when next() " +
    133   "is called, and the Subscriber iterates over the rest of the Observables");