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

Port writable stream abort tests to wpt #540

Merged
merged 3 commits into from
Oct 25, 2016

Conversation

marvinhagemeister
Copy link
Contributor

Just ported another test file to wpt. There is one thing where I'm unsure if this is the correct way for assertion. In some tests the constructor of the error object is compared. I couldn't get it to work without casting it to a string first.

For example:

const ws = new WritableStream();
const writer = ws.getWriter();
writer.write().then(
   () => { throw new Error('something failed'); },
   r => assert_equals(r.constructor.toString(), TypeError.toString(), 'err message')
);

@domenic
Copy link
Member

domenic commented Oct 14, 2016

The pattern we've been using for that is to put

const error1 = new Error('error1');
error1.name = 'error1';

at the top of the file (plus maybe error2 if you have multiple errors and want to distinguish), then later doing

return promise_rejects(t, error1, writer.write(), 'err message');

@marvinhagemeister marvinhagemeister changed the title Prot writable stream abort tests to wpt Port writable stream abort tests to wpt Oct 14, 2016
@marvinhagemeister
Copy link
Contributor Author

Ah I see. I'll adapt my code to use promise_rejects 👍

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general very nice, and the porting work is super-appreciated. The main things are using promise_rejects and recordingWritableStream to clean up the tests.

}, 'Aborting a WritableStream should cause the writer\'s fulfilled ready promise to reset to a rejected one');

function promise_fulfills(expectedValue, promise, msg) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary. Inside your promise_test, just do

return promise.then(value => {
  assert_equals(value, expectedValue, msg);
});

the test will fail if it returns a rejected promise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

promise_test(() => {
const ws = new WritableStream({
write() {
throw new Error('Unexpected write() call');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a decent bit of work, but I think these sorts of tests would be improved by using the recordingWritableStream, and then checking the recorded events in a final .then block. An example:

promise_test(() => {
const ws = recordingWritableStream();
const writer = ws.getWriter();
return writer.ready.then(() => {
assert_equals(writer.desiredSize, 1, 'desiredSize should be 1');
writer.close();
assert_equals(writer.desiredSize, 1, 'desiredSize should be still 1');
return writer.ready.then(v => {
assert_equals(v, undefined, 'ready promise should be fulfilled with undefined');
assert_array_equals(ws.events, ['close'], 'write and abort should not be called');
});
});
}, 'when close is called on a WritableStream in writable state, ready should return a fulfilled promise');

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the tip. recordingWritableStream is much cleaner 👍

promise_test(() => {
let writeCount = 0;

const ws = new WritableStream({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another good example of where recordingWritableStream would help you. You wouldn't need writeCount or any asserts, just check the events in a final .then block.

]);
}, 'Aborting a WritableStream puts it in an errored state, with stored error equal to the abort reason');

test(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be a promise_test when it moves to use assert_promise_rejects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure where to import assert_promise_rejects from. This function seems to be duplicated inside the web-platform-tests repo. I tried including one of the existing functions, but get an URL error by testharness

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant promise_rejects, sorry.


writer.close();

setTimeout(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use promise_test and delay()

@marvinhagemeister
Copy link
Contributor Author

Sorry for the late response, I got ill for a few days. Thanks, for the review. I'll make these changes over the day 👍

@domenic
Copy link
Member

domenic commented Oct 19, 2016

It looks like you just accidentally created a duplicate of promise_rejects named assert_promise_rejects. I'm sorry for misleading you by saying the wrong name! But yeah, that can be deleted and we can just use promise_rejects.

@marvinhagemeister
Copy link
Contributor Author

Thanks for clearing that up. Yeah, I got confused by the existing tests in inside the web-platform-tests folder. Adjusted the PR.

@@ -1,14 +1,16 @@
'use strict';
/* global delay, recordingWritableStream */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you rebase this will not be necessary


if (self.importScripts) {
self.importScripts('../resources/test-utils.js');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this after testharness.js

writer.write(2);
})
.then(() => {
assert_equals(ws.events.length, 2, 'the stream should have received 2 events');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use assert_array_equals here like the other recording stream tests. Same below.

The events[1] entry is the argument passed to abort, by the way, and is not related to writes.


const writer = ws.getWriter();

return promise_rejects(t, errorInSinkAbort, writer.abort(undefined),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the error1 pattern used elsewhere? With a single error1 at the top of the file? Here and below.

Also everywhere that creates a separate passedReason can use that error1.

const passedReason = new Error('Sorry, it just wasn\'t meant to be.');
writer.abort(passedReason);

assert_equals(recordedReason, passedReason);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test can use recordingWritableStream instead, with assert_array_equals on the contents.

]);
}, 'Aborting a WritableStream puts it in an errored state, with stored error equal to the abort reason');

// TODO return promise
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just store the promise with const writePromise = promise_rejects(...) and then return it as the last line


const passedReason = new Error('Sorry, it just wasn\'t meant to be.');
writer.abort(passedReason);
}, 'Aborting a WritableStream causes any outstanding write() promises to be rejected with the abort reason');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test description is again outdated; "with a TypeError"

const passedReason = new Error('Sorry, it just wasn\'t meant to be.');
writer.abort(passedReason);

return promise_rejects(t, new TypeError('Aborted'), writer.closed, 'the stream should be errored with a TypeError');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include 'Aborted' here; the test framework doesn't look at messages. (Yeah, it's kind of wonky.)

.then(() => writer.abort())
.then(
v => assert_equals(v, undefined, 'abort promise should fulfill with undefined'),
() => { throw new Error(); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This () => { throw new Error(); } is not necessary. In fact the second .then() can be removed entirely since we already test the undefinedness earlier.


const writer = ws.getWriter();

writer.abort();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again best to use recordingWritableStream. As-is, this test will pass even if close is never called.

It might be good to add something to recordingWritableStream's close() that asserts that arguments.length === 0.

@domenic domenic force-pushed the writable_abort_tests branch from edaab4b to 995382f Compare October 25, 2016 19:23
@domenic
Copy link
Member

domenic commented Oct 25, 2016

@marvinhagemeister I'll take care of the rest of the issues I noted. Thanks so much for your help getting this file moved over :).

@domenic domenic merged commit 5dd1862 into whatwg:master Oct 25, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants