-
Notifications
You must be signed in to change notification settings - Fork 476
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
RFC: Async Helpers #3724
RFC: Async Helpers #3724
Conversation
This proposes a `harness/asyncHelpers.js` file with two helpers in it, `asyncTest()` and `assert.throwsAsync()`. See the RFC for further motivation and details. Note the draft RFC process in tc39#3525. My idea for this pull request is that besides being an RFC in its own right, we use it as a test case for the process. That is, we follow the draft RFC process and hopefully either validate it, or surface changes that need to be made, after which we can land the RFC process in our documentation.
I overlooked the fact that passing an imported module object to $DONE will correctly fail the test. I still think this way of writing the test is unclear, though.
Since a promise rejection is not inherently an exception, I prefer node's naming of |
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.
As discussed, this makes sense to me. I have no strong opinions on the naming.
Thanks for taking the time to write this, Philip! I especially appreciate all the research you did for the prior art. Most of the rationale applies to -asyncTest(async function () {
+(async function () {
await assert.throwsAsync(TypeError, Array.fromAsync([], null), "null mapfn");
await assert.throwsAsync(TypeError, Array.fromAsync([], {}), "non-callable object mapfn");
await assert.throwsAsync(TypeError, Array.fromAsync([], "String"), "string mapfn");
await assert.throwsAsync(TypeError, Array.fromAsync([], true), "boolean mapfn");
await assert.throwsAsync(TypeError, Array.fromAsync([], 3.1416), "number mapfn");
-});
+})().then($DONE, $DONE); This has more characters, but it isn't as concerning as the "boilerplate" you've identified for Sticking with Of course, both concerns apply to any new utility function, but they feel more compelling relative to the convenience that |
@ljharb This seems like a result of the proposed API's fluidity. If it only accepted a Promise instance, then I'd prefer the new assertion accepted only function values, but not only because it increases parity with await assert.throwsAsync(TypeError, Array.fromAsync, "string value"); That would pass with the current design, even though the intention might have been to validate: await assert.throwsAsync(TypeError, Array.fromAsync("string value")); |
I'm not attached to the naming, I do have a preference for |
While it's true that I think overall |
Using the correct terminology here.
I take it that this RFC does not require changes by test embedders, and only makes things easier for test authors, right? My opinion is that there should be a fairly low bar for such changes, and they shouldn't be subject to excessive gatekeeping/bikeshedding. It's fine to write out an RFC with detailed rationale for such a change, but I don't think it should be required for such issues in the future. I encourage you to land this RFC and the supporting code file, and in general, that you land additions to helper files without requiring strong agreement from everyone who's been involved in test262. |
Summary of discussionsSince this is the first, "trial balloon" RFC, I wanted to take things slow and allow plenty of time for comments from stakeholders. I announced the RFC in various TC39 Matrix channels a few weeks ago, and included it in our status update in last week's TC39 plenary. So far the only comment resulting from that was Dan's. So with this post I'd like to propose that we move the RFC to final comment period, with a disposition of "merge". Below I'll write a summary of the discussions that occurred and what changes I propose to make (or have already made) based on them. Please feel free to correct or expand if I didn't summarize accurately. NamingJordan prefers renaming Mike gave an example of a non-obvious misuse of the API, which would be prevented by only accepting a callable. I think this is a good motivation for Proposed conclusion: Update the RFC to only accept callables in Scope of APIMike doesn't find Ms2ger finds that I do see that In order to address Mike's concern about multiple ways to do the same thing within the test corpus, I propose that we port existing tests to use The changes proposed above would hopefully address Mike's concerns sufficiently in order to proceed with Proposed conclusions: Add additional motivation for Detection of missing
|
Thanks for the thorough write-up, @ptomato! For the most part, it seems to accurately reflect everyone's intentions and the path forward. There is a discrepancy that we ought to consider, though: the prevalence of the Earlier in this thread, @Ms2ger reported that the pattern exists in only ~20 tests. That made any harm from introducing an alternate pattern seem negligible, and it also made rewriting the existing uses seem trivial. However, today in the Test262 Matrix channel, @cjtenny shared evidence that the number is a couple orders of magnitude larger:
@ptomato does the prevalence of the older pattern factor in to your valuation of a new one? The code review will certainly be more onerous! |
Hey @jugglinmike , sorry for the delay - I wanted to respond in a bit more detail. First to clear up the misunderstanding: @Ms2ger clarified to me that he'd looked specifically for the pattern of an IIFE followed by that invocation. There are many fewer cases of that. Second, I realized many of the ~5000 invocations were procedurally generated from templates & cases in I did more work characterizing other cases in test262 to understand a good way forward. Many of the invocations would be poor candidates for asyncTest, because they use I decided to refactor all the 'basic' cases I could find - about 50 files, 4 of them leading to another 20 generated cases. I started trying to refactor all the other 'simple' cases. For example, a 'simple' case might look like this: // near the end of the test
someAsyncFunction(/*{ args }*/).then(value => {
assert.sameValue(value, 1, "called once");
}).then($DONE, $DONE); But many quickly start to look like: someAsyncFunction(/* {args }*/).then({retFn} => {
assert.sameValue(retFn.constructor, C);
retFn().then(() => {
throw new Test262Error("Should not resolve");
}, (error) => {
assert.sameValue(...);
...
}).then($DONE, $DONE);
}).catch($DONE); There are also many tests (calling, eventually, I've updated the implementation PR with the refactoring of the simplest cases to use I think refactoring these cases also strikes a good balance of illustrating the clear way for simple cases, while not setting the precedent that we need to exhaustively refactor tests for new language features or harness features. I also think the benefit of Overall, @jugglinmike , does that address your concerns? If you're okay with it and give a 👍 , I'd like to continue with the previous plan discussed in the maintainers' meeting to move this to final comment as soon as I hear from you. Otherwise, what do you think we should do? |
…API for asyncTest and assert.throwsAsync
Co-authored-by: Philip Chimento <philip.chimento@gmail.com>
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.
Sounds good to me!
This was signed off for final comment period (pending Mike's final look, which has occurred) in the maintainers meeting of 2023-01-05, with a disposition of "merge". As per the draft process that specifies 10 calendar days, final comment period ends 2023-01-19 12:00 Pacific time. |
Thanks Ashley!
As the final comment period has closed, I think we can merge this :) and if there are no further comments on #3728 , too, we can merge that and push tests ready for review based upon it! |
This proposes a
harness/asyncHelpers.js
file with two helpers in it,asyncTest()
andassert.throwsAsync()
. See the RFC for further motivation and details.Note the draft RFC process in #3525. My idea for this pull request is that besides being an RFC in its own right, we use it as a test case for the process. That is, we follow the draft RFC process and hopefully either validate it, or surface changes that need to be made, after which we can land the RFC process in our documentation.