File: observable-reduce.any.js

package info (click to toggle)
firefox-esr 140.5.0esr-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie-proposed-updates
  • size: 4,539,036 kB
  • sloc: cpp: 7,381,527; javascript: 6,388,905; ansic: 3,710,087; python: 1,393,776; xml: 628,165; asm: 426,918; java: 184,004; sh: 65,744; makefile: 19,302; objc: 13,059; perl: 12,912; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,226; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (152 lines) | stat: -rw-r--r-- 4,454 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
promise_test(async (t) => {
  const source = new Observable(subscriber => {
    subscriber.next(1);
    subscriber.next(2);
    subscriber.next(3);
    t.step_timeout(() => subscriber.complete(), 0);
  });

  const reducerArguments = [];

  const promiseToResult = source.reduce((acc, value, index) => {
    reducerArguments.push([acc, value, index]);
    return acc + value;
  }, 0);

  // The reducer should be called immediately when the source emits a value.
  assert_equals(reducerArguments.length, 3);
  assert_array_equals(reducerArguments[0], [0, 1, 0]);
  assert_array_equals(reducerArguments[1], [1, 2, 1]);
  assert_array_equals(reducerArguments[2], [3, 3, 2]);

  const result = await promiseToResult;
  assert_equals(result, 6);
}, "reduce(): Reduces the values of the Observable, starting with the " +
   "initial seed value");

promise_test(async (t) => {
  let error = new Error('from the source');
  const source = new Observable(subscriber => {
    subscriber.next(1);
    subscriber.error(error);
  });

  return promise_rejects_exactly(t, error, source.reduce((acc, value) => acc + value, 0));
}, "reduce(): Rejects if the source observable emits an error");

promise_test(async (t) => {
  const source = new Observable(subscriber => {
    subscriber.next(1);
    subscriber.next(2);
    subscriber.next(3);
    t.step_timeout(() => subscriber.complete(), 0);
  });

  const reducerArguments = [];

  const promiseToResult = source.reduce((acc, value, index) => {
    reducerArguments.push([acc, value, index]);
    return acc + value;
  });

  // The reducer should be called immediately when the source emits a value.
  assert_equals(reducerArguments.length, 2);
  assert_array_equals(reducerArguments[0], [1, 2, 1]);
  assert_array_equals(reducerArguments[1], [3, 3, 2]);

  const result = await promiseToResult;
  assert_equals(result, 6);
}, "reduce(): Seeds with the first value of the source, if no initial value " +
   "is provided");

promise_test(async (t) => {
  const logs = [];

  const source = new Observable(subscriber => {
    subscriber.addTeardown(() => logs.push('teardown'));
    logs.push('next 1');
    subscriber.next(1);
    logs.push('next 2');
    subscriber.next(2);
    logs.push('try to next 3');
    subscriber.next(3);
    logs.push('try to complete');
    subscriber.complete();
  });

  const error = new Error('from the reducer');

  const promiseToResult = source.reduce((acc, value) => {
    if (value === 2) {
      logs.push('throw error');
      throw error;
    }
    return acc + value;
  }, 0);

  await promise_rejects_exactly(t, error, promiseToResult);

  assert_array_equals(logs, [
    'next 1',
    'next 2',
    'throw error',
    'teardown',
    'try to next 3',
    'try to complete',
  ]);
}, "reduce(): Errors thrown in reducer reject the promise and abort the source");

promise_test(async () => {
  const source = new Observable(subscriber => {
    subscriber.complete();
  });

  const result = await source.reduce(() => 'reduced', 'seed');

  assert_equals(result, 'seed');
}, "reduce(): When source is empty, promise resolves with initial value");

promise_test(async (t) => {
  // This tests behavior that is analogous to `[].reduce(() => 'reduced')`,
  // which throws a TypeError.

  const source = new Observable(subscriber => {
    subscriber.complete();
  });

  return promise_rejects_js(t, TypeError, source.reduce(() => 'reduced'));
}, "reduce(): When source is empty, AND no seed value is provided, the " +
   "promise rejects with a TypeError");

promise_test(async (t) => {
  let tornDown = false;
  const source = new Observable((subscriber) => {
    subscriber.addTeardown(() => {
      tornDown = true;
    });
    // Waits forever.
  });

  const abortController = new AbortController();

  t.step_timeout(() => {
    abortController.abort();
    assert_true(tornDown);
  }, 0);

  return promise_rejects_dom(t, 'AbortError', source.reduce(() => 'reduced', 'seed', { signal: abortController.signal }));
}, "reduce(): Reject with an AbortError if the subscription is aborted " +
   "before the source completes");

promise_test(async () => {
  const source = new Observable(subscriber => {
    subscriber.complete();
  });

  const values = [{}, [], new Error("some error")];

  for (let value of values) {
    const result = await source.reduce(() => {}, value);
    assert_equals(result, value);
  }
}, "reduce(): Reduces the values for different objects");