-
Notifications
You must be signed in to change notification settings - Fork 470
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
Add partial tests for import defer
#4278
Conversation
b38f80f
to
fda523d
Compare
I tried running these in my WebKit implementation and found a few minor issues in the tests, such as missing module flags. This commit has the fixes I made: takikawa/WebKit@d536aa2 After the fixes I had about 8 failures but at least some of these are due to bugs in my implementation, I think. |
Thanks! I imported your patch.
(EDIT: Confirmed that they are bugs in Asumu's implementation) |
620655a
to
79c364c
Compare
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.
I haven't gotten most of the way through this, but here are some initial comments.
test/language/import/import-defer/syntax/invalid-defer-default-and-namespace copy.js
Outdated
Show resolved
Hide resolved
features: [import-defer] | ||
---*/ | ||
|
||
import defer from "./dep_FIXTURE.js"; |
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.
Do we have a test elsewhere (not in syntax) that ensures this syntax is treated as a sync default binding named defer
and not as a deferred import? e.g. the imported module performs a side effect that is tested for.
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.
No. Should I just add it in this file, given that we don't really have the concept of "syntax tests"?
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.
Sure, that would be fine too. By "in syntax" I meant in this syntax/
folder where the test is currently placed; if the test no longer purely tests syntax, you could move it, but I don't think it matters that much.
test/language/import/import-defer/deferred-namespace-object/identity.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/deferred-namespace-object/object-properties.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/deferred-namespace-object/object-properties.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/deferred-namespace-object/object-properties.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/errors/get-other-while-evaluating/main.js
Outdated
Show resolved
Hide resolved
...nguage/import/import-defer/errors/module-throws/third-party-evaluation-after-defer-import.js
Outdated
Show resolved
Hide resolved
I noticed that I cannot use |
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.
Thanks! In general these tests are pretty easy to read and understand.
There were some things that I think are errors in assertions, like the tags pushed to globalThis.evaluations
in some cases, so if your implementation is passing these tests in their current state, you might want to check if that's correct.
test/language/import/import-defer/deferred-namespace-object/object-properties.js
Outdated
Show resolved
Hide resolved
assert(globalThis["error on ns.foo"] instanceof TypeError, "ns.foo while evaluating throws a TypeError"); | ||
|
||
ns.foo; | ||
|
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.
Is this order correct? It seems like the evaluation of the module should only happen during the evaluation of ns.foo in line 36, so in line 34 the error won't be present yet.
Additionally, do we not need to await Promise.resolve()
in between evaluating ns.foo
and checking for the TypeError, since the error will be caught in a microtask?
These comments may just be my misunderstanding of the proposal! I have similar comments on several other files which probably indicates that I'm missing some piece of comprehension.
(If I'm misunderstanding and microtasks in a deferred module import happen synchronously, then does this test and similar ones really need to be async though?)
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.
What is happening here is that ./dep_FIXTURE.js
is not deferred, because it contains top-level await. So what is happening in this test is that:
- the deferred module is not actually deferred, so
dep_FIXTURE.js
starts executing and goes in itsevaluating
state - it has access to a deferred namespace of itself
- once it reaches the
await
, the state changes toevaluating-async
- the test tries then to access a property from the deferred namespace while it's
evaluating-async
(which is what this test it testing). It should throw. dep_FIXTURE.js
is done, and becomesevaluated
main.js
starts evaluating, and the error is already therens.foo
now works, becausens
isevaluated
and notevaluating-async
Should I put this comment in the "info" section, even if usually it just lists spec algorithms?
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.
I think it'd be helpful to spell this out, in the info
section, but feel free to use your own judgement; it might already be obvious to someone who's implementing the proposal.
test/language/import/import-defer/errors/resolution-error/import-defer-of-syntax-error-fails.js
Outdated
Show resolved
Hide resolved
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.
Name might have been copied from the one in syntax-error/
, rename to import-defer-of-missing-module-fails.js
?
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.
I think this got resolved accidentally, the name still references SyntaxError.
test/language/import/import-defer/errors/syntax-error/import-defer-of-syntax-error-fails.js
Outdated
Show resolved
Hide resolved
...ort/import-defer/evaluation-top-level-await/sync-dependency-of-deferred-async-module/main.js
Show resolved
Hide resolved
...ort/import-defer/evaluation-top-level-await/sync-dependency-of-deferred-async-module/main.js
Show resolved
Hide resolved
test/language/import/import-defer/evaluation-sync/evaluation-ignore-isExtensible.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/evaluation-sync/evaluation-ignore-preventExtensions.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/evaluation-sync/evaluation-ignore-setPrototypeOf.js
Outdated
Show resolved
Hide resolved
.../import/import-defer/evaluation-top-level-await/import-defer-transitive-async-module/main.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/evaluation-top-level-await/flattening-order/main.js
Outdated
Show resolved
Hide resolved
Thanks both for the reviews :) Comments addressed. |
test/language/import/import-defer/evaluation-top-level-await/flattening-order/main.js
Outdated
Show resolved
Hide resolved
|
||
let err1, err2; | ||
try { ns.foo } catch (e) { err1 = e }; | ||
assert.deepEqual(err1, { someError: "the error from throws_FIXTURE" }, "Evaluation errors are thrown when evaluating"); |
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.
Looks like this needs the deepEqual include or be written to avoid it
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.
Could we instead write the test to avoid deepEqual
? We are trying to avoid it in new tests, see #3476.
The thrown value could be a primitive, like "the error from throws_FIXTURE"
, since we are not checking for object identity anyway.
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.
I want to throw an object to test that it's the same, but I'll remove deepEqual
test/language/import/import-defer/errors/module-throws/defer-import-after-evaluation.js
Outdated
Show resolved
Hide resolved
...nguage/import/import-defer/errors/module-throws/third-party-evaluation-after-defer-import.js
Outdated
Show resolved
Hide resolved
All fixed, thanks @takikawa! |
...anguage/import/import-defer/evaluation-top-level-await/flattening-order/dep-2.2.1_FIXTURE.js
Outdated
Show resolved
Hide resolved
...age/import/import-defer/evaluation-top-level-await/flattening-order/dep-2.1.1-tla_FIXTURE.js
Outdated
Show resolved
Hide resolved
test/language/import/import-defer/errors/get-other-while-evaluating-async/dep-1-tla_FIXTURE.js
Show resolved
Hide resolved
...anguage/import/import-defer/errors/get-other-while-dep-evaluating-async/dep-1-tla_FIXTURE.js
Show resolved
Hide resolved
Aside from the |
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.
Just minor comments this time.
@takikawa You mentioned that the flattening-order
test needs more adjustments, can you elaborate? I'll approve when that's resolved.
assert.sameValue(Reflect.setPrototypeOf(ns, null), true, "Deferred namespaces' prototype can be 'set' to null"); | ||
|
||
assert.throws(TypeError, () => Reflect.apply(ns, null, []), "Deferred namespaces are not callable"); | ||
assert.throws(TypeError, () => Reflect.construct(ns, null, []), "Deferred namespaces are not constructable"); |
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.
Sorry I didn't notice this before:
assert.throws(TypeError, () => Reflect.construct(ns, null, []), "Deferred namespaces are not constructable"); | |
assert.throws(TypeError, () => Reflect.construct(ns, [], ns), "Deferred namespaces are not constructable"); |
(or Reflect.construct(function () {}, [], ns)
or use harness/isConstructor.js
)
|
||
let err1, err2; | ||
try { ns.foo } catch (e) { err1 = e }; | ||
assert.deepEqual(err1, { someError: "the error from throws_FIXTURE" }, "Evaluation errors are thrown when evaluating"); |
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.
Could we instead write the test to avoid deepEqual
? We are trying to avoid it in new tests, see #3476.
The thrown value could be a primitive, like "the error from throws_FIXTURE"
, since we are not checking for object identity anyway.
assert(globalThis["error on ns.foo"] instanceof TypeError, "ns.foo while evaluating throws a TypeError"); | ||
|
||
ns.foo; | ||
|
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.
I think it'd be helpful to spell this out, in the info
section, but feel free to use your own judgement; it might already be obvious to someone who's implementing the proposal.
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.
I think this got resolved accidentally, the name still references SyntaxError.
@ptomato handled all of your remaining comments |
45e8d4e
to
dd44fcb
Compare
I ran the flattening order test again, and these are the results I got (formatted to make it easier to read)
I suspect the differences may be due to how JSC's module loader is implemented (in particular, how it runs async dependencies here); basically the TLA doesn't seem to yield to the other imports. Not 100% sure though. Edit: I originally said something about |
@takikawa We indeed need to add 5 at the end. The position of the |
- syntax - Deferred namespace objects - Behavior of synchronous deferred modules - Errors for synchronous cases I will open another PR (or push another commit here) for tests about async modules, since I still have to finish polishing it up. There are a few details of the proposal that are still in flux because of some bugs, so this PR does not include tests for them: - `Symbol.toStringTag` of deferred namespace objects - `test/language/import/import-defer/evaluation-sync/evaluation-*` for the other object operations - `import.defer`, which currently doesn't actually defer due to a problem with `.then`
* Add deepEqual.js include where needed * Add module flag where needed * Fix some typos * In evaluation-ignore-set, add a try block to catch typeerrors from assignment Need the bug URL (OOPS!). Reviewed by NOBODY (OOPS!). Explanation of why this fixes the bug (OOPS!). * test/language/import/import-defer/deferred-namespace-object/dep-defer-ns_FIXTURE.js: * test/language/import/import-defer/deferred-namespace-object/identity.js: * test/language/import/import-defer/deferred-namespace-object/object-properties.js: * test/language/import/import-defer/errors/get-other-while-dep-evaluating/main.js: * test/language/import/import-defer/errors/get-other-while-evaluating/main.js: * test/language/import/import-defer/errors/get-self-while-defer-evaluating/main.js: * test/language/import/import-defer/errors/get-self-while-evaluating.js: * test/language/import/import-defer/errors/module-throws/defer-import-after-evaluation.js: * test/language/import/import-defer/errors/module-throws/third-party-evaluation-after-defer-import.js: * test/language/import/import-defer/errors/module-throws/trigger-evaluation.js: * test/language/import/import-defer/errors/resolution-error/import-defer-of-syntax-error-fails.js: * test/language/import/import-defer/errors/syntax-error/import-defer-of-syntax-error-fails.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-get-symbol.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-getPrototypeOf.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-isExtensible.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-preventExtensions.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-set.js: * test/language/import/import-defer/evaluation-sync/evaluation-ignore-setPrototypeOf.js: * test/language/import/import-defer/evaluation-sync/evaluation-trigger-get-string.js: * test/language/import/import-defer/evaluation-sync/import-defer-does-not-evaluate.js: * test/language/import/import-defer/evaluation-sync/module-imported-defer-and-eager.js: * test/language/import/import-defer/syntax/import-attributes.js: * test/language/import/import-defer/syntax/valid-default-binding-named-defer.js: * test/language/import/import-defer/syntax/valid-defer-namespace.js:
Plan: #4215 (I checked the checkbox for tests added by this PR)
This PR includes tests for:
I will open another PR (or push another commit here) for tests about async modules, since I still have to finish polishing it up.
There are a few details of the proposal that are still in flux because of some bugs, so this PR does not include tests for them:
Symbol.toStringTag
of deferred namespace objectstest/language/import/import-defer/evaluation-sync/evaluation-*
for the other object operationsimport.defer
, which currently doesn't actually defer due to a problem with.then