Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0e25306

Browse files
srujzscommit-bot@chromium.org
authored andcommitted
[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 <[email protected]> Reviewed-by: Sigmund Cherem <[email protected]>
1 parent b91ff15 commit 0e25306

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Tests `is` checks and `as` casts between various JS objects. Currently, all
6+
// checks and casts should be allowed between JS objects.
7+
8+
@JS()
9+
library is_check_and_as_cast_test;
10+
11+
import 'package:js/js.dart';
12+
import 'package:expect/minitest.dart';
13+
14+
@JS()
15+
external void eval(String code);
16+
17+
@JS()
18+
class Foo {
19+
external Foo(int a);
20+
external int get a;
21+
}
22+
23+
// Class with same structure as Foo but separate JS class.
24+
@JS()
25+
class Bar {
26+
external Bar(int a);
27+
external int get a;
28+
}
29+
30+
@JS('Bar')
31+
class BarCopy {
32+
external BarCopy(int a);
33+
external int get a;
34+
}
35+
36+
@JS()
37+
class Baz {
38+
external Baz(int a, int b);
39+
external int get a;
40+
external int get b;
41+
}
42+
43+
// JS object literals
44+
@JS()
45+
@anonymous
46+
class LiteralA {
47+
external int get x;
48+
}
49+
50+
@JS()
51+
@anonymous
52+
class LiteralB {
53+
external int get y;
54+
}
55+
56+
// Library is annotated with JS so we don't need the annotation here.
57+
external LiteralA get a;
58+
external LiteralB get b;
59+
60+
void main() {
61+
eval(r"""
62+
function Foo(a) {
63+
this.a = a;
64+
}
65+
function Bar(a) {
66+
this.a = a;
67+
}
68+
function Baz(a, b) {
69+
Foo.call(this, a);
70+
this.b = b;
71+
}
72+
Baz.prototype.__proto__ = Foo.prototype;
73+
var a = {
74+
x: 1,
75+
};
76+
var b = {
77+
y: 2,
78+
};
79+
""");
80+
81+
// JS class object can be checked and casted with itself.
82+
var foo = Foo(42);
83+
expect(foo is Foo, isTrue);
84+
expect(() => (foo as Foo), returnsNormally);
85+
86+
// Try it with dynamic.
87+
dynamic d = Foo(42);
88+
expect(d is Foo, isTrue);
89+
expect(() => (d as Foo), returnsNormally);
90+
91+
// Casts are allowed between any JS class objects.
92+
expect(foo is Bar, isTrue);
93+
expect(d is Bar, isTrue);
94+
expect(() => (foo as Bar), returnsNormally);
95+
expect(() => (d as Bar), returnsNormally);
96+
97+
// Type-checking and casting works regardless of the inheritance chain.
98+
var baz = Baz(42, 43);
99+
expect(baz is Foo, isTrue);
100+
expect(() => (baz as Foo), returnsNormally);
101+
expect(foo is Baz, isTrue);
102+
expect(() => (foo as Baz), returnsNormally);
103+
104+
// BarCopy is the same JS class as Bar.
105+
var barCopy = BarCopy(42);
106+
expect(barCopy is Bar, isTrue);
107+
expect(() => (barCopy as Bar), returnsNormally);
108+
109+
// JS object literal can be checked and casted with itself.
110+
expect(a is LiteralA, isTrue);
111+
expect(() => (a as LiteralA), returnsNormally);
112+
113+
// Like class objects, casts are allowed between any object literals.
114+
expect(a is LiteralB, isTrue);
115+
expect(() => (a as LiteralB), returnsNormally);
116+
117+
// Similarly, casts are allowed between any class objects and object literals.
118+
expect(foo is LiteralB, isTrue);
119+
expect(() => (foo as LiteralB), returnsNormally);
120+
expect(a is Foo, isTrue);
121+
expect(() => (a as Foo), returnsNormally);
122+
}

0 commit comments

Comments
 (0)