tor-browser

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

observable-map.any.js (5165B)


      1 test(() => {
      2  const results = [];
      3  const indices = [];
      4  const source = new Observable((subscriber) => {
      5    subscriber.next(1);
      6    subscriber.next(2);
      7    subscriber.next(3);
      8    subscriber.complete();
      9  });
     10 
     11  const mapped = source.map((value, i) => {
     12    indices.push(i);
     13    return value * 2;
     14  });
     15 
     16  assert_true(mapped instanceof Observable, "map() returns an Observable");
     17 
     18  assert_array_equals(results, [], "Does not map until subscribed (values)");
     19  assert_array_equals(indices, [], "Does not map until subscribed (indices)");
     20 
     21  mapped.subscribe({
     22    next: (value) => results.push(value),
     23    error: () => results.push('error'),
     24    complete: () => results.push('complete'),
     25  });
     26 
     27  assert_array_equals(results, [2, 4, 6, 'complete']);
     28  assert_array_equals(indices, [0, 1, 2]);
     29 }, "map(): Maps values correctly");
     30 
     31 test(() => {
     32  const error = new Error("error");
     33  const results = [];
     34  let teardownCalled = false;
     35 
     36  const source = new Observable((subscriber) => {
     37    subscriber.addTeardown(() => teardownCalled = true);
     38 
     39    subscriber.next(1);
     40    assert_false(teardownCalled,
     41        "Teardown not called until until map unsubscribes due to error");
     42    subscriber.next(2);
     43    assert_true(teardownCalled, "Teardown called once map unsubscribes due to error");
     44    assert_false(subscriber.active, "Unsubscription makes Subscriber inactive");
     45    subscriber.next(3);
     46    subscriber.complete();
     47  });
     48 
     49  const mapped = source.map((value) => {
     50    if (value === 2) {
     51      throw error;
     52    }
     53    return value * 2;
     54  });
     55 
     56  mapped.subscribe({
     57    next: (value) => results.push(value),
     58    error: (error) => results.push(error),
     59    complete: () => results.push("complete"),
     60  });
     61 
     62  assert_array_equals(results, [2, error],
     63      "Mapper errors are emitted to Observer error() handler");
     64 }, "map(): Mapper errors are emitted to Observer error() handler");
     65 
     66 test(() => {
     67  const source = new Observable(subscriber => {
     68    subscriber.next(1);
     69    subscriber.complete();
     70    subscriber.next(2);
     71  });
     72 
     73  let mapperCalls = 0;
     74  const results = [];
     75  source.map(v => {
     76    mapperCalls++;
     77    return v * 2;
     78  }).subscribe({
     79    next: v => results.push(v),
     80    error: e => results.push(e),
     81    complete: () => results.push('complete'),
     82  });
     83 
     84  assert_equals(mapperCalls, 1, "Mapper is not called after complete()");
     85  assert_array_equals(results, [2, "complete"]);
     86 }, "map(): Passes complete() through from source Observable");
     87 
     88 test(() => {
     89  const source = new Observable(subscriber => {
     90    subscriber.next(1);
     91    subscriber.error('error');
     92    subscriber.next(2);
     93  });
     94 
     95  let mapperCalls = 0;
     96  const results = [];
     97  source.map(v => {
     98    mapperCalls++;
     99    return v * 2;
    100  }).subscribe({
    101    next: v => results.push(v),
    102    error: e => results.push(e),
    103    complete: () => results.push('complete'),
    104  });
    105 
    106  assert_equals(mapperCalls, 1, "Mapper is not called after error()");
    107  assert_array_equals(results, [2, "error"]);
    108 }, "map(): Passes error() through from source Observable");
    109 
    110 // This is mostly ensuring that the ordering in
    111 // https://wicg.github.io/observable/#dom-subscriber-complete is consistent.
    112 //
    113 // That is, the `Subscriber#complete()` method *first* closes itself and signals
    114 // abort on its own `Subscriber#signal()` and *then* calls whatever supplied
    115 // completion algorithm exists. In the case of `map()`, the "supplied completion
    116 // algorithm" is simply a set of internal observer steps that call
    117 // `Subscriber#complete()` on the *outer* mapper's Observer. This means the
    118 // outer Observer is notified of completion *after* the source Subscriber's
    119 // signal is aborted / torn down.
    120 test(() => {
    121  const results = [];
    122  const source = new Observable(subscriber => {
    123    subscriber.addTeardown(() => results.push('source teardown'));
    124    subscriber.signal.addEventListener('abort',
    125        () => results.push('source abort event'));
    126 
    127    subscriber.complete();
    128  });
    129 
    130  source.map(() => results.push('mapper called')).subscribe({
    131    complete: () => results.push('map observable complete'),
    132  });
    133 
    134  assert_array_equals(results,
    135      ['source abort event', 'source teardown', 'map observable complete']);
    136 }, "map(): Upon source completion, source Observable teardown sequence " +
    137   "happens before downstream mapper complete() is called");
    138 
    139 test(() => {
    140  const results = [];
    141  let sourceSubscriber = null;
    142  const source = new Observable(subscriber => {
    143    subscriber.addTeardown(() => results.push('source teardown'));
    144    sourceSubscriber = subscriber;
    145 
    146    subscriber.next(1);
    147  });
    148 
    149  const controller = new AbortController();
    150  source.map(v => v * 2).subscribe({
    151    next: v => {
    152      results.push(v);
    153 
    154      // Triggers unsubscription to `source`.
    155      controller.abort();
    156 
    157      // Does nothing, since `source` is already torn down.
    158      sourceSubscriber.next(100);
    159    },
    160    complete: () => results.push('mapper complete'),
    161    error: e => results.push('mapper error'),
    162  }, {signal: controller.signal});
    163 
    164  assert_array_equals(results, [2, 'source teardown']);
    165 }, "map(): Map observable unsubscription causes source Observable " +
    166   "unsubscription. Mapper Observer's complete()/error() are not called");