-
Notifications
You must be signed in to change notification settings - Fork 8
Conversation
Okay, the tests really don't like having the ponyfill come from a different VM. It breaks in all sorts of ways.
let proto = this;
while (proto !== Object.prototype) {
// ...
proto = Object.getPrototypeOf(proto);
} However, the "parent VM's" Then there's the Finally, there are these tests in One way to fix these issues would be to load the ponyfill inside of the test VM, rather than loading it in the "parent VM" and copying it into the test VM's global scope. This would be closer to what the reference implementation does with WPT runner, but it would be very different from the existing Node WPT tests. I... don't really know how I feel about this. 🤷 |
Hi @MattiasBuelens ! I hit the same kind of issues as you when I tried to update the WPT test harness in nodejs/node#33770. |
@targos Interesting! So instead of spinning up a VM and copying variables into its global scope, the WPT runner would spin up a new Node process and have it load all of the necessary code (e.g. load the library and set up the global variables) to run the test? |
Yes, exactly. |
I went for a Worker-based approach, which was easier to implement. PR: nodejs/node#34796 |
I see nodejs/node#34796 has landed recently. I'll have a look integrating the new test runner soon™, and see if that improves things. 🙂 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Progress! With the new WPT test runner (and only a few hacks), I can get all relevant tests to pass. 🎉
The polyfill still needs to be updated to handle one of the more recent spec changes. After that, I'll run git node wpt streams
again to get the latest WPT streams tests as well.
// HACK: Pretend that our JavaScript shell exposes worker interfaces. | ||
// The streams interfaces are currently only exposed for windows, workers and worklets | ||
// and there's no such thing as [Exposed=Shell] in Web IDL yet. | ||
return globals.has("DedicatedWorker"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better suggestions are welcome. 😁
Hi @MattiasBuelens can I help you get this across the finish line? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Ethan-Arrowood Sorry, this has been lingering for a while. I didn't get much feedback, so I thought people weren't very interested. 🤷♂️
Either way, I've just updated the PR to the latest version of the polyfill and the WPT tests. Have a look!
@@ -0,0 +1,14 @@ | |||
{ | |||
"piping/pipe-through.any.js": { | |||
"fail": "Node does not perform a brand check for AbortSignal.prototype.aborted" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test checks whether passing a "bad" AbortSignal
(in particular ) causes pipeThrough()
to throw. The polyfill implements this by trying to retrieve AbortSignal.prototype.aborted
and checking that it does not throw. WebIDL requires this attribute to perform a brand check, so a compliant implementation should throw a TypeError
when this getter is run on such a "bad" AbortSignal
.
Unfortunately, Node's AbortSignal implementation does not throw an error when AbortSignal.prototype.aborted
is run such a signal. Instead, it will return false
and the polyfill will consider this to be a valid AbortSignal
.
I'm not sure what we want to do here. Should we fix Node to perform a brand check in get aborted
(i.e. throw an error if this[kAborted]
does not exist)? Or should we change how the polyfill does this check (although I'm not sure how)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand you correctly, I think the best course of action is to make an upstream change to Node.js core AbortSignal so that it aligns more with the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On it! 🙂
EDIT: Opened nodejs/node#37720.
Thank you for pushing all of these updates! I'll review next week when I have some more time to go through it all. I'd also like to encourage @nodejs/whatwg-stream and @nodejs/undici to take a look here. Now that things likes EventTarget and AbortController are in core this is the next logical progression towards Fetch and overall WHATWG Stream support for Node 😄 |
Given that this is based on http://npm.im/web-streams-polyfill, is having this repo still useful? Are you running the WPT tests in http://npm.im/web-streams-polyfill? |
This is a bit hard to review with so many files. |
@ronag Note that everything inside |
@mcollina Yes, the polyfill also runs the WPT tests. The polyfill uses a different test runner though: |
Yea, I get that but it's still difficult to review with the GitHub UI. Could you perhaps put all the functionality changes in one commit which we can review and the test fixtures in another one? |
git node wpt streams git node wpt resources git node wpt interfaces git node wpt common
e16f846
to
35cb5db
Compare
@ronag I've squashed the history together in a few commits. All WPT fixtures are now added in one single commit, so you can skip that one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
@joyeecheung @targos @benjamingr should we land this? |
I'm in favour |
What's going to happen after we land? I don't remember the goal of this repository, sorry 😄 |
provide a stopgap solution while we add them to core and bless something as our official implementation. I'll open an issue on nodejs/node. |
But if I understand correctly, this delegates the implementation to an existing module, so the stopgap solution already exists? I'm okay with that as a temporary thing but in the end we will not be able to integrate it like this in Node.js core (the code will have to be copied/adapted at some point). |
Yes exactly. |
Now that Node has a built-in experimental implementation of web streams with nodejs/node#39062 (🎉🎉🎉), I believe this PR and (by extension) this repository has become obsolete. I suggest we close this PR and/or archive this repository. No hard feelings, on the contrary: I'm very happy that web streams made it into Node proper! 😄 |
Woho good news! |
This implements the WHATWG Streams API using the ES2018 ponyfill build from web-streams-polyfill.
The WPT set up is based off of @joyeecheung's work in #2. Many thanks for that! 😄
To do list:
promise_test
), this means that tests can interfere with each other. This is especially bad for the "patched globals" tests, which will literally break the API during the test.completionCallback
is called before we start the next test. I'll try implementing it here first, to see if it works. Hopefully we can upstream that afterwards? 🙏Promise
orUint8Array
from there. However, the tests are run inside a separate VM context, so when it tries to compare whether e.g.ReadableStreamBYOBRequest.view
is aUint8Array
, it's using a different global forUint8Array
than the polyfill.ReadableStream[Symbol.asyncIterator]()
has%AsyncIteratorPrototype%
as its prototype. As far as I know, there's no way to replace that...ReadableStream.pipeTo()
uses anAbortSignal
. Currently, I'm using a separate polyfill for that.It looks like Node has recently added an experimental implementation for this in lib: initial experimental AbortController implementation node#33527? Could be interesting.AbortSignal
from Node 15! 😁ReadableStream.pipeTo()
needs to reject with aDOMException
when it is aborted using a signal, which is also tested by WPT.--expose-internals
, I can retrieve theDOMException
implementation from Node itself. It's even given as an example in the test driver's README! 😅