-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[package:js] Add test for is checks and as casts
Adds tests for type checks and casts using JS classes and object literals. Checks typing between different classes, same classes, object literals, subtypes, and dynamic conversions. Change-Id: I01c384395f0e6c8d671ac9bd0dc6e6905845a760 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/152990 Commit-Queue: Srujan Gaddam <srujzs@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com>
- Loading branch information
Showing
1 changed file
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// 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 `is` checks and `as` casts between various JS objects. Currently, all | ||
// checks and casts should be allowed between JS objects. | ||
|
||
@JS() | ||
library is_check_and_as_cast_test; | ||
|
||
import 'package:js/js.dart'; | ||
import 'package:expect/minitest.dart'; | ||
|
||
@JS() | ||
external void eval(String code); | ||
|
||
@JS() | ||
class Foo { | ||
external Foo(int a); | ||
external int get a; | ||
} | ||
|
||
// Class with same structure as Foo but separate JS class. | ||
@JS() | ||
class Bar { | ||
external Bar(int a); | ||
external int get a; | ||
} | ||
|
||
@JS('Bar') | ||
class BarCopy { | ||
external BarCopy(int a); | ||
external int get a; | ||
} | ||
|
||
@JS() | ||
class Baz { | ||
external Baz(int a, int b); | ||
external int get a; | ||
external int get b; | ||
} | ||
|
||
// JS object literals | ||
@JS() | ||
@anonymous | ||
class LiteralA { | ||
external int get x; | ||
} | ||
|
||
@JS() | ||
@anonymous | ||
class LiteralB { | ||
external int get y; | ||
} | ||
|
||
// Library is annotated with JS so we don't need the annotation here. | ||
external LiteralA get a; | ||
external LiteralB get b; | ||
|
||
void main() { | ||
eval(r""" | ||
function Foo(a) { | ||
this.a = a; | ||
} | ||
function Bar(a) { | ||
this.a = a; | ||
} | ||
function Baz(a, b) { | ||
Foo.call(this, a); | ||
this.b = b; | ||
} | ||
Baz.prototype.__proto__ = Foo.prototype; | ||
var a = { | ||
x: 1, | ||
}; | ||
var b = { | ||
y: 2, | ||
}; | ||
"""); | ||
|
||
// JS class object can be checked and casted with itself. | ||
var foo = Foo(42); | ||
expect(foo is Foo, isTrue); | ||
expect(() => (foo as Foo), returnsNormally); | ||
|
||
// Try it with dynamic. | ||
dynamic d = Foo(42); | ||
expect(d is Foo, isTrue); | ||
expect(() => (d as Foo), returnsNormally); | ||
|
||
// Casts are allowed between any JS class objects. | ||
expect(foo is Bar, isTrue); | ||
expect(d is Bar, isTrue); | ||
expect(() => (foo as Bar), returnsNormally); | ||
expect(() => (d as Bar), returnsNormally); | ||
|
||
// Type-checking and casting works regardless of the inheritance chain. | ||
var baz = Baz(42, 43); | ||
expect(baz is Foo, isTrue); | ||
expect(() => (baz as Foo), returnsNormally); | ||
expect(foo is Baz, isTrue); | ||
expect(() => (foo as Baz), returnsNormally); | ||
|
||
// BarCopy is the same JS class as Bar. | ||
var barCopy = BarCopy(42); | ||
expect(barCopy is Bar, isTrue); | ||
expect(() => (barCopy as Bar), returnsNormally); | ||
|
||
// JS object literal can be checked and casted with itself. | ||
expect(a is LiteralA, isTrue); | ||
expect(() => (a as LiteralA), returnsNormally); | ||
|
||
// Like class objects, casts are allowed between any object literals. | ||
expect(a is LiteralB, isTrue); | ||
expect(() => (a as LiteralB), returnsNormally); | ||
|
||
// Similarly, casts are allowed between any class objects and object literals. | ||
expect(foo is LiteralB, isTrue); | ||
expect(() => (foo as LiteralB), returnsNormally); | ||
expect(a is Foo, isTrue); | ||
expect(() => (a as Foo), returnsNormally); | ||
} |