Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streams: update tests for Web IDL conversion #22982

Merged
merged 10 commits into from
Jun 11, 2020
276 changes: 248 additions & 28 deletions streams/readable-streams/async-iterator.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,20 +292,256 @@ promise_test(async t => {
const it = s[Symbol.asyncIterator]();

const iterResult1 = await it.next();
assert_equals(iterResult1.value, 0);
assert_equals(iterResult1.done, false);
assert_equals(iterResult1.value, 0, '1st next() value');
assert_equals(iterResult1.done, false, '1st next() done');

await promise_rejects_exactly(t, error1, it.next());
await promise_rejects_exactly(t, error1, it.next(), '2nd next()');
}, 'next() rejects if the stream errors');

promise_test(async () => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
if (timesPulled === 0) {
c.enqueue(0);
++timesPulled;
} else {
c.error(error1);
}
}
});

const it = s[Symbol.asyncIterator]();

const iterResult = await it.return('return value');
assert_equals(iterResult.value, 'return value', 'value');
assert_equals(iterResult.done, true, 'done');
}, 'return() does not rejects if the stream has not errored yet');

promise_test(async t => {
const s = recordingReadableStream();
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
// Do not error in start() because doing so would prevent acquiring a reader/async iterator.
c.error(error1);
}
});

const it = s[Symbol.asyncIterator]();
it.next();

await promise_rejects_js(t, TypeError, it.return(), 'return() should reject');
assert_array_equals(s.events, ['pull']);
}, 'calling return() while there are pending reads rejects');
await flushAsyncEvents();
await promise_rejects_exactly(t, error1, it.return('return value'));
}, 'return() rejects if the stream has errored');

promise_test(async t => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
if (timesPulled === 0) {
c.enqueue(0);
++timesPulled;
} else {
c.error(error1);
}
}
});

const it = s[Symbol.asyncIterator]();

const iterResult1 = await it.next();
assert_equals(iterResult1.value, 0, '1st next() value');
assert_equals(iterResult1.done, false, '1st next() done');

await promise_rejects_exactly(t, error1, it.next(), '2nd next()');

const iterResult3 = await it.next();
assert_equals(iterResult3.value, undefined, '3rd next() value');
assert_equals(iterResult3.done, true, '3rd next() done');
}, 'next() after next() reports an error');

promise_test(async () => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
if (timesPulled === 0) {
c.enqueue(0);
++timesPulled;
} else {
c.error(error1);
}
}
});

const it = s[Symbol.asyncIterator]();

const iterResults = await Promise.allSettled([it.next(), it.next(), it.next()]);

assert_equals(iterResults[0].status, 'fulfilled', '1st next() promise status');
assert_equals(iterResults[0].value.value, 0, '1st next() value');
assert_equals(iterResults[0].value.done, false, '1st next() done');

assert_equals(iterResults[1].status, 'rejected', '2nd next() promise status');
assert_equals(iterResults[1].reason, error1, '2nd next() rejection reason');

assert_equals(iterResults[2].status, 'fulfilled', '3rd next() promise status');
assert_equals(iterResults[2].value.value, undefined, '3rd next() value');
assert_equals(iterResults[2].value.done, true, '3rd next() done');
}, 'next() after next() reports an error, no awaiting');

promise_test(async t => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
if (timesPulled === 0) {
c.enqueue(0);
++timesPulled;
} else {
c.error(error1);
}
}
});

const it = s[Symbol.asyncIterator]();

const iterResult1 = await it.next();
assert_equals(iterResult1.value, 0, '1st next() value');
assert_equals(iterResult1.done, false, '1st next() done');

await promise_rejects_exactly(t, error1, it.next(), '2nd next()');

const iterResult3 = await it.return('return value');
assert_equals(iterResult3.value, 'return value', 'return() value');
assert_equals(iterResult3.done, true, 'return() done');
}, 'return() after next() reports an error');
domenic marked this conversation as resolved.
Show resolved Hide resolved

promise_test(async () => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
if (timesPulled === 0) {
c.enqueue(0);
++timesPulled;
} else {
c.error(error1);
}
}
});

const it = s[Symbol.asyncIterator]();

const iterResults = await Promise.allSettled([it.next(), it.next(), it.return('return value')]);

assert_equals(iterResults[0].status, 'fulfilled', '1st next() promise status');
assert_equals(iterResults[0].value.value, 0, '1st next() value');
assert_equals(iterResults[0].value.done, false, '1st next() done');

assert_equals(iterResults[1].status, 'rejected', '2nd next() promise status');
assert_equals(iterResults[1].reason, error1, '2nd next() rejection reason');

assert_equals(iterResults[2].status, 'fulfilled', 'return() promise status');
assert_equals(iterResults[2].value.value, 'return value', 'return() value');
assert_equals(iterResults[2].value.done, true, 'return() done');
}, 'return() after next() reports an error, no awaiting');

promise_test(async () => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
c.enqueue(timesPulled);
++timesPulled;
}
});
const it = s[Symbol.asyncIterator]();

const iterResult1 = await it.next();
assert_equals(iterResult1.value, 0, 'next() value');
assert_equals(iterResult1.done, false, 'next() done');

const iterResult2 = await it.return('return value');
assert_equals(iterResult2.value, 'return value', 'return() value');
assert_equals(iterResult2.done, true, 'return() done');

assert_equals(timesPulled, 2);
}, 'return() after next()');

promise_test(async () => {
let timesPulled = 0;
const s = new ReadableStream({
pull(c) {
c.enqueue(timesPulled);
++timesPulled;
}
});
const it = s[Symbol.asyncIterator]();

const iterResults = await Promise.allSettled([it.next(), it.return('return value')]);

assert_equals(iterResults[0].status, 'fulfilled', 'next() promise status');
assert_equals(iterResults[0].value.value, 0, 'next() value');
assert_equals(iterResults[0].value.done, false, 'next() done');

assert_equals(iterResults[1].status, 'fulfilled', 'return() promise status');
assert_equals(iterResults[1].value.value, 'return value', 'return() value');
assert_equals(iterResults[1].value.done, true, 'return() done');

assert_equals(timesPulled, 2);
}, 'return() after next(), no awaiting');

promise_test(async () => {
const rs = new ReadableStream();
const it = rs.values();

const iterResult1 = await it.return('return value');
assert_equals(iterResult1.value, 'return value', 'return() value');
assert_equals(iterResult1.done, true, 'return() done');

const iterResult2 = await it.next();
assert_equals(iterResult2.value, undefined, 'next() value');
assert_equals(iterResult2.done, true, 'next() done');
}, 'next() after return()');

promise_test(async () => {
const rs = new ReadableStream();
const it = rs.values();

const iterResults = await Promise.allSettled([it.return('return value'), it.next()]);

assert_equals(iterResults[0].status, 'fulfilled', 'return() promise status');
assert_equals(iterResults[0].value.value, 'return value', 'return() value');
assert_equals(iterResults[0].value.done, true, 'return() done');

assert_equals(iterResults[1].status, 'fulfilled', 'next() promise status');
assert_equals(iterResults[1].value.value, undefined, 'next() value');
assert_equals(iterResults[1].value.done, true, 'next() done');
}, 'next() after return(), no awaiting');

promise_test(async () => {
const rs = new ReadableStream();
const it = rs.values();

const iterResult1 = await it.return('return value 1');
assert_equals(iterResult1.value, 'return value 1', '1st return() value');
assert_equals(iterResult1.done, true, '1st return() done');

const iterResult2 = await it.return('return value 2');
assert_equals(iterResult2.value, 'return value 2', '2nd return() value');
assert_equals(iterResult2.done, true, '2nd return() done');
}, 'return() after return()');

promise_test(async () => {
const rs = new ReadableStream();
const it = rs.values();

const iterResults = await Promise.allSettled([it.return('return value 1'), it.return('return value 2')]);

assert_equals(iterResults[0].status, 'fulfilled', '1st return() promise status');
assert_equals(iterResults[0].value.value, 'return value 1', '1st return() value');
assert_equals(iterResults[0].value.done, true, '1st return() done');

assert_equals(iterResults[1].status, 'fulfilled', '2nd return() promise status');
assert_equals(iterResults[1].value.value, 'return value 2', '2nd return() value');
assert_equals(iterResults[1].value.done, true, '2nd return() done');
}, 'return() after return(), no awaiting');

test(() => {
const s = new ReadableStream({
Expand Down Expand Up @@ -351,15 +587,17 @@ promise_test(async t => {
}
});

const it = s[Symbol.asyncIterator]();
const it = s[Symbol.asyncIterator]({ preventCancel: true });

const iterResult1 = await it.next();
assert_equals(iterResult1.value, 0);
assert_equals(iterResult1.done, false);

await promise_rejects_exactly(t, error1, it.next(), 'next() should reject with the error');

await promise_rejects_exactly(t, error1, it.return('return value'), 'return() should reject with the error');
const iterResult2 = await it.return('return value');
assert_equals(iterResult2.value, 'return value');
assert_equals(iterResult2.done, true);

// i.e. it should not reject with a generic "this stream is locked" TypeError.
const reader = s.getReader();
Expand Down Expand Up @@ -417,24 +655,6 @@ promise_test(async () => {
await reader.closed;
}, 'Acquiring a reader and reading the remaining chunks after partially async-iterating a stream with preventCancel = true');

promise_test(async t => {
const rs = new ReadableStream();
const it = rs.values();
await it.return('return value');
const readResult = await it.next();
assert_equals(readResult.done, true, 'done');
assert_equals(readResult.value, undefined, 'undefined');
}, 'calling next() after return() should result in { value: undefined, done: true }');

promise_test(async t => {
const rs = new ReadableStream();
const it = rs.values();
await it.return('return value 1');
const iterResult = await it.return('return value 2');
assert_equals(iterResult.done, true, 'done');
assert_equals(iterResult.value, 'return value 2', 'undefined');
}, 'calling return() after return() should result in { value: passedInValue, done: true }');

for (const preventCancel of [false, true]) {
test(() => {
const rs = new ReadableStream();
Expand Down