Skip to content

Commit

Permalink
Bug 1889399 [wpt PR 45500] - DOM: Implement the last() Observable o…
Browse files Browse the repository at this point in the history
…perator, a=testonly

Automatic update from web-platform-tests
DOM: Implement the `last()` Observable operator

See WICG/observable#133. This CL implements the
`last()` operator which returns a Promise that resolves to the last
item that the source Observable emits, and rejects with a RangeError
if the Observable completes prematurely.

For WPTs:
Co-authored-by: [email protected]

[email protected]

Bug: 40282760
Change-Id: Id1ec2af152c288ae81dfe383dfa9a7f166cfb375
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5417373
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Dominic Farolino <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1282037}

--

wpt-commits: 66396b12b8f7aa4390fc9e6db826dfcec7f8ff2c
wpt-pr: 45500
  • Loading branch information
domfarolino authored and moz-wptsync-bot committed Apr 10, 2024
1 parent bf7db03 commit bd6cc68
Showing 1 changed file with 113 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
promise_test(async () => {
const source = new Observable(subscriber => {
// Never exposed to the `last()` promise.
subscriber.next(1);

subscriber.next(2);
subscriber.complete();
});

const value = await source.last();

assert_equals(value, 2);
}, "last(): Promise resolves to last value");

promise_test(async () => {
const error = new Error("error from source");
const source = new Observable(subscriber => {
subscriber.error(error);
});

let rejection = null;
try {
await source.last();
} catch (e) {
rejection = e;
}

assert_equals(rejection, error);
}, "last(): Promise rejects with emitted error");

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

let rejection = null;
try {
await source.last();
} catch (e) {
rejection = e;
}

assert_true(rejection instanceof RangeError,
"Promise rejects with RangeError");
assert_equals(rejection.message, "No values in Observable");
}, "last(): Promise rejects with RangeError when source Observable " +
"completes without emitting any values");

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

const controller = new AbortController();
const promise = source.last({ signal: controller.signal });

controller.abort();

let rejection = null;
try {
await promise;
} catch (e) {
rejection = e;
}

assert_true(rejection instanceof DOMException,
"Promise rejects with a DOMException for abortion");
assert_equals(rejection.name, "AbortError",
"Rejected with 'AbortError' DOMException");
assert_equals(rejection.message, "signal is aborted without reason");
}, "last(): Aborting a signal rejects the Promise with an AbortError DOMException");

promise_test(async () => {
const results = [];
const source = new Observable(subscriber => {
results.push("source subscribe");
subscriber.addTeardown(() => results.push("source teardown"));
subscriber.signal.addEventListener("abort", () => results.push("source abort"));
results.push("before source next 1");
subscriber.next(1);
results.push("after source next 1");
results.push("before source complete");
subscriber.complete();
results.push("after source complete");
});

results.push("calling last");
const promise = source.last();

assert_array_equals(results, [
"calling last",
"source subscribe",
"before source next 1",
"after source next 1",
"before source complete",
"source teardown",
"source abort",
"after source complete",
], "Array values after last() is called");

const lastValue = await promise;
results.push(`last resolved with: ${lastValue}`);

assert_array_equals(results, [
"calling last",
"source subscribe",
"before source next 1",
"after source next 1",
"before source complete",
"source teardown",
"source abort",
"after source complete",
"last resolved with: 1",
], "Array values after Promise is awaited");
}, "last(): Lifecycle");

0 comments on commit bd6cc68

Please sign in to comment.