d17205184a
`dart:html` types have changed to inherit `JavaScriptObject`. Therefore, the dart2js runtime needs to be changed so that interceptors are still created for those types, and they're properly handled in `toString` calculations. Includes tests on `Object` members that are currently inconsistent between both compilers. This test passes on dart2js with and without making the types in `dart:html` extend `JavaScriptObject`. This test fails in DDC for the following reasons: - `toString` of native types calls the native `toString` - `hashCode` for interop objects are random and not 0 - `runtimeType` of interop objects is `LegacyJavaScriptObject` not `JSObject` Change-Id: Ibf80109174615120df9e64995fa13016f7a1677b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/228741 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Srujan Gaddam <srujzs@google.com>
81 lines
2.4 KiB
Dart
81 lines
2.4 KiB
Dart
// Copyright (c) 2022, 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.
|
|
|
|
// Make sure `Object` methods work as expected with `dart:html` and interop
|
|
// types. The expectations here aren't guarantees that they should work a
|
|
// particular way, but rather a way to monitor regressions/changes.
|
|
|
|
@JS()
|
|
library object_members_test;
|
|
|
|
import 'package:js/js.dart';
|
|
import 'package:expect/minitest.dart';
|
|
|
|
import 'dart:html';
|
|
import 'dart:_interceptors' show JSObject;
|
|
|
|
@JS()
|
|
external void eval(String code);
|
|
|
|
@JS()
|
|
class JSClass {
|
|
external JSClass();
|
|
}
|
|
|
|
void main() {
|
|
eval(r'''
|
|
function JSClass() {}
|
|
''');
|
|
|
|
// `dart:html` type.
|
|
var div = document.createElement('div');
|
|
expect(div == div, true);
|
|
expect(div == DomPointReadOnly(), false);
|
|
// Ensure that we get a random hash for each new instance. It should be
|
|
// improbable for this to fail across many runs if the hash is
|
|
// non-deterministic.
|
|
var hashCode = div.hashCode;
|
|
var attempts = 0;
|
|
var maxAttempts = 1000;
|
|
while (div.hashCode == hashCode && attempts < maxAttempts) {
|
|
div = document.createElement('div');
|
|
attempts++;
|
|
}
|
|
expect(attempts > 0 && attempts != maxAttempts, isTrue);
|
|
expect(div.toString, isNotNull);
|
|
expect(div.toString(), 'div');
|
|
expect(div.noSuchMethod, isNotNull);
|
|
var noSuchMethodErrorThrown = true;
|
|
try {
|
|
(div as dynamic).triggerNoSuchMethod();
|
|
noSuchMethodErrorThrown = false;
|
|
} catch (_) {}
|
|
expect(noSuchMethodErrorThrown, isTrue);
|
|
expect(div.runtimeType, DivElement);
|
|
|
|
// `toString` for `dart:html` types that do not have an overridden `toString`
|
|
// should look up the type through the proto.
|
|
expect(window.navigator.toString(), "Instance of 'Navigator'");
|
|
|
|
// Interop type.
|
|
var js = JSClass();
|
|
expect(js == js, true);
|
|
expect(js == JSClass(), false);
|
|
// TODO(srujzs): Modify this once interop has random hash codes.
|
|
hashCode = js.hashCode;
|
|
expect(hashCode, 0);
|
|
expect(hashCode, js.hashCode);
|
|
expect(js.toString, isNotNull);
|
|
// Should forward to underlying `toString` call.
|
|
expect(js.toString(), '[object Object]');
|
|
expect(js.noSuchMethod, isNotNull);
|
|
noSuchMethodErrorThrown = true;
|
|
try {
|
|
(js as dynamic).triggerNoSuchMethod();
|
|
noSuchMethodErrorThrown = false;
|
|
} catch (_) {}
|
|
expect(noSuchMethodErrorThrown, isTrue);
|
|
expect(js.runtimeType, JSObject);
|
|
}
|