-
Notifications
You must be signed in to change notification settings - Fork 28
#3180. Add tests for JsAnyOperation.equals()
#3222
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
Conversation
I can see that this PR uses the same approach as #3216 where I asked why some tests had two |
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, with a couple of questions about the fact that certain declarations are evaluated more than once.
@srujzs, here's another one. Do tell us if we need to find other interop expert reviewers!
Answered in #3216 as well. A raw string doesn't support |
Oh, how funny - I didn't see this PR first and wrote comments about how I'd prefer this way in the other PRs. This makes more sense imo! |
@osa1, could you take a look at this? It looks like the WASM behavior differs from the expected behavior, so we need to know whether it's the expectations or the WASM implementation that should be adjusted. ;-) |
@eernstg which lines/tests do you mean? I run all of the tests here and they pass with dart2wasm. |
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.
The test cases LGTM, but similar @srujzs in #3216 (comment), I also wonder if this might be overkill. JSAny
is just a reference to a JS object, and operator ==
simply call JS ===
: https://github.com/dart-lang/sdk/blob/b67482d6bc21fd7462c98122086eae56450d7d11/sdk/lib/_internal/wasm/lib/js_helper.dart#L158-L159
I suspect it should be the same in dart2js as well.
So if Dart to JS and JS to Dart conversions are correct, then operator ==
cannot be wrong.
I think it's just a wrong PR. @osa1 please, take a look at #3221 (comment) For me it's strange that it passes on JS. Another example. main() {
Expect.isTrue(true.toJS.isTruthy);
} This works with JS but fails with WASM. Adding |
@sgrekhov thanks for the smaller repro. I think the output is as expected. https://api.dart.dev/dart-js_interop/JSAnyOperatorExtension/isTruthy.html and Edit: to elaborate: |
About tests expecting not-a-number and failing because |
Hmm... According to @srujzs
And there's no any information about |
@sgrekhov do you have the link to @srujzs's comment on this? This behavior is the same in import 'dart:js_interop';
import 'expect.dart';
@JS('eval')
external void eval(String s);
@JS('foo')
external JSNumber foo();
main() {
eval('''
globalThis.foo = function() {
return 123;
};
''');
print(foo());
print(foo() == 123.0); // true in dart2js, false in dart2wasm
print(foo() == 123); // true in dart2js, false in dart2wasm
} The reason is because in dart2wasm we have to box the JS references returned from JS calls, and once you box the references you can implement your own In dart2js you don't have to box, and boxing would cost you performance. So if we make dart2js work like dart2wasm here, So we have three options:
I don't see any other options. @srujzs have you considered this case already? Do you have any opinions on the options above? |
@osa1 is there a way to detect Expect.isTrue(true.toJS.isTruthy.dartify());
if (isJS) {
Expect.isTrue(true.toJS.isTruthy);
}
if (isWasm) {
Expect.isFalse(true.toJS.isTruthy);
} |
@sgrekhov |
It is an extension type on Dart bool directly in the JS compilers. Re: documentation, I agree it might be helpful to be clearer about the representation type differences, but I don't want to specify that the representation type is a specific type, because that may and should be allow to change. https://api.dart.dev/dart-js_interop/ specifies the runtime type differences and that My comment here about not using
We could lint as a fourth option. We already lint for
I think this would be the preferable way to check for the compiler. |
Thanks. So we accept this difference in semantics as expected. Do we want to test Given that this is not a specified behavior of |
It works, thank you!
Now there is a note that one should do
I still don't have a clear understanding of what kind of tests we should write.
main() {
eval(r'''
var jsVar = "jsVar";
''');
Expect.equals("jsVar", globalContext["jsVar"]);
} We could instead write something like: main() {
eval(r'''
var jsVar = "jsVar";
''');
Expect.equals("jsVar", globalContext["jsVar"].dartify());
if (isJS) {
Expect.equals("jsVar", globalContext["jsVar"]);
}
if (isWasm) {
Expect.notEquals("jsVar", globalContext["jsVar"]); // If one day this fail it'd mean that the lint also should be removed
}
} @srujzs @osa1 @eernstg do we need the tests like the above? Or this, probably, makes sense for Honestly, I'd vote for option 3: to make // On dart2wasm
print(globalContext["jsVar"]); // prints 'jsVar'
print(globalContext["jsVar"] == "jsVar"); // false Just saw @osa1's note that we’ve accepted the fact that the semantics of
Does that work for you? |
Thinking about this more, the lint we mention above already exists: https://dart.dev/tools/linter-rules/unrelated_type_equality_checks The issue with equality is not specific to js_interop types, so the lint above should work. Regarding option (3): I realized that it's actually not easily possible without potentically sacrificing a lot of performance in dart2wasm. The problem is
I'm not sure if I agree.. You're comparing We accept this difference between dart2js and dart2wasm not because it's the ideal language design, but for pragmatic reasons. Wasm and JS are different targets with different limitations and performance. If we want both of these backends to be useful we have to accept this kind of thing sometimes. For testing We don't want to test JS So I think for each operation we want a few cases that to check that the right JS function is called. For |
Hi @osa1, @srujzs, and @sgrekhov, there's a lot of discussion here. I think the semantics issue has been settled:
which means that tests should expect WASM or JS compilation in those cases, and specify different expectations. Next, the desired level of coverage is addressed here:
So the tests would then be simplified considerably. Presumably that would be done by adding more commits to this PR, as well as a few others? |
No. I created #3223 as a replacement for this and the others. Please review it. If that PR is landed, I'll close this and the other PRs. |
Well, with a clause that that's for comparing two JS values, not a JS value and a Dart value. :) But yes, we should tell users not to use
The final PR converts both values to JS values but we could also go the other way:
Yes, thanks for simplifying here and all the work here, @sgrekhov!
Ah yeah, and it's in core too. The one downside is
Agreed. I think poking a hole into |
Replaced by #3223 |
If this PR approach is OK, I'll rewrite the earlier tests this way.