From e661776f8096e236077e1160ec9badd57f57a671 Mon Sep 17 00:00:00 2001 From: Srujan Gaddam Date: Wed, 16 Oct 2024 18:18:23 +0000 Subject: [PATCH] [pkg:js] Add tests for allowInterop idempotency Closes https://github.com/dart-lang/sdk/issues/56897 Adds a few missing tests to make sure we handle already converted functions, Dart functions that were wrapped by a previous call, and JS functions correctly in allowInterop and allowInteropCaptureThis. Change-Id: Iaa6f34652717787fad8141ad941c47e944e70a5e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390400 Auto-Submit: Srujan Gaddam Commit-Queue: Srujan Gaddam Reviewed-by: Nicholas Shahan --- .../lib/js/allowInterop_idempotent_test.dart | 58 +++++++++++++++++++ tests/lib/lib.status | 1 + 2 files changed, 59 insertions(+) create mode 100644 tests/lib/js/allowInterop_idempotent_test.dart diff --git a/tests/lib/js/allowInterop_idempotent_test.dart b/tests/lib/js/allowInterop_idempotent_test.dart new file mode 100644 index 000000000000..b4b315381cde --- /dev/null +++ b/tests/lib/js/allowInterop_idempotent_test.dart @@ -0,0 +1,58 @@ +// Copyright (c) 2024, 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. + +// Test that `allowInterop` and `allowInteropCaptureThis` should be idempotent +// when given wrapped functions, JS functions, or Dart functions that were +// wrapped by a previous call. + +import 'package:expect/expect.dart'; +import 'package:js/js.dart'; + +const isDart2JS = const bool.fromEnvironment('dart.tool.dart2js'); + +@JS() +external void eval(String code); + +@JS() +external Function get jsFunction; + +void main() { + eval(''' + self.jsFunction = function() {}; + '''); + final dartFunction = (_) {}; + final wrappedFunction = allowInterop(dartFunction); + final wrappedFunctionCaptureThis = allowInteropCaptureThis(dartFunction); + // Should add a wrapper that's unique to the function. + Expect.notEquals(dartFunction, wrappedFunction); + Expect.notEquals(dartFunction, wrappedFunctionCaptureThis); + Expect.notEquals(wrappedFunction, wrappedFunctionCaptureThis); + // Should return the same value if the value is already a wrapped function. + Expect.equals(wrappedFunction, allowInterop(wrappedFunction)); + Expect.equals( + wrappedFunctionCaptureThis, allowInterop(wrappedFunctionCaptureThis)); + // Passing a non-Dart function to `allowInteropCaptureThis` throws in dart2js, + // so for now, capture the existing semantics. We may want to update DDC to + // match this. + if (isDart2JS) { + Expect.throws(() => allowInteropCaptureThis(wrappedFunction)); + Expect.throws(() => allowInteropCaptureThis(wrappedFunctionCaptureThis)); + } else { + Expect.equals(wrappedFunction, allowInteropCaptureThis(wrappedFunction)); + Expect.equals(wrappedFunctionCaptureThis, + allowInteropCaptureThis(wrappedFunctionCaptureThis)); + } + // Should directly return JS functions without doing anything. + Expect.equals(jsFunction, allowInterop(jsFunction)); + if (isDart2JS) { + Expect.throws(() => allowInteropCaptureThis(jsFunction)); + } else { + Expect.equals(jsFunction, allowInteropCaptureThis(jsFunction)); + } + // If `allowInterop`/`allowInteropCaptureThis` is called again on the same + // Dart value, should return the previously wrapped function. + Expect.equals(wrappedFunction, allowInterop(dartFunction)); + Expect.equals( + wrappedFunctionCaptureThis, allowInteropCaptureThis(dartFunction)); +} diff --git a/tests/lib/lib.status b/tests/lib/lib.status index f2c87743c48a..50145dd2c13a 100644 --- a/tests/lib/lib.status +++ b/tests/lib/lib.status @@ -54,6 +54,7 @@ html/xhr_test/xhr: Skip # Times out. Issue 21527 [ $csp ] html/js_interop_constructor_name/*: SkipByDesign # Issue 42085. isolate/deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode +js/allowInterop_idempotent_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/call_field_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/call_getter_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code js/call_method_test: SkipByDesign # Issue 42085. CSP policy disallows injected JS code