Skip to content

Commit d3bb9c1

Browse files
authored
#3180. Add @JS() annotation tests. Part 4. (#3270)
Add `@JS()` annotation tests. Part 4.
1 parent 7be0e41 commit d3bb9c1

File tree

7 files changed

+329
-2
lines changed

7 files changed

+329
-2
lines changed

LibTest/js_interop/JS/js_A03_t05.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ void complete(String value) {
3232
main() {
3333
globalContext["complete"] = complete.toJS;
3434
eval(r'''
35-
var lib1;
3635
(async () => {
37-
lib1 = await import('/root_dart/tests/co19/src/LibTest/js_interop/module.js');
36+
globalThis.lib1 =
37+
await import('/root_dart/tests/co19/src/LibTest/js_interop/module.js');
3838
})().then(function(v) {
3939
globalThis.complete("");
4040
});

LibTest/js_interop/JS/js_A03_t06.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 An annotation on a JavaScript interop declaration.
6+
///
7+
/// This annotation defines a given library, top-level external declaration, or
8+
/// extension type as a JavaScript interop declaration.
9+
///
10+
/// @description Check that a library directive can be annotated with a `@JS()`
11+
/// annotation. Test renaming a top-level function.
12+
/// @author [email protected]
13+
14+
@JS("lib1")
15+
library;
16+
17+
import 'dart:async';
18+
import 'dart:js_interop';
19+
import 'dart:js_interop_unsafe';
20+
import '../../../Utils/expect.dart';
21+
import '../js_utils.dart';
22+
23+
@JS("answer")
24+
external int myAnswer();
25+
26+
final completer = Completer<String>();
27+
28+
void complete(String value) {
29+
completer.complete(value);
30+
}
31+
32+
main() {
33+
globalContext["complete"] = complete.toJS;
34+
eval(r'''
35+
(async () => {
36+
globalThis.lib1 =
37+
await import('/root_dart/tests/co19/src/LibTest/js_interop/module.js');
38+
})().then(function(v) {
39+
globalThis.complete("");
40+
});
41+
''');
42+
asyncStart();
43+
completer.future.then((_) {
44+
Expect.equals(42, myAnswer()); // calls lib1.answer()
45+
asyncEnd();
46+
});
47+
}

LibTest/js_interop/JS/js_A03_t07.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 An annotation on a JavaScript interop declaration.
6+
///
7+
/// This annotation defines a given library, top-level external declaration, or
8+
/// extension type as a JavaScript interop declaration.
9+
///
10+
/// @description Check that a library directive can be annotated with a `@JS()`
11+
/// annotation. Test an extension type.
12+
/// @author [email protected]
13+
14+
@JS("lib1")
15+
library;
16+
17+
import 'dart:async';
18+
import 'dart:js_interop';
19+
import 'dart:js_interop_unsafe';
20+
import '../../../Utils/expect.dart';
21+
import '../js_utils.dart';
22+
23+
extension type C(JSObject v) implements JSObject {
24+
external String foo();
25+
external static String bar();
26+
}
27+
28+
final completer = Completer<String>();
29+
30+
void complete(String value) {
31+
completer.complete(value);
32+
}
33+
34+
main() {
35+
globalContext["complete"] = complete.toJS;
36+
eval(r'''
37+
(async () => {
38+
globalThis.lib1 =
39+
await import('/root_dart/tests/co19/src/LibTest/js_interop/module.js');
40+
})().then(function(v) {
41+
globalThis.c = new globalThis.C();
42+
globalThis.complete("");
43+
});
44+
''');
45+
asyncStart();
46+
completer.future.then((_) {
47+
C c = C(globalContext["c"] as JSObject);
48+
Expect.equals("C.foo() from module.js", c.foo());
49+
Expect.equals("C.bar() from module.js", C.bar());
50+
asyncEnd();
51+
});
52+
}

LibTest/js_interop/JS/js_A03_t08.dart

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 An annotation on a JavaScript interop declaration.
6+
///
7+
/// This annotation defines a given library, top-level external declaration, or
8+
/// extension type as a JavaScript interop declaration.
9+
///
10+
/// @description Check that a library directive can be annotated with a `@JS()`
11+
/// annotation. Test an extension type with rename.
12+
/// @author [email protected]
13+
14+
@JS("lib1")
15+
library;
16+
17+
import 'dart:async';
18+
import 'dart:js_interop';
19+
import 'dart:js_interop_unsafe';
20+
import '../../../Utils/expect.dart';
21+
import '../js_utils.dart';
22+
23+
@JS("C")
24+
extension type A(JSObject v) implements JSObject {
25+
@JS("foo")
26+
external String myFoo();
27+
@JS("bar")
28+
external static String myBar();
29+
}
30+
31+
final completer = Completer<String>();
32+
33+
void complete(String value) {
34+
completer.complete(value);
35+
}
36+
37+
main() {
38+
globalContext["complete"] = complete.toJS;
39+
eval(r'''
40+
(async () => {
41+
globalThis.lib1 =
42+
await import('/root_dart/tests/co19/src/LibTest/js_interop/module.js');
43+
})().then(function(v) {
44+
globalThis.c = new globalThis.C();
45+
globalThis.complete("");
46+
});
47+
''');
48+
asyncStart();
49+
completer.future.then((_) {
50+
A c = A(globalContext["c"] as JSObject);
51+
Expect.equals("C.foo() from module.js", c.myFoo());
52+
Expect.equals("C.bar() from module.js", A.myBar());
53+
asyncEnd();
54+
});
55+
}

LibTest/js_interop/JS/js_A04_t01.dart

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 An annotation on a JavaScript interop declaration.
6+
/// ...
7+
/// Specifying name customizes the JavaScript name to use, which can be used in
8+
/// the following scenarios:
9+
/// - Adding a JavaScript prefix to all the external top-level declarations,
10+
/// static members, and constructors of a library by parameterizing the
11+
/// annotation on the library with `name`.
12+
/// - Specifying the JavaScript class to use for external static members and
13+
/// constructors of an interop extension type by parameterizing the annotation
14+
/// on the interop extension type with `name`.
15+
/// - Renaming external declarations by parameterizing the annotation on the
16+
/// member with `name`.
17+
///
18+
/// @description Check that `@JS("")` is equivalent to `@JS()`.
19+
/// @author [email protected]
20+
21+
@JS("")
22+
library;
23+
24+
import 'dart:js_interop';
25+
import 'dart:js_interop_unsafe';
26+
import '../../../Utils/expect.dart';
27+
import '../js_utils.dart';
28+
29+
@JS("")
30+
external int f1();
31+
32+
@JS("")
33+
extension type ET1(JSObject _) implements JSObject {
34+
external String f2();
35+
external static String f3();
36+
}
37+
38+
extension type ET2(JSObject _) implements JSObject {
39+
@JS("")
40+
external String f4();
41+
42+
@JS("")
43+
external static String f5();
44+
}
45+
46+
main() {
47+
eval(r'''
48+
globalThis.f1 = function() {return 1;};
49+
50+
class ET1 {
51+
f2() {
52+
return "f2() from ET1";
53+
}
54+
static f3() {
55+
return "f3() from ET1";
56+
}
57+
}
58+
globalThis.ET1 = ET1;
59+
globalThis.et1 = new ET1();
60+
61+
class ET2 {
62+
f4() {
63+
return "f4() from ET2";
64+
}
65+
static f5() {
66+
return "f5() from ET2";
67+
}
68+
}
69+
globalThis.ET2 = ET2;
70+
globalThis.et2 = new ET2();
71+
''');
72+
Expect.equals(1, f1());
73+
74+
ET1 et1 = ET1(globalContext["et1"] as JSObject);
75+
Expect.equals("f2() from ET1", et1.f2());
76+
Expect.equals("f3() from ET1", ET1.f3());
77+
78+
ET2 et2 = ET2(globalContext["et2"] as JSObject);
79+
Expect.equals("f4() from ET2", et2.f4());
80+
Expect.equals("f5() from ET2", ET2.f5());
81+
}

LibTest/js_interop/JS/js_A04_t02.dart

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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 An annotation on a JavaScript interop declaration.
6+
/// ...
7+
/// Specifying name customizes the JavaScript name to use, which can be used in
8+
/// the following scenarios:
9+
/// - Adding a JavaScript prefix to all the external top-level declarations,
10+
/// static members, and constructors of a library by parameterizing the
11+
/// annotation on the library with `name`.
12+
/// - Specifying the JavaScript class to use for external static members and
13+
/// constructors of an interop extension type by parameterizing the annotation
14+
/// on the interop extension type with `name`.
15+
/// - Renaming external declarations by parameterizing the annotation on the
16+
/// member with `name`.
17+
///
18+
/// @description Check that `@JS(null)` is equivalent to `@JS()`.
19+
/// @author [email protected]
20+
21+
@JS(null)
22+
library;
23+
24+
import 'dart:js_interop';
25+
import 'dart:js_interop_unsafe';
26+
import '../../../Utils/expect.dart';
27+
import '../js_utils.dart';
28+
29+
@JS(null)
30+
external int f1();
31+
32+
@JS(null)
33+
extension type ET1(JSObject _) implements JSObject {
34+
external String f2();
35+
external static String f3();
36+
}
37+
38+
extension type ET2(JSObject _) implements JSObject {
39+
@JS(null)
40+
external String f4();
41+
42+
@JS(null)
43+
external static String f5();
44+
}
45+
46+
main() {
47+
eval(r'''
48+
globalThis.f1 = function() {return 1;};
49+
50+
class ET1 {
51+
f2() {
52+
return "f2() from ET1";
53+
}
54+
static f3() {
55+
return "f3() from ET1";
56+
}
57+
}
58+
globalThis.ET1 = ET1;
59+
globalThis.et1 = new ET1();
60+
61+
class ET2 {
62+
f4() {
63+
return "f4() from ET2";
64+
}
65+
static f5() {
66+
return "f5() from ET2";
67+
}
68+
}
69+
globalThis.ET2 = ET2;
70+
globalThis.et2 = new ET2();
71+
''');
72+
Expect.equals(1, f1());
73+
74+
ET1 et1 = ET1(globalContext["et1"] as JSObject);
75+
Expect.equals("f2() from ET1", et1.f2());
76+
Expect.equals("f3() from ET1", ET1.f3());
77+
78+
ET2 et2 = ET2(globalContext["et2"] as JSObject);
79+
Expect.equals("f4() from ET2", et2.f4());
80+
Expect.equals("f5() from ET2", ET2.f5());
81+
}

LibTest/js_interop/module.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,14 @@ export function B() {}
88
export function answer() {
99
return 42;
1010
}
11+
12+
export class C {
13+
foo() {
14+
return "C.foo() from module.js";
15+
}
16+
static bar() {
17+
return "C.bar() from module.js";
18+
}
19+
}
20+
21+
globalThis.C = C;

0 commit comments

Comments
 (0)