tor-browser

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

observable-inspect.any.js (11471B)


      1 // Because we test that the global error handler is called at various times.
      2 setup({ allow_uncaught_exception: true });
      3 
      4 test(() => {
      5  const results = [];
      6  let sourceSubscriptionCall = 0;
      7  const source = new Observable(subscriber => {
      8    sourceSubscriptionCall++;
      9    results.push(`source subscribe ${sourceSubscriptionCall}`);
     10    subscriber.next(1);
     11    subscriber.next(2);
     12    subscriber.next(3);
     13    subscriber.complete();
     14  });
     15 
     16  let inspectSubscribeCall = 0;
     17  const result = source.inspect({
     18    subscribe: () => {
     19      inspectSubscribeCall++;
     20      results.push(`inspect() subscribe ${inspectSubscribeCall}`);
     21    },
     22    next: (value) => results.push(`inspect() next ${value}`),
     23    error: () => results.push('inspect() error'),
     24    complete: () => results.push('inspect() complete'),
     25  });
     26 
     27  result.subscribe({
     28    next: (value) => results.push(`result next ${value}`),
     29    error: () => results.push('result error'),
     30    complete: () => results.push('result complete'),
     31  });
     32 
     33  result.subscribe({
     34    next: (value) => results.push(`result next ${value}`),
     35    error: () => results.push('result error'),
     36    complete: () => results.push('result complete'),
     37  });
     38 
     39  assert_array_equals(results,
     40    [
     41      "inspect() subscribe 1",
     42      "source subscribe 1",
     43      "inspect() next 1",
     44      "result next 1",
     45      "inspect() next 2",
     46      "result next 2",
     47      "inspect() next 3",
     48      "result next 3",
     49      "inspect() complete",
     50      "result complete",
     51      "inspect() subscribe 2",
     52      "source subscribe 2",
     53      "inspect() next 1",
     54      "result next 1",
     55      "inspect() next 2",
     56      "result next 2",
     57      "inspect() next 3",
     58      "result next 3",
     59      "inspect() complete",
     60      "result complete",
     61    ]);
     62 }, "inspect(): Provides a pre-subscription subscribe callback");
     63 
     64 test(() => {
     65  const source = new Observable(subscriber => {
     66    subscriber.next(1);
     67    subscriber.next(2);
     68    subscriber.next(3);
     69    subscriber.complete();
     70  });
     71 
     72  const results = [];
     73 
     74  const result = source.inspect({
     75    next: value => results.push(value),
     76    error: e => results.push(e),
     77    complete: () => results.push("complete"),
     78  });
     79 
     80  result.subscribe();
     81  result.subscribe();
     82 
     83  assert_array_equals(results, [1, 2, 3, "complete", 1, 2, 3, "complete"]);
     84 }, "inspect(): Provides a way to tap into the values and completions of the " +
     85   "source observable using an observer");
     86 
     87 test(() => {
     88  const error = new Error("error from source");
     89  const source = new Observable(subscriber => subscriber.error(error));
     90 
     91  const results = [];
     92 
     93  const result = source.inspect({
     94    next: value => results.push(value),
     95    error: e => results.push(e),
     96    complete: () => results.push("complete"),
     97  });
     98 
     99  let errorReported = null;
    100  self.addEventListener('error', e => errorReported = e.error, {once: true});
    101  result.subscribe();
    102 
    103  assert_array_equals(results, [error]);
    104  assert_equals(errorReported, error,
    105      "errorReported to global matches error from source Observable");
    106 }, "inspect(): Error handler does not stop error from being reported to the " +
    107   "global, when subscriber does not pass error handler");
    108 
    109 test(() => {
    110  const error = new Error("error from source");
    111  const source = new Observable(subscriber => {
    112    subscriber.next(1);
    113    subscriber.next(2);
    114    subscriber.next(3);
    115    subscriber.error(error);
    116  });
    117 
    118  const results = [];
    119 
    120  const result = source.inspect({
    121    next: value => results.push(value),
    122    error: e => results.push(e),
    123    complete: () => results.push("complete"),
    124  });
    125 
    126  const observer = {
    127    error: e => results.push(e),
    128  };
    129  result.subscribe(observer);
    130  result.subscribe(observer);
    131 
    132  assert_array_equals(results, [1, 2, 3, error, error, 1, 2, 3, error, error]);
    133 }, "inspect(): Provides a way to tap into the values and errors of the " +
    134   "source observable using an observer. Errors are passed through");
    135 
    136 test(() => {
    137  const source = new Observable(subscriber => {
    138    subscriber.next(1);
    139    subscriber.next(2);
    140    subscriber.next(3);
    141    subscriber.complete();
    142  });
    143 
    144  const results = [];
    145 
    146  const result = source.inspect(value => results.push(value));
    147 
    148  result.subscribe();
    149  result.subscribe();
    150 
    151  assert_array_equals(results, [1, 2, 3, 1, 2, 3]);
    152 }, "inspect(): ObserverCallback passed in");
    153 
    154 test(() => {
    155  const source = new Observable(subscriber => {
    156    subscriber.next(1);
    157    subscriber.next(2);
    158    subscriber.next(3);
    159  });
    160 
    161  const error = new Error("error from inspect() next handler");
    162  const result = source.inspect({
    163    next: (value) => {
    164      if (value === 2) {
    165        throw error;
    166      }
    167    },
    168  });
    169 
    170  const results1 = [];
    171  result.subscribe({
    172    next: (value) => results1.push(value),
    173    error: (e) => results1.push(e),
    174    complete: () => results1.push("complete"),
    175  });
    176 
    177  const results2 = [];
    178  result.subscribe({
    179    next: (value) => results2.push(value),
    180    error: (e) => results2.push(e),
    181    complete: () => results2.push("complete"),
    182  });
    183 
    184  assert_array_equals(results1, [1, error]);
    185  assert_array_equals(results2, [1, error]);
    186 }, "inspect(): Throwing an error in the observer next handler is caught and " +
    187   "sent to the error callback of the result observable");
    188 
    189 test(() => {
    190  const sourceError = new Error("error from source");
    191  const inspectError = new Error("error from inspect() error handler");
    192 
    193  const source = new Observable(subscriber => {
    194    subscriber.error(sourceError);
    195  });
    196 
    197  const result = source.inspect({
    198    error: () => {
    199      throw inspectError;
    200    },
    201  });
    202 
    203  const results = [];
    204  result.subscribe({
    205    next: () => results.push("next"),
    206    error: (e) => results.push(e),
    207    complete: () => results.push("complete"),
    208  });
    209 
    210  assert_array_equals(results, [inspectError]);
    211 }, "inspect(): Throwing an error in the observer error handler in " +
    212   "inspect() is caught and sent to the error callback of the result " +
    213   "observable");
    214 
    215 test(() => {
    216  const source = new Observable(subscriber => {
    217    subscriber.next(1);
    218    subscriber.next(2);
    219    subscriber.next(3);
    220    subscriber.complete();
    221  });
    222 
    223  const error = new Error("error from inspect() complete handler");
    224  const result = source.inspect({
    225    complete: () => {
    226      throw error;
    227    },
    228  });
    229 
    230  const results = [];
    231  result.subscribe({
    232    next: (value) => results.push(value),
    233    error: (e) => results.push(e),
    234    complete: () => results.push("complete"),
    235  });
    236 
    237  assert_array_equals(results, [1, 2, 3, error]);
    238 }, "inspect(): Throwing an error in the observer complete handler is caught " +
    239   "and sent to the error callback of the result observable");
    240 
    241 test(() => {
    242  const source = new Observable(subscriber => {
    243    subscriber.next(1);
    244    subscriber.next(2);
    245    subscriber.next(3);
    246  });
    247 
    248  const error = new Error("error from inspect() next handler");
    249  const result = source.inspect({
    250    next: (value) => {
    251      if (value === 2) {
    252        throw error;
    253      }
    254    },
    255  });
    256 
    257  const results = [];
    258  result.subscribe({
    259    next: (value) => results.push(value),
    260    error: (e) => results.push(e),
    261    complete: () => results.push("complete"),
    262  });
    263 
    264  assert_array_equals(results, [1, error]);
    265 }, "inspect(): Throwing an error in the next handler function in do should " +
    266   "be caught and sent to the error callback of the result observable");
    267 
    268 test(() => {
    269  const source = new Observable(subscriber => {});
    270  const error = new Error("error from do subscribe handler");
    271 
    272  const result = source.inspect({
    273    subscribe: () => {
    274      throw error;
    275    },
    276  });
    277 
    278  const results = [];
    279  result.subscribe({
    280    next: () => results.push("next"),
    281    error: (e) => results.push(e),
    282    complete: () => results.push("complete"),
    283  });
    284 
    285  assert_array_equals(results, [error]);
    286 }, "inspect(): Errors thrown in subscribe() Inspector handler subscribe " +
    287   "handler are caught and sent to error callback");
    288 
    289 test(() => {
    290  const results = [];
    291  let sourceTeardownCall = 0;
    292  const source = new Observable(subscriber => {
    293    subscriber.addTeardown(() => {
    294      sourceTeardownCall++;
    295      results.push(`source teardown ${sourceTeardownCall}`);
    296    });
    297    subscriber.next(1);
    298    subscriber.next(2);
    299    subscriber.next(3);
    300    subscriber.complete();
    301  });
    302 
    303  let doUnsubscribeCall = 0;
    304  const result = source.inspect({
    305    abort: (reason) => {
    306      doUnsubscribeCall++;
    307      results.push(`inspect() abort ${doUnsubscribeCall} ${reason}`);
    308    },
    309    next: (value) => results.push(`inspect() next ${value}`),
    310    error: () => results.push('inspect() error'),
    311    complete: () => results.push(`inspect() complete`),
    312  });
    313 
    314  const controller = new AbortController();
    315  result.subscribe({
    316    next: (value) => {
    317      results.push(`result next ${value}`);
    318      if (value === 2) {
    319        controller.abort("abort reason");
    320      }
    321    },
    322    error: () => results.push('result error'),
    323    complete: () => results.push(`result complete`),
    324  }, { signal: controller.signal });
    325 
    326  assert_array_equals(results, [
    327    "inspect() next 1",
    328    "result next 1",
    329    "inspect() next 2",
    330    "result next 2",
    331    "inspect() abort 1 abort reason",
    332    "source teardown 1",
    333  ]);
    334 }, "inspect(): Provides a way to tap into the moment a source observable is unsubscribed from");
    335 
    336 test(() => {
    337  const results = [];
    338  let sourceTeardownCall = 0;
    339  const source = new Observable(subscriber => {
    340    subscriber.addTeardown(() => {
    341      sourceTeardownCall++;
    342      results.push(`source teardown ${sourceTeardownCall}`);
    343    });
    344    subscriber.next(1);
    345    subscriber.next(2);
    346    subscriber.next(3);
    347    subscriber.complete();
    348  });
    349 
    350  let inspectUnsubscribeCall = 0;
    351  const result = source.inspect({
    352    next: (value) => results.push(`inspect() next ${value}`),
    353    complete: () => results.push(`inspect() complete`),
    354    abort: (reason) => {
    355      inspectUnsubscribeCall++;
    356      results.push(`inspect() abort ${inspectUnsubscribeCall} ${reason}`);
    357    },
    358  });
    359 
    360  result.subscribe({
    361    next: (value) => results.push(`result next ${value}`),
    362    complete: () => results.push(`result complete`),
    363  });
    364 
    365  assert_array_equals(results, [
    366    "inspect() next 1",
    367    "result next 1",
    368    "inspect() next 2",
    369    "result next 2",
    370    "inspect() next 3",
    371    "result next 3",
    372    "source teardown 1",
    373    "inspect() complete",
    374    "result complete",
    375  ]);
    376 }, "inspect(): Inspector abort() handler is not called if the source " +
    377   "completes before the result is unsubscribed from");
    378 
    379 test(() => {
    380  const source = new Observable(subscriber => {
    381    subscriber.next(1);
    382  });
    383 
    384  const results = [];
    385  const error = new Error("error from inspect() subscribe handler");
    386 
    387  const result = source.inspect({
    388    abort: () => {
    389      results.push("abort() handler run");
    390      throw error;
    391    },
    392  });
    393 
    394  const controller = new AbortController();
    395 
    396  self.when("error").take(1).subscribe((e) => {
    397    results.push("from report exception");
    398    results.push(e.error);
    399  });
    400 
    401  result.subscribe({
    402    next: (value) => {
    403      results.push(value);
    404      controller.abort();
    405    },
    406    error: () => {
    407      assert_unreached("This should not be invoked at all!!");
    408    },
    409    complete: () => results.push("complete"),
    410  }, { signal: controller.signal });
    411 
    412  assert_array_equals(results, [
    413    1,
    414    "abort() handler run",
    415    "from report exception",
    416    error,
    417  ]);
    418 }, "inspect(): Errors thrown from inspect()'s abort() handler are caught " +
    419   "and reported to the global, because the subscription is already closed " +
    420   "by the time the handler runs");