152 lines
4.3 KiB
JavaScript
152 lines
4.3 KiB
JavaScript
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");
|