Skip to content

Commit ed1be95

Browse files
authored
#3180. Add interop types tests. Part 1. (#3279)
1 parent 7ff6839 commit ed1be95

9 files changed

+561
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that it is a compile-time error if a JS interop type
11+
/// member contains Dart [Object] or a type parameter with [Object] as a bound
12+
/// in its signature.
13+
/// @author [email protected]
14+
15+
import 'dart:js_interop';
16+
17+
extension type ET._(JSObject _) implements JSObject {
18+
external ET.fromDartObject(Object value);
19+
// ^^^^^^
20+
// [analyzer] unspecified
21+
// [web] unspecified
22+
23+
external Object foo();
24+
// ^^^^^^
25+
// [analyzer] unspecified
26+
// [web] unspecified
27+
28+
external void bar(Object _);
29+
// ^^^^^^
30+
// [analyzer] unspecified
31+
// [web] unspecified
32+
}
33+
34+
@JS('ET')
35+
extension type ET2<T extends Object>._(JSObject _) implements JSObject {
36+
external factory ET2.fromDartObject(T value);
37+
// ^
38+
// [analyzer] unspecified
39+
// [web] unspecified
40+
41+
external T foo();
42+
// ^
43+
// [analyzer] unspecified
44+
// [web] unspecified
45+
46+
external void bar(T _);
47+
// ^
48+
// [analyzer] unspecified
49+
// [web] unspecified
50+
}
51+
52+
main() {
53+
print(ET);
54+
print(ET2);
55+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that it is a compile-time error if a JS interop type
11+
/// member contains in its signature an extension type with Dart [Object] as a
12+
/// representation type.
13+
/// @author [email protected]
14+
15+
import 'dart:js_interop';
16+
17+
extension type ObjectET1(Object o) implements Object {}
18+
19+
extension type ObjectET2(Object o) {}
20+
21+
extension type ET._(JSObject _) implements JSObject {
22+
external ET.fromDartObject(ObjectET1 value);
23+
// ^^^^^^^^^
24+
// [analyzer] unspecified
25+
// [web] unspecified
26+
27+
external ObjectET1 foo();
28+
// ^^^^^^^^^
29+
// [analyzer] unspecified
30+
// [web] unspecified
31+
32+
external void bar(ObjectET1 _);
33+
// ^^^^^^^^^
34+
// [analyzer] unspecified
35+
// [web] unspecified
36+
}
37+
38+
@JS('ET')
39+
extension type ET2._(JSObject _) implements JSObject {
40+
external ET2.fromDartObject(ObjectET2 value);
41+
// ^^^^^^^^^
42+
// [analyzer] unspecified
43+
// [web] unspecified
44+
45+
external ObjectET2 foo();
46+
// ^^^^^^^^^
47+
// [analyzer] unspecified
48+
// [web] unspecified
49+
50+
external void bar(ObjectET2 _);
51+
// ^^^^^^^^^
52+
// [analyzer] unspecified
53+
// [web] unspecified
54+
}
55+
56+
main() {
57+
print(ET);
58+
print(ET2);
59+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that it is a compile-time error if a JS interop type
11+
/// member contains Dart [dynamic] or a type parameter with [dynamic] as a bound
12+
/// in its signature.
13+
/// @author [email protected]
14+
15+
import 'dart:js_interop';
16+
17+
extension type ET._(JSObject _) implements JSObject {
18+
external ET.fromDart(dynamic value);
19+
// ^^^^^^^
20+
// [analyzer] unspecified
21+
// [web] unspecified
22+
23+
external dynamic foo();
24+
// ^^^^^^^
25+
// [analyzer] unspecified
26+
// [web] unspecified
27+
28+
external void bar(dynamic _);
29+
// ^^^^^^^
30+
// [analyzer] unspecified
31+
// [web] unspecified
32+
}
33+
34+
@JS('ET')
35+
extension type ET2<T extends dynamic>._(JSObject _) implements JSObject {
36+
external factory ET2.fromDart(T value);
37+
// ^
38+
// [analyzer] unspecified
39+
// [web] unspecified
40+
41+
external T foo();
42+
// ^
43+
// [analyzer] unspecified
44+
// [web] unspecified
45+
46+
external void bar(T _);
47+
// ^
48+
// [analyzer] unspecified
49+
// [web] unspecified
50+
}
51+
52+
@JS('ET')
53+
extension type ET3._(JSObject _) implements JSObject {
54+
external ET3.fromDartDynamic(value);
55+
// ^^^^^
56+
// [analyzer] unspecified
57+
// [web] unspecified
58+
external factory ET3.fromDart(value);
59+
// ^^^^^
60+
// [analyzer] unspecified
61+
// [web] unspecified
62+
63+
external foo();
64+
// ^
65+
// [analyzer] unspecified
66+
// [web] unspecified
67+
68+
external void bar(_);
69+
// ^
70+
// [analyzer] unspecified
71+
// [web] unspecified
72+
}
73+
74+
main() {
75+
print(ET);
76+
print(ET2);
77+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that a JS interop type member may contain JS types from
11+
/// 'dart:js_interop' in its signature.
12+
/// @author [email protected]
13+
14+
import 'dart:js_interop';
15+
import 'dart:js_interop_unsafe';
16+
import '../../Utils/expect.dart';
17+
import 'js_utils.dart';
18+
19+
extension type ET._(JSObject _) implements JSObject {
20+
external ET.c(JSNumber v1);
21+
external factory ET.f(JSNumber v1, JSBigInt v2);
22+
23+
external JSNumber v1;
24+
external JSBigInt v2;
25+
external JSString v;
26+
external JSBoolean foo();
27+
external void bar(JSString _);
28+
external JSSymbol baz(JSSymbol _);
29+
}
30+
31+
main() {
32+
eval(r'''
33+
class ET {
34+
constructor(v1, v2) {
35+
this.v1 = v1;
36+
this.v2 = v2;
37+
}
38+
foo() {
39+
return true;
40+
}
41+
bar(v) {
42+
this.v = v;
43+
}
44+
baz(val) {
45+
return val;
46+
}
47+
}
48+
globalThis.ET = ET;
49+
globalThis.bi = 123n;
50+
globalThis.smb = Symbol('$name');
51+
''');
52+
ET et1 = ET.c(1.toJS);
53+
Expect.equals(1, et1.v1.toDartInt);
54+
Expect.isTrue(et1.foo().toDart);
55+
et1.bar("x".toJS);
56+
Expect.equals("x", et1.v.toDart);
57+
58+
ET et2 = ET.f(2.toJS, (globalContext["bi"] as JSBigInt));
59+
Expect.equals(2, et2.v1.toDartInt);
60+
Expect.equals(123.toString(), et2.v2.toString());
61+
var smb = globalContext["smb"] as JSSymbol;
62+
Expect.equals(smb, et2.baz(smb));
63+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that a JS interop type member may contain an
11+
/// `ExternalDartReference` in its signature.
12+
/// @author [email protected]
13+
14+
import 'dart:js_interop';
15+
import '../../Utils/expect.dart';
16+
import 'js_utils.dart';
17+
18+
class C {
19+
int id;
20+
String name;
21+
C(this.id, this.name);
22+
}
23+
24+
extension type ET._(JSObject _) implements JSObject {
25+
external ET.fromDart(ExternalDartReference<C> v);
26+
external factory ET.fromDartFactory(ExternalDartReference<C> v);
27+
28+
external ExternalDartReference<C> foo();
29+
external ExternalDartReference<C> bar(ExternalDartReference<C> _);
30+
}
31+
32+
main() {
33+
eval(r'''
34+
class ET {
35+
constructor(v) {
36+
this.v = v;
37+
}
38+
foo() {
39+
return this.v;
40+
}
41+
bar(v) {
42+
return v;
43+
}
44+
}
45+
globalThis.ET = ET;
46+
''');
47+
C c1 = C(42, "Object from Dart");
48+
ET et1 = ET.fromDart(c1.toExternalReference);
49+
ExternalDartReference<C> ref1 = et1.foo();
50+
Expect.equals(42, ref1.toDartObject.id);
51+
Expect.equals("Object from Dart", ref1.toDartObject.name);
52+
var ref2 = et1.bar(c1.toExternalReference);
53+
Expect.equals(42, ref2.toDartObject.id);
54+
Expect.equals("Object from Dart", ref2.toDartObject.name);
55+
56+
C c2 = C(1, "one");
57+
ET et2 = ET.fromDartFactory(c2.toExternalReference);
58+
ExternalDartReference<C> ref3 = et2.foo();
59+
Expect.equals(1, ref3.toDartObject.id);
60+
Expect.equals("one", ref3.toDartObject.name);
61+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) 2025, 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+
/// @assertion When interacting with a JS value, you need to provide a Dart type
6+
/// for it. You can do this by either using or declaring an interop type.
7+
/// Interop types are either a "JS type" provided by Dart or an extension type
8+
/// wrapping an interop type.
9+
///
10+
/// @description Check that a JS interop type member may contain Dart types
11+
/// `void`, `bool`, `num`, `double`, `int` and `String` in its signature.
12+
/// @author [email protected]
13+
14+
import 'dart:js_interop';
15+
import '../../Utils/expect.dart';
16+
import 'js_utils.dart';
17+
18+
extension type ET._(JSObject _) implements JSObject {
19+
external ET.fromDart(num v1);
20+
external factory ET.fromNum(int v1, double v2);
21+
22+
external num v1;
23+
external num v2;
24+
external String v;
25+
external bool foo();
26+
external void bar(String _);
27+
}
28+
29+
main() {
30+
eval(r'''
31+
class ET {
32+
constructor(v1, v2) {
33+
this.v1 = v1;
34+
this.v2 = v2;
35+
}
36+
foo() {
37+
return true;
38+
}
39+
bar(v) {
40+
this.v = v;
41+
}
42+
}
43+
globalThis.ET = ET;
44+
''');
45+
ET et1 = ET.fromDart(1);
46+
Expect.equals(1, et1.v1);
47+
Expect.isTrue(et1.foo());
48+
et1.bar("x");
49+
Expect.equals("x", et1.v);
50+
51+
ET et2 = ET.fromNum(2, 3);
52+
Expect.equals(2, et2.v1);
53+
Expect.equals(3, et2.v2);
54+
}

0 commit comments

Comments
 (0)