| // 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. | |
| // Requirements=checked-implicit-downcasts | |
| /// WARNING | |
| /// | |
| /// Not all of the expectations in this test match the language specification. | |
| /// | |
| /// This is part of a set of tests covering "callable objects". Please consider | |
| /// them all together when making changes: | |
| /// | |
| /// ``` | |
| /// tests/lib/js/static_interop_test/call_getter_test.dart | |
| /// tests/lib/js/static_interop_test/call_method_test.dart | |
| /// ``` | |
| /// | |
| /// This test was created with expectations that match the current behavior to | |
| /// make it more clear when something changes and when the results in the web | |
| /// compilers differ. | |
| /// | |
| /// If your change causes an expectation to fail you should decide if the | |
| /// new result is desirable and update the expectation accordingly. | |
| import 'dart:js_interop'; | |
| import 'package:expect/expect.dart'; | |
| import 'call_utils.dart'; | |
| @JS('jsFunction') | |
| external JSFunction get jsFunctionAsJSFunction; | |
| @JS('jsObject') | |
| external JSFunction get jsObjectAsJSFunction; | |
| @JS('jsClass') | |
| external JSFunction get jsClassAsJSFunction; | |
| extension on JSFunction { | |
| @JS('call') | |
| external String _call(JSAny? self, String s); | |
| String call(String s) => _call(globalContext, s); | |
| } | |
| extension type ExtOnJSObject._(JSObject _) implements JSObject { | |
| external String call(String s); | |
| } | |
| @JS('jsFunction') | |
| external ExtOnJSObject get jsFunctionAsExtOnJSObject; | |
| @JS('jsObject') | |
| external ExtOnJSObject get jsObjectAsExtOnJSObject; | |
| @JS('jsClass') | |
| external ExtOnJSObject get jsClassAsExtOnJSObject; | |
| extension type ExtOnJSFunction._(JSFunction _) implements JSFunction { | |
| external String call(String s); | |
| } | |
| @JS('jsFunction') | |
| external ExtOnJSFunction get jsFunctionAsExtOnJSFunction; | |
| @JS('jsObject') | |
| external ExtOnJSFunction get jsObjectAsExtOnJSFunction; | |
| @JS('jsClass') | |
| external ExtOnJSFunction get jsClassAsExtOnJSFunction; | |
| void main() { | |
| injectJS(); | |
| testJSFunction(); | |
| testExtOnJSObject(); | |
| testExtOnJSFunction(); | |
| testAsDynamic(); | |
| } | |
| void testJSFunction() { | |
| var obj = jsFunctionAsJSFunction; | |
| Expect.equals( | |
| 'C', | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.equals('C', obj.call('Cello')); | |
| Expect.equals('C', (obj.call)('Cello')); | |
| Expect.equals('C', obj('Cello')); | |
| if (dart2wasm) { | |
| obj = jsObjectAsJSFunction; | |
| Expect.throws( | |
| () => | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.throws(() => obj.call('Cello')); | |
| Expect.throws(() => (obj.call)('Cello')); | |
| Expect.throws(() => obj('Cello')); | |
| } else { | |
| Expect.throwsTypeError(() => jsObjectAsJSFunction); | |
| } | |
| if (dart2wasm) { | |
| obj = jsClassAsJSFunction; | |
| Expect.throws( | |
| () => | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.throws(() => obj.call('Cello')); | |
| Expect.throws(() => (obj.call)('Cello')); | |
| Expect.throws(() => obj('Cello')); | |
| } else { | |
| Expect.throwsTypeError(() => jsClassAsJSFunction); | |
| } | |
| } | |
| void testExtOnJSObject() { | |
| var obj = jsFunctionAsExtOnJSObject; | |
| Expect.throws( | |
| () => obj.call('Cello'), | |
| dart2wasm ? null : jsArgIsNotStringCheck, | |
| ); | |
| Expect.throws(() => obj('Cello'), dart2wasm ? null : jsArgIsNotStringCheck); | |
| obj = jsObjectAsExtOnJSObject; | |
| Expect.equals('C', obj.call('Cello')); | |
| Expect.equals('C', obj('Cello')); | |
| obj = jsClassAsExtOnJSObject; | |
| Expect.equals('C', obj.call('Cello')); | |
| Expect.equals('C', obj('Cello')); | |
| } | |
| void testExtOnJSFunction() { | |
| var obj = jsFunctionAsExtOnJSFunction; | |
| Expect.equals( | |
| 'C', | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.throws( | |
| () => obj.call('Cello'), | |
| dart2wasm ? null : jsArgIsNotStringCheck, | |
| ); | |
| Expect.throws(() => obj('Cello'), dart2wasm ? null : jsArgIsNotStringCheck); | |
| if (dart2wasm) { | |
| obj = jsObjectAsExtOnJSFunction; | |
| Expect.throws( | |
| () => | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.equals('C', obj.call('Cello')); | |
| Expect.equals('C', obj('Cello')); | |
| } else { | |
| Expect.throwsTypeError(() => jsObjectAsExtOnJSFunction); | |
| } | |
| if (dart2wasm) { | |
| obj = jsClassAsExtOnJSFunction; | |
| Expect.throws( | |
| () => | |
| (obj.callAsFunction(globalContext, 'Cello'.toJS) as JSString).toDart, | |
| ); | |
| Expect.equals('C', obj.call('Cello')); | |
| Expect.equals('C', obj('Cello')); | |
| } else { | |
| Expect.throwsTypeError(() => jsClassAsExtOnJSFunction); | |
| } | |
| } | |
| testAsDynamic() { | |
| dynamic d = confuse(jsFunctionAsJSFunction); | |
| if (dart2wasm) { | |
| Expect.throwsNoSuchMethodError(() => d.call('Fosse')); | |
| } else { | |
| Expect.equals('F', d.call('Fosse')); | |
| } | |
| if (ddc) { | |
| Expect.equals('F', (d.call)('Fosse')); | |
| } else { | |
| Expect.throwsNoSuchMethodError(() => (d.call)('Fosse')); | |
| } | |
| if (dart2wasm) { | |
| Expect.throwsNoSuchMethodError(() => d('Fosse')); | |
| } else { | |
| Expect.equals('F', d('Fosse')); | |
| } | |
| d = confuse(jsObjectAsExtOnJSObject); | |
| Expect.throwsNoSuchMethodError(() => d.call('Fosse')); | |
| if (ddc) { | |
| Expect.equals('F', (d.call)('Fosse')); | |
| } else { | |
| Expect.throwsNoSuchMethodError(() => (d.call)('Fosse')); | |
| } | |
| Expect.throwsNoSuchMethodError(() => d('Fosse')); | |
| d = confuse(jsClassAsExtOnJSObject); | |
| Expect.throwsNoSuchMethodError(() => d.call('Fosse')); | |
| if (ddc) { | |
| Expect.throws(() => (d.call)('Fosse'), jsThisIsNullCheck); | |
| } else { | |
| Expect.throwsNoSuchMethodError(() => (d.call)('Fosse')); | |
| } | |
| Expect.throwsNoSuchMethodError(() => d('Fosse')); | |
| } |