From 07313b996d8dd525fb8d1c9d3825b2cbe87b4cde Mon Sep 17 00:00:00 2001 From: "Sergey G. Grekhov" Date: Wed, 27 Aug 2025 17:08:47 +0300 Subject: [PATCH 1/7] #3180. Add tests for `ObjectToJSBoxedDartObject` --- .../toJSBox_A01_t01.dart | 51 +++++++++++++++++++ .../toJSBox_A01_t02.dart | 29 +++++++++++ .../toJSBox_A01_t03.dart | 30 +++++++++++ .../toJSBox_A02_t01.dart | 49 ++++++++++++++++++ .../toJSBox_A02_t02.dart | 51 +++++++++++++++++++ 5 files changed, 210 insertions(+) create mode 100644 LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart create mode 100644 LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart create mode 100644 LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart create mode 100644 LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t01.dart create mode 100644 LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart new file mode 100644 index 0000000000..06c7b89751 --- /dev/null +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2025, 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. + +/// @assertion A JavaScript object that wraps this [Object]. +/// +/// There are no usable members in the resulting [JSBoxedDartObject] and you may +/// get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart +/// [Object]. +/// +/// Throws an [Exception] if this [Object] is a JavaScript value. +/// +/// Unlike [ObjectToExternalDartReference.toExternalReference], this returns a +/// JavaScript value. Therefore, the representation is guaranteed to be +/// consistent across all platforms and interop members can be declared on +/// [JSBoxedDartObjects]. +/// +/// @description Checks that this property returns a JavaScript object that +/// wraps this [Object]. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; +import '../../../Utils/expect.dart'; + +class C { + int id; + C(this.id); +} + +main() async { + var boxedString = "String".toJSBox; + Expect.equals("String", boxedString.toDart); + + var boxedNum = 42.toJSBox; + Expect.equals(42, boxedNum.toDart); + + var boxedBool = false.toJSBox; + Expect.isFalse(boxedBool.toDart); + + var boxedObject = C(42).toJSBox; + Expect.equals(42, (boxedObject.toDart as C).id); + + var boxedMap = {"key": "value"}.toJSBox; + Expect.mapEquals({"key": "value"}, boxedMap.toDart); + + var boxedSet = {42}.toJSBox; + Expect.setEquals({42}, boxedSet.toDart as Set); + + var boxedFuture = Future.value(42).toJSBox; + Expect.equals(42, await (boxedFuture.toDart as Future)); +} diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart new file mode 100644 index 0000000000..f9e10ac008 --- /dev/null +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2025, 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. + +/// @assertion A JavaScript object that wraps this [Object]. +/// +/// There are no usable members in the resulting [JSBoxedDartObject] and you may +/// get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart +/// [Object]. +/// +/// Throws an [Exception] if this [Object] is a JavaScript value. +/// +/// Unlike [ObjectToExternalDartReference.toExternalReference], this returns a +/// JavaScript value. Therefore, the representation is guaranteed to be +/// consistent across all platforms and interop members can be declared on +/// [JSBoxedDartObjects]. +/// +/// @description Checks that an [Exception] is thrown if this [Object] is a +/// JavaScript value. Test Dart [List]. +/// @author sgrekhov22@gmail.com +/// @issue 61405, 56905 + +import 'dart:js_interop'; +import '../../../Utils/expect.dart'; + +main() { + var boxedList = [42].toJSBox; + Expect.listEquals([42], boxedList.toDart); +} diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart new file mode 100644 index 0000000000..26d0a8e80d --- /dev/null +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2025, 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. + +/// @assertion A JavaScript object that wraps this [Object]. +/// +/// There are no usable members in the resulting [JSBoxedDartObject] and you may +/// get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart +/// [Object]. +/// +/// Throws an [Exception] if this [Object] is a JavaScript value. +/// +/// Unlike [ObjectToExternalDartReference.toExternalReference], this returns a +/// JavaScript value. Therefore, the representation is guaranteed to be +/// consistent across all platforms and interop members can be declared on +/// [JSBoxedDartObjects]. +/// +/// @description Checks that an [Exception] is thrown if this [Object] is a +/// JavaScript value. Test Dart typed list. +/// @author sgrekhov22@gmail.com +/// @issue 61405, 56905 + +import 'dart:typed_data'; +import 'dart:js_interop'; +import '../../../Utils/expect.dart'; + +main() { + var boxedInt8List = Int8List.fromList([42]).toJSBox; + Expect.listEquals([42], (boxedInt8List.toDart as Int8List).toList()); +} diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t01.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t01.dart new file mode 100644 index 0000000000..07d94730d9 --- /dev/null +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t01.dart @@ -0,0 +1,49 @@ +// Copyright (c) 2025, 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. + +/// @assertion A JavaScript object that wraps this [Object]. +/// +/// There are no usable members in the resulting [JSBoxedDartObject] and you may +/// get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart +/// [Object]. +/// +/// Throws an [Exception] if this [Object] is a JavaScript value. +/// +/// Unlike [ObjectToExternalDartReference.toExternalReference], this returns a +/// JavaScript value. Therefore, the representation is guaranteed to be +/// consistent across all platforms and interop members can be declared on +/// [JSBoxedDartObjects]. +/// +/// @description Checks that an [Exception] is thrown if this [Object] is a +/// JavaScript value. Test JS primitive types. +/// @author sgrekhov22@gmail.com +/// @issue 61405, 56905 + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import '../../../Utils/expect.dart'; +import '../js_utils.dart'; + +main() { + eval(r''' + globalThis.bi = 42n; + globalThis.s = Symbol("name"); + '''); + Expect.throws(() { + "String".toJS.toJSBox; + }); + + Expect.throws(() { + 42.toJS.toJSBox; + }); + Expect.throws(() { + true.toJS.toJSBox; + }); + Expect.throws(() { + (globalContext["bi"] as JSBigInt).toJSBox; + }); + Expect.throws(() { + (globalContext["s"] as JSSymbol).toJSBox; + }); +} diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart new file mode 100644 index 0000000000..13832a2b89 --- /dev/null +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart @@ -0,0 +1,51 @@ +// Copyright (c) 2025, 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. + +/// @assertion A JavaScript object that wraps this [Object]. +/// +/// There are no usable members in the resulting [JSBoxedDartObject] and you may +/// get a new [JSBoxedDartObject] when calling [toJSBox] on the same Dart +/// [Object]. +/// +/// Throws an [Exception] if this [Object] is a JavaScript value. +/// +/// Unlike [ObjectToExternalDartReference.toExternalReference], this returns a +/// JavaScript value. Therefore, the representation is guaranteed to be +/// consistent across all platforms and interop members can be declared on +/// [JSBoxedDartObjects]. +/// +/// @description Checks that an [Exception] is thrown if this [Object] is a +/// JavaScript value. Test non-primitive JS types. +/// @author sgrekhov22@gmail.com + +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import '../../../Utils/expect.dart'; +import '../js_utils.dart'; + +main() { + eval(r''' + globalThis.obj = {}; + '''); + Expect.throws(() { + JSArray().toJSBox; + }); + + Expect.throws(() { + JSObject().toJSBox; + }); + + Expect.throws(() { + (globalContext["obj"] as JSObject).toJSBox; + }); + + eval(r''' + globalThis.foo = function(resolve, reject) { + resolve("Success"); + }; + '''); + Expect.throws(() { + JSPromise(globalContext["foo"] as JSFunction).toJSBox; + }); +} From 922ebd7e384d535a78c4fe925b060edaca13ba10 Mon Sep 17 00:00:00 2001 From: "Sergey G. Grekhov" Date: Thu, 28 Aug 2025 10:47:21 +0300 Subject: [PATCH 2/7] Fix descriptions --- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart | 4 ++-- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart index f9e10ac008..600ccefb60 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart @@ -15,8 +15,8 @@ /// consistent across all platforms and interop members can be declared on /// [JSBoxedDartObjects]. /// -/// @description Checks that an [Exception] is thrown if this [Object] is a -/// JavaScript value. Test Dart [List]. +/// @description Checks that this property returns a JavaScript object that +/// wraps this [Object]. Test Dart [List]. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905 diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart index 26d0a8e80d..4b3fba7e84 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart @@ -15,8 +15,8 @@ /// consistent across all platforms and interop members can be declared on /// [JSBoxedDartObjects]. /// -/// @description Checks that an [Exception] is thrown if this [Object] is a -/// JavaScript value. Test Dart typed list. +/// @description Checks that this property returns a JavaScript object that +/// wraps this [Object]. Test Dart typed list. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905 From e4ff533f8df7595344035e3bf90b7236e6de296a Mon Sep 17 00:00:00 2001 From: "Sergey G. Grekhov" Date: Thu, 28 Aug 2025 10:54:53 +0300 Subject: [PATCH 3/7] Add check for `JSBoxedDartObject` --- .../ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart index 13832a2b89..a78ed2f951 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A02_t02.dart @@ -48,4 +48,9 @@ main() { Expect.throws(() { JSPromise(globalContext["foo"] as JSFunction).toJSBox; }); + + var boxedObject = Object().toJSBox; + Expect.throws(() { + boxedObject.toJSBox; + }); } From e95c3ef9abf6c72dfc72c9a3b1dacfa7c9df0248 Mon Sep 17 00:00:00 2001 From: "Sergey G. Grekhov" Date: Fri, 29 Aug 2025 14:06:34 +0300 Subject: [PATCH 4/7] Improve descriptions --- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart | 3 ++- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart | 3 ++- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart index 06c7b89751..d4786c7ade 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart @@ -16,7 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object]. +/// wraps this [Object] and the original Dart object can be unwrapped via ` +/// .toDart`. /// @author sgrekhov22@gmail.com import 'dart:js_interop'; diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart index 600ccefb60..2a4cb7dabd 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart @@ -16,7 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object]. Test Dart [List]. +/// wraps this [Object] and the original Dart object can be unwrapped via ` +/// .toDart`. Test Dart [List]. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905 diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart index 4b3fba7e84..927f52df45 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart @@ -16,7 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object]. Test Dart typed list. +/// wraps this [Object] and the original Dart object can be unwrapped via ` +/// .toDart`. Test Dart typed list. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905 From 3362048e96de1da6ff077237a00729e9eb18acb2 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Fri, 29 Aug 2025 13:30:41 +0200 Subject: [PATCH 5/7] Update toJSBox_A01_t01.dart --- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart index d4786c7ade..9a6749f83b 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t01.dart @@ -16,8 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object] and the original Dart object can be unwrapped via ` -/// .toDart`. +/// wraps this [Object] and the original Dart object can be unwrapped via +/// `.toDart`. /// @author sgrekhov22@gmail.com import 'dart:js_interop'; From 0c615c4f209ff4475a8f09875c69561744161ad4 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Fri, 29 Aug 2025 13:31:39 +0200 Subject: [PATCH 6/7] Update toJSBox_A01_t02.dart --- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart index 2a4cb7dabd..8a72098ff4 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t02.dart @@ -16,8 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object] and the original Dart object can be unwrapped via ` -/// .toDart`. Test Dart [List]. +/// wraps this [Object] and the original Dart object can be unwrapped via +/// `.toDart`. Test Dart [List]. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905 From e7fe15448786d99d715f7a389cda3d8e0e48f441 Mon Sep 17 00:00:00 2001 From: Erik Ernst Date: Fri, 29 Aug 2025 13:32:13 +0200 Subject: [PATCH 7/7] Update toJSBox_A01_t03.dart --- .../js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart index 927f52df45..3733f32e02 100644 --- a/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart +++ b/LibTest/js_interop/ObjectToJSBoxedDartObject/toJSBox_A01_t03.dart @@ -16,8 +16,8 @@ /// [JSBoxedDartObjects]. /// /// @description Checks that this property returns a JavaScript object that -/// wraps this [Object] and the original Dart object can be unwrapped via ` -/// .toDart`. Test Dart typed list. +/// wraps this [Object] and the original Dart object can be unwrapped via +/// `.toDart`. Test Dart typed list. /// @author sgrekhov22@gmail.com /// @issue 61405, 56905