mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:09:48 +00:00
[pkg:js] Add subtyping tests with liveness
Adds tests for subtyping between pkg:js types. Also runs tests for both when types are made live and for when they are not. Also adds these tests to lib_2. Change-Id: I25fdc293e422eb21fa8a80dea66ae5d492c5aafd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/205601 Reviewed-by: Sigmund Cherem <sigmund@google.com> Reviewed-by: Riley Porter <rileyporter@google.com> Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
parent
44ffad59d2
commit
0fc2d929e3
|
@ -1,88 +0,0 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships between JS and anonymous classes.
|
||||
|
||||
@JS()
|
||||
library subtyping_test;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:expect/expect.dart' show hasUnsoundNullSafety;
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
class JSClassA {}
|
||||
|
||||
@JS()
|
||||
class JSClassB {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassA {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassB {}
|
||||
|
||||
class DartClass {}
|
||||
|
||||
void useJSClassA(JSClassA _) {}
|
||||
void useAnonymousClassA(AnonymousClassA _) {}
|
||||
void useDartClass(DartClass _) {}
|
||||
|
||||
void useNullableJSClassA(JSClassA? _) {}
|
||||
void useNullableAnonymousClassA(AnonymousClassA? _) {}
|
||||
|
||||
// Avoid static type optimization by running all tests using this.
|
||||
@pragma('dart2js:noInline')
|
||||
@pragma('dart2js:assumeDynamic')
|
||||
confuse(x) => x;
|
||||
|
||||
void main() {
|
||||
// Checks subtyping with the same type and nullability subtyping.
|
||||
expect(useJSClassA is void Function(JSClassA), true);
|
||||
expect(useAnonymousClassA is void Function(AnonymousClassA), true);
|
||||
expect(useJSClassA is void Function(JSClassA?), hasUnsoundNullSafety);
|
||||
expect(useAnonymousClassA is void Function(AnonymousClassA?),
|
||||
hasUnsoundNullSafety);
|
||||
expect(useNullableJSClassA is void Function(JSClassA?), true);
|
||||
expect(useNullableAnonymousClassA is void Function(AnonymousClassA?), true);
|
||||
expect(useNullableJSClassA is void Function(JSClassA), true);
|
||||
expect(useNullableAnonymousClassA is void Function(AnonymousClassA), true);
|
||||
|
||||
expect(confuse(useJSClassA) is void Function(JSClassA), true);
|
||||
expect(confuse(useAnonymousClassA) is void Function(AnonymousClassA), true);
|
||||
expect(
|
||||
confuse(useJSClassA) is void Function(JSClassA?), hasUnsoundNullSafety);
|
||||
expect(confuse(useAnonymousClassA) is void Function(AnonymousClassA?),
|
||||
hasUnsoundNullSafety);
|
||||
expect(confuse(useNullableJSClassA) is void Function(JSClassA?), true);
|
||||
expect(confuse(useNullableAnonymousClassA) is void Function(AnonymousClassA?),
|
||||
true);
|
||||
expect(confuse(useNullableJSClassA) is void Function(JSClassA), true);
|
||||
expect(confuse(useNullableAnonymousClassA) is void Function(AnonymousClassA),
|
||||
true);
|
||||
|
||||
// No subtyping between JS and anonymous classes.
|
||||
expect(useJSClassA is void Function(AnonymousClassA), false);
|
||||
expect(useAnonymousClassA is void Function(JSClassA), false);
|
||||
|
||||
expect(confuse(useJSClassA) is void Function(AnonymousClassA), false);
|
||||
expect(confuse(useAnonymousClassA) is void Function(JSClassA), false);
|
||||
|
||||
// No subtyping between separate classes even if they're both JS classes or
|
||||
// anonymous classes.
|
||||
expect(useJSClassA is void Function(JSClassB), false);
|
||||
expect(useAnonymousClassA is void Function(AnonymousClassB), false);
|
||||
|
||||
expect(confuse(useJSClassA) is void Function(JSClassB), false);
|
||||
expect(confuse(useAnonymousClassA) is void Function(AnonymousClassB), false);
|
||||
|
||||
// No subtyping between JS/anonymous classes and Dart classes.
|
||||
expect(useJSClassA is void Function(DartClass), false);
|
||||
expect(useAnonymousClassA is void Function(DartClass), false);
|
||||
|
||||
expect(confuse(useJSClassA) is void Function(DartClass), false);
|
||||
expect(confuse(useAnonymousClassA) is void Function(DartClass), false);
|
||||
}
|
20
tests/lib/js/subtyping_test/subtyping_live_test.dart
Normal file
20
tests/lib/js/subtyping_test/subtyping_live_test.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships after making package:js types live.
|
||||
|
||||
@JS()
|
||||
library subtyping_live_test;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'subtyping_test_util.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic get externalGetter;
|
||||
|
||||
void main() {
|
||||
// Call to foreign function should trigger dart2js to assume types are live.
|
||||
externalGetter;
|
||||
testSubtyping();
|
||||
}
|
12
tests/lib/js/subtyping_test/subtyping_not_live_test.dart
Normal file
12
tests/lib/js/subtyping_test/subtyping_not_live_test.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships without making package:js types live.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'subtyping_test_util.dart';
|
||||
|
||||
void main() {
|
||||
testSubtyping();
|
||||
}
|
92
tests/lib/js/subtyping_test/subtyping_test_util.dart
Normal file
92
tests/lib/js/subtyping_test/subtyping_test_util.dart
Normal file
|
@ -0,0 +1,92 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships between JS and anonymous classes.
|
||||
|
||||
@JS()
|
||||
library subtyping_test_util;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:expect/expect.dart' show hasUnsoundNullSafety;
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
class JSClassA {}
|
||||
|
||||
@JS()
|
||||
class JSClassB {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassA {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassB {}
|
||||
|
||||
class DartClass {}
|
||||
|
||||
JSClassA returnJS() => throw '';
|
||||
JSClassA? returnNullableJS() => throw '';
|
||||
|
||||
AnonymousClassA returnAnon() => throw '';
|
||||
AnonymousClassA? returnNullableAnon() => throw '';
|
||||
|
||||
DartClass returnDartClass() => throw '';
|
||||
|
||||
// Avoid static type optimization by running all tests using this.
|
||||
@pragma('dart2js:noInline')
|
||||
@pragma('dart2js:assumeDynamic')
|
||||
confuse(x) => x;
|
||||
|
||||
void testSubtyping() {
|
||||
// Checks subtyping with the same type and nullability subtyping.
|
||||
expect(returnJS is JSClassA Function(), true);
|
||||
expect(returnAnon is AnonymousClassA Function(), true);
|
||||
expect(returnJS is JSClassA? Function(), true);
|
||||
expect(returnAnon is AnonymousClassA? Function(), true);
|
||||
expect(returnNullableJS is JSClassA? Function(), true);
|
||||
expect(returnNullableAnon is AnonymousClassA? Function(), true);
|
||||
expect(returnNullableJS is JSClassA Function(), hasUnsoundNullSafety);
|
||||
expect(
|
||||
returnNullableAnon is AnonymousClassA Function(), hasUnsoundNullSafety);
|
||||
|
||||
// Subtyping between JS and anonymous classes.
|
||||
expect(returnJS is AnonymousClassA Function(), true);
|
||||
expect(returnAnon is JSClassA Function(), true);
|
||||
|
||||
// Subtyping between same type of package:js classes.
|
||||
expect(returnJS is JSClassB Function(), true);
|
||||
expect(returnAnon is AnonymousClassB Function(), true);
|
||||
|
||||
// No subtyping between JS/anonymous classes and Dart classes.
|
||||
expect(returnJS is DartClass Function(), false);
|
||||
expect(returnDartClass is JSClassA Function(), false);
|
||||
expect(returnAnon is DartClass Function(), false);
|
||||
expect(returnDartClass is AnonymousClassA Function(), false);
|
||||
|
||||
// Repeat the checks but using `confuse` to coerce runtime checks instead of
|
||||
// compile-time like above.
|
||||
expect(confuse(returnJS) is JSClassA Function(), true);
|
||||
expect(confuse(returnAnon) is AnonymousClassA Function(), true);
|
||||
expect(confuse(returnJS) is JSClassA? Function(), true);
|
||||
expect(confuse(returnAnon) is AnonymousClassA? Function(), true);
|
||||
expect(confuse(returnNullableJS) is JSClassA? Function(), true);
|
||||
expect(confuse(returnNullableAnon) is AnonymousClassA? Function(), true);
|
||||
expect(
|
||||
confuse(returnNullableJS) is JSClassA Function(), hasUnsoundNullSafety);
|
||||
expect(confuse(returnNullableAnon) is AnonymousClassA Function(),
|
||||
hasUnsoundNullSafety);
|
||||
|
||||
expect(confuse(returnJS) is AnonymousClassA Function(), true);
|
||||
expect(confuse(returnAnon) is JSClassA Function(), true);
|
||||
|
||||
expect(confuse(returnJS) is JSClassB Function(), true);
|
||||
expect(confuse(returnAnon) is AnonymousClassB Function(), true);
|
||||
|
||||
expect(confuse(returnJS) is DartClass Function(), false);
|
||||
expect(confuse(returnDartClass) is JSClassA Function(), false);
|
||||
expect(confuse(returnAnon) is DartClass Function(), false);
|
||||
expect(confuse(returnDartClass) is AnonymousClassA Function(), false);
|
||||
}
|
20
tests/lib_2/js/subtyping_test/subtyping_live_test.dart
Normal file
20
tests/lib_2/js/subtyping_test/subtyping_live_test.dart
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships after making package:js types live.
|
||||
|
||||
@JS()
|
||||
library subtyping_live_test;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'subtyping_test_util.dart';
|
||||
|
||||
@JS()
|
||||
external dynamic get externalGetter;
|
||||
|
||||
void main() {
|
||||
// Call to foreign function should trigger dart2js to assume types are live.
|
||||
externalGetter;
|
||||
testSubtyping();
|
||||
}
|
12
tests/lib_2/js/subtyping_test/subtyping_not_live_test.dart
Normal file
12
tests/lib_2/js/subtyping_test/subtyping_not_live_test.dart
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships without making package:js types live.
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'subtyping_test_util.dart';
|
||||
|
||||
void main() {
|
||||
testSubtyping();
|
||||
}
|
74
tests/lib_2/js/subtyping_test/subtyping_test_util.dart
Normal file
74
tests/lib_2/js/subtyping_test/subtyping_test_util.dart
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// Tests subtyping relationships between JS and anonymous classes.
|
||||
|
||||
@JS()
|
||||
library subtyping_test_util;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:expect/minitest.dart';
|
||||
|
||||
@JS()
|
||||
class JSClassA {}
|
||||
|
||||
@JS()
|
||||
class JSClassB {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassA {}
|
||||
|
||||
@JS()
|
||||
@anonymous
|
||||
class AnonymousClassB {}
|
||||
|
||||
class DartClass {}
|
||||
|
||||
JSClassA returnJS() => throw '';
|
||||
|
||||
AnonymousClassA returnAnon() => throw '';
|
||||
|
||||
DartClass returnDartClass() => throw '';
|
||||
|
||||
// Avoid static type optimization by running all tests using this.
|
||||
@pragma('dart2js:noInline')
|
||||
@pragma('dart2js:assumeDynamic')
|
||||
confuse(x) => x;
|
||||
|
||||
void testSubtyping() {
|
||||
// Checks subtyping with the same type.
|
||||
expect(returnJS is JSClassA Function(), true);
|
||||
expect(returnAnon is AnonymousClassA Function(), true);
|
||||
|
||||
// Subtyping between JS and anonymous classes.
|
||||
expect(returnJS is AnonymousClassA Function(), true);
|
||||
expect(returnAnon is JSClassA Function(), true);
|
||||
|
||||
// Subtyping between same type of package:js classes.
|
||||
expect(returnJS is JSClassB Function(), true);
|
||||
expect(returnAnon is AnonymousClassB Function(), true);
|
||||
|
||||
// No subtyping between JS/anonymous classes and Dart classes.
|
||||
expect(returnJS is DartClass Function(), false);
|
||||
expect(returnDartClass is JSClassA Function(), false);
|
||||
expect(returnAnon is DartClass Function(), false);
|
||||
expect(returnDartClass is AnonymousClassA Function(), false);
|
||||
|
||||
// Repeat the checks but using `confuse` to coerce runtime checks instead of
|
||||
// compile-time like above.
|
||||
expect(confuse(returnJS) is JSClassA Function(), true);
|
||||
expect(confuse(returnAnon) is AnonymousClassA Function(), true);
|
||||
|
||||
expect(confuse(returnJS) is AnonymousClassA Function(), true);
|
||||
expect(confuse(returnAnon) is JSClassA Function(), true);
|
||||
|
||||
expect(confuse(returnJS) is JSClassB Function(), true);
|
||||
expect(confuse(returnAnon) is AnonymousClassB Function(), true);
|
||||
|
||||
expect(confuse(returnJS) is DartClass Function(), false);
|
||||
expect(confuse(returnDartClass) is JSClassA Function(), false);
|
||||
expect(confuse(returnAnon) is DartClass Function(), false);
|
||||
expect(confuse(returnDartClass) is AnonymousClassA Function(), false);
|
||||
}
|
Loading…
Reference in a new issue