tor-browser

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

observable-switchMap.any.js (6909B)


      1 test(() => {
      2  const source = createTestSubject();
      3  const inner1 = createTestSubject();
      4  const inner2 = createTestSubject();
      5 
      6  const result = source.switchMap((value, index) => {
      7    if (value === 1) {
      8      return inner1;
      9    }
     10    if (value === 2) {
     11      return inner2;
     12    }
     13    throw new Error("invalid ");
     14  });
     15 
     16  const results = [];
     17 
     18  result.subscribe({
     19    next: v => results.push(v),
     20    error: e => results.push(e),
     21    complete: () => results.push("complete"),
     22  });
     23 
     24  assert_equals(source.subscriberCount(), 1,
     25      "source observable is subscribed to");
     26 
     27  source.next(1);
     28  assert_equals(inner1.subscriberCount(), 1,
     29      "inner1 observable is subscribed to");
     30 
     31  inner1.next("1a");
     32  assert_array_equals(results, ["1a"]);
     33 
     34  inner1.next("1b");
     35  assert_array_equals(results, ["1a", "1b"]);
     36 
     37  source.next(2);
     38  assert_equals(inner1.subscriberCount(), 0,
     39      "inner1 observable is unsubscribed from");
     40  assert_equals(inner2.subscriberCount(), 1,
     41      "inner2 observable is subscribed to");
     42 
     43  inner2.next("2a");
     44  assert_array_equals(results, ["1a", "1b", "2a"]);
     45 
     46  inner2.next("2b");
     47  assert_array_equals(results, ["1a", "1b", "2a", "2b"]);
     48 
     49  inner2.complete();
     50  assert_array_equals(results, ["1a", "1b", "2a", "2b"]);
     51 
     52  source.complete();
     53  assert_array_equals(results, ["1a", "1b", "2a", "2b", "complete"]);
     54 }, "switchMap(): result subscribes to one inner observable at a time, " +
     55   "unsubscribing from the previous active one when a new one replaces it");
     56 
     57 test(() => {
     58  const source = createTestSubject();
     59  const inner = createTestSubject();
     60 
     61  const result = source.switchMap(() => inner);
     62 
     63  const results = [];
     64 
     65  result.subscribe({
     66    next: v => results.push(v),
     67    error: e => results.push(e),
     68    complete: () => results.push("complete"),
     69  });
     70 
     71  assert_equals(source.subscriberCount(), 1,
     72      "source observable is subscribed to");
     73  assert_equals(inner.subscriberCount(), 0,
     74      "inner observable is not subscribed to");
     75 
     76  source.next(1);
     77  assert_equals(inner.subscriberCount(), 1,
     78      "inner observable is subscribed to");
     79 
     80  inner.next("a");
     81  assert_array_equals(results, ["a"]);
     82 
     83  inner.next("b");
     84  assert_array_equals(results, ["a", "b"]);
     85 
     86  source.complete();
     87  assert_array_equals(results, ["a", "b"],
     88      "Result observable does not complete when source observable completes, " +
     89      "because inner is still active");
     90 
     91  inner.next("c");
     92  assert_array_equals(results, ["a", "b", "c"]);
     93 
     94  inner.complete();
     95  assert_array_equals(results, ["a", "b", "c", "complete"],
     96      "Result observable completes when inner observable completes, because " +
     97      "source is already complete");
     98 }, "switchMap(): result does not complete when the source observable " +
     99   "completes, if the inner observable is still active");
    100 
    101 test(() => {
    102  const source = createTestSubject();
    103 
    104  const e = new Error('thrown from mapper');
    105  const result = source.switchMap(() => {
    106    throw e;
    107  });
    108 
    109  const results = [];
    110 
    111  result.subscribe({
    112    next: v => results.push(v),
    113    error: e => results.push(e),
    114    complete: () => results.push("complete"),
    115  });
    116 
    117  assert_equals(source.subscriberCount(), 1,
    118      "source observable is subscribed to");
    119 
    120  source.next(1);
    121  assert_array_equals(results, [e]);
    122  assert_equals(source.subscriberCount(), 0,
    123      "source observable is unsubscribed from");
    124 }, "switchMap(): result emits an error if Mapper callback throws an error");
    125 
    126 test(() => {
    127  const source = createTestSubject();
    128  const inner = createTestSubject();
    129 
    130  const result = source.switchMap(() => inner);
    131 
    132  const results = [];
    133 
    134  result.subscribe({
    135    next: v => results.push(v),
    136    error: e => results.push(e),
    137    complete: () => results.push("complete"),
    138  });
    139 
    140  source.next(1);
    141  inner.next("a");
    142  assert_array_equals(results, ["a"]);
    143 
    144  const e = new Error('error from source');
    145  source.error(e);
    146  assert_array_equals(results, ["a", e],
    147      "switchMap result emits an error if the source emits an error");
    148  assert_equals(inner.subscriberCount(), 0,
    149      "inner observable is unsubscribed from");
    150  assert_equals(source.subscriberCount(), 0,
    151      "source observable is unsubscribed from");
    152 }, "switchMap(): result emits an error if the source observable emits an " +
    153   "error");
    154 
    155 test(() => {
    156  const source = createTestSubject();
    157  const inner = createTestSubject();
    158 
    159  const result = source.switchMap(() => inner);
    160 
    161  const results = [];
    162 
    163  result.subscribe({
    164    next: v => results.push(v),
    165    error: e => results.push(e),
    166    complete: () => results.push("complete"),
    167  });
    168 
    169  source.next(1);
    170  inner.next("a");
    171  assert_array_equals(results, ["a"]);
    172 
    173  const e = new Error("error from inner");
    174  inner.error(e);
    175  assert_array_equals(results, ["a", e],
    176      "result emits an error if the inner observable emits an error");
    177  assert_equals(inner.subscriberCount(), 0,
    178      "inner observable is unsubscribed from");
    179  assert_equals(source.subscriberCount(), 0,
    180      "source observable is unsubscribed from");
    181 }, "switchMap(): result emits an error if the inner observable emits an error");
    182 
    183 test(() => {
    184  const results = [];
    185  const source = new Observable(subscriber => {
    186    subscriber.next(1);
    187    subscriber.addTeardown(() => {
    188      results.push('source teardown');
    189    });
    190    subscriber.signal.onabort = e => {
    191      results.push('source onabort');
    192    };
    193  });
    194 
    195  const inner = new Observable(subscriber => {
    196    subscriber.addTeardown(() => {
    197      results.push('inner teardown');
    198    });
    199    subscriber.signal.onabort = () => {
    200      results.push('inner onabort');
    201    };
    202  });
    203 
    204  const result = source.switchMap(() => inner);
    205 
    206  const ac = new AbortController();
    207  result.subscribe({
    208    next: v => results.push(v),
    209    error: e => results.error(e),
    210    complete: () => results.complete("complete"),
    211  }, {signal: ac.signal});
    212 
    213  ac.abort();
    214  assert_array_equals(results, [
    215    "source onabort",
    216    "source teardown",
    217    "inner onabort",
    218    "inner teardown",
    219  ], "Unsubscription order is correct");
    220 }, "switchMap(): should unsubscribe in the correct order when user aborts " +
    221   "the subscription");
    222 
    223 // A helper function to create an Observable that can be externally controlled
    224 // and examined for testing purposes.
    225 function createTestSubject() {
    226  const subscribers = new Set();
    227  const subject = new Observable(subscriber => {
    228    subscribers.add(subscriber);
    229    subscriber.addTeardown(() => subscribers.delete(subscriber));
    230  });
    231 
    232  subject.next = value => {
    233    for (const subscriber of Array.from(subscribers)) {
    234      subscriber.next(value);
    235    }
    236  };
    237  subject.error = error => {
    238    for (const subscriber of Array.from(subscribers)) {
    239      subscriber.error(error);
    240    }
    241  };
    242  subject.complete = () => {
    243    for (const subscriber of Array.from(subscribers)) {
    244      subscriber.complete();
    245    }
    246  };
    247  subject.subscriberCount = () => {
    248    return subscribers.size;
    249  };
    250 
    251  return subject;
    252 }