Add extra type check cases and record current test status in javascriptobject_extensions_test.dart
- Adds some missing type check cases to check whether a Dart class that implements a JS class properly type-checks and vice versa. Also adds the generic version of those cases. - Furthermore, this file contains a number of tests that are broken in both compilers so it's currently marked as failing on all configurations. Instead of doing this, we mark the current status for each individual test in the expectation, and place the real expected value in a comment next to it. That way, if the current status changes, we can detect it. Change-Id: I7b208863fdebdf80b3735fae896943da65ecf69a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/378565 Commit-Queue: Srujan Gaddam <srujzs@google.com> Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
committed by
Commit Queue
parent
238f116757
commit
33dd27771d
@@ -20,6 +20,9 @@ import 'dart:_interceptors'
|
||||
UnknownJavaScriptObject,
|
||||
JSObject;
|
||||
|
||||
const isDDC = const bool.fromEnvironment('dart.library._ddc_only');
|
||||
const isDart2JS = const bool.fromEnvironment('dart.library._dart2js_only');
|
||||
|
||||
@JS()
|
||||
external void eval(String code);
|
||||
|
||||
@@ -35,6 +38,15 @@ class ImplementationClass implements JSClass {
|
||||
String get name => 'ImplementationClass';
|
||||
}
|
||||
|
||||
class GenericInterfaceClass<T> {}
|
||||
|
||||
@JS('JSClass')
|
||||
class GenericJSClass<T> implements GenericInterfaceClass<T> {
|
||||
external GenericJSClass();
|
||||
}
|
||||
|
||||
class GenericImplementationClass<T> implements GenericJSClass<T> {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClass {
|
||||
@@ -145,20 +157,44 @@ main() {
|
||||
expect(null is JavaScriptObject, false);
|
||||
runtimeIsAndAs<JavaScriptObject>(null, hasUnsoundNullSafety);
|
||||
|
||||
// Most of the following tests don't work in DDC and dart2js. In order to test
|
||||
// the current status on both compilers, we place the current status in the
|
||||
// expectation, and the real expected value in a comment next to it. If at any
|
||||
// point we fix the compilers so we get the real expected value, the
|
||||
// corresponding expectations should be amended.
|
||||
|
||||
// Transitive is and as.
|
||||
// JS type <: JavaScriptObject <: JSObject
|
||||
expect(jsObj is JSObject, true);
|
||||
runtimeIsAndAs<JSObject>(jsObj);
|
||||
// JavaScriptObject <: JS type <: Dart interface
|
||||
expect(javaScriptObject is InterfaceClass, true);
|
||||
runtimeIsAndAs<InterfaceClass>(javaScriptObject);
|
||||
expect(jsObj is InterfaceClass, isDart2JS /* true */);
|
||||
runtimeIsAndAs<InterfaceClass>(jsObj, isDart2JS /* true */);
|
||||
// Generics should be effectively ignored when a JS interop class implements
|
||||
// a Dart class or vice versa.
|
||||
var jsObjInt = GenericJSClass<int>();
|
||||
expect(jsObjInt is GenericInterfaceClass<int>, isDart2JS /* true */);
|
||||
runtimeIsAndAs<GenericInterfaceClass<int>>(jsObjInt, isDart2JS /* true */);
|
||||
var jsObjString = GenericJSClass<String>();
|
||||
expect(jsObjString is GenericInterfaceClass<int>, isDart2JS /* true */);
|
||||
runtimeIsAndAs<GenericInterfaceClass<int>>(jsObjString, isDart2JS /* true */);
|
||||
expect(javaScriptObject is InterfaceClass, isDart2JS /* true */);
|
||||
runtimeIsAndAs<InterfaceClass>(javaScriptObject, isDart2JS /* true */);
|
||||
// Dart implementation <: JS type <: JavaScriptObject
|
||||
var impl = ImplementationClass();
|
||||
expect(impl is JavaScriptObject, true);
|
||||
runtimeIsAndAs<JavaScriptObject>(impl);
|
||||
expect(impl is JSClass, true);
|
||||
runtimeIsAndAs<JSClass>(impl);
|
||||
var implInt = GenericImplementationClass<int>();
|
||||
expect(implInt is GenericJSClass<int>, true);
|
||||
runtimeIsAndAs<GenericJSClass<int>>(implInt);
|
||||
var implString = GenericImplementationClass<String>();
|
||||
expect(implString is GenericJSClass<int>, true);
|
||||
runtimeIsAndAs<GenericJSClass<int>>(implString);
|
||||
expect(impl is JavaScriptObject, false /* true */);
|
||||
runtimeIsAndAs<JavaScriptObject>(impl, false /* true */);
|
||||
// Dart implementation <: JS type <: JavaScriptObject <: JSObject
|
||||
expect(impl is JSObject, true);
|
||||
runtimeIsAndAs<JSObject>(impl);
|
||||
expect(impl is JSObject, false /* true */);
|
||||
runtimeIsAndAs<JSObject>(impl, false /* true */);
|
||||
|
||||
// Test that subtyping with nullability works as expected.
|
||||
expect(returnJavaScriptObject is JavaScriptObject? Function(), true);
|
||||
@@ -167,40 +203,49 @@ main() {
|
||||
|
||||
// Test that JavaScriptObject can be used in place of package:js types in
|
||||
// function types, and vice versa.
|
||||
expect(returnJavaScriptObject is JSClass Function(), true);
|
||||
expect(returnJS is JavaScriptObject Function(), true);
|
||||
expect(returnJavaScriptObject is AnonymousClass Function(), true);
|
||||
expect(returnAnon is JavaScriptObject Function(), true);
|
||||
// TODO(srujzs): We should add tests for subtyping involving generics in each
|
||||
// of these cases. However, it's very unlikely we'll fix the non-generic cases
|
||||
// to begin with, and such tests would be filtered today anyways, so we can
|
||||
// add those tests later if we do fix these.
|
||||
expect(returnJavaScriptObject is JSClass Function(), false /* true */);
|
||||
expect(returnJS is JavaScriptObject Function(), isDDC /* true */);
|
||||
expect(returnJavaScriptObject is AnonymousClass Function(), false /* true */);
|
||||
expect(returnAnon is JavaScriptObject Function(), isDDC /* true */);
|
||||
|
||||
// Transitive subtyping.
|
||||
// UnknownJavaScriptObject <: JavaScriptObject <: JS type
|
||||
expect(returnUnknownJavaScriptObject is JSClass Function(), true);
|
||||
expect(returnUnknownJavaScriptObject is JSClass Function(), false /* true */);
|
||||
// JS type <: JavaScriptObject <: JSObject
|
||||
expect(returnJS is JSObject Function(), true);
|
||||
expect(returnJS is JSObject Function(), isDDC /* true */);
|
||||
// JavaScriptObject <: JS type <: Dart interface
|
||||
expect(returnJavaScriptObject is InterfaceClass Function(), true);
|
||||
expect(returnJavaScriptObject is InterfaceClass Function(), false /* true */);
|
||||
// Dart implementation <: JS type <: JavaScriptObject
|
||||
expect(returnImpl is JavaScriptObject Function(), true);
|
||||
expect(returnImpl is JavaScriptObject Function(), false /* true */);
|
||||
// UnknownJavaScriptObject <: JavaScriptObject <: JS type <: Dart interface
|
||||
expect(returnUnknownJavaScriptObject is InterfaceClass Function(), true);
|
||||
expect(returnUnknownJavaScriptObject is InterfaceClass Function(),
|
||||
false /* true */);
|
||||
// Dart implementation <: JS type <: JavaScriptObject <: JSObject
|
||||
expect(returnImpl is JSObject Function(), true);
|
||||
expect(returnImpl is JSObject Function(), false /* true */);
|
||||
|
||||
// Run above subtype checks but at runtime.
|
||||
expect(confuse(returnJavaScriptObject) is JavaScriptObject? Function(), true);
|
||||
expect(confuse(returnNullableJavaScriptObject) is JavaScriptObject Function(),
|
||||
hasUnsoundNullSafety);
|
||||
|
||||
expect(confuse(returnJavaScriptObject) is JSClass Function(), true);
|
||||
expect(
|
||||
confuse(returnJavaScriptObject) is JSClass Function(), false /* true */);
|
||||
expect(confuse(returnJS) is JavaScriptObject Function(), true);
|
||||
expect(confuse(returnJavaScriptObject) is AnonymousClass Function(), true);
|
||||
expect(confuse(returnJavaScriptObject) is AnonymousClass Function(),
|
||||
false /* true */);
|
||||
expect(confuse(returnAnon) is JavaScriptObject Function(), true);
|
||||
|
||||
expect(confuse(returnUnknownJavaScriptObject) is JSClass Function(), true);
|
||||
expect(confuse(returnUnknownJavaScriptObject) is JSClass Function(),
|
||||
isDart2JS /* true */);
|
||||
expect(confuse(returnJS) is JSObject Function(), true);
|
||||
expect(confuse(returnJavaScriptObject) is InterfaceClass Function(), true);
|
||||
expect(confuse(returnImpl) is JavaScriptObject Function(), true);
|
||||
expect(confuse(returnJavaScriptObject) is InterfaceClass Function(),
|
||||
false /* true */);
|
||||
expect(confuse(returnImpl) is JavaScriptObject Function(), false /* true */);
|
||||
expect(confuse(returnUnknownJavaScriptObject) is InterfaceClass Function(),
|
||||
true);
|
||||
expect(confuse(returnImpl) is JSObject Function(), true);
|
||||
isDart2JS /* true */);
|
||||
expect(confuse(returnImpl) is JSObject Function(), false /* true */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user