mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:47:03 +00:00
da01ce02fc
Changes in type hierarchy will have JavaScriptObject as the new parent class of interop and native types instead. Also modifies js_interop_constructor_name tests to reflect addition of static interop. Change-Id: I74957ca89aea1726a01e0677548fbb3c5c981323 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215949 Reviewed-by: Sigmund Cherem <sigmund@google.com> Reviewed-by: Mayank Patke <fishythefish@google.com>
177 lines
4.7 KiB
Dart
177 lines
4.7 KiB
Dart
// Copyright (c) 2015, 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.
|
|
|
|
import "native_testing.dart";
|
|
import 'dart:_foreign_helper' show JS_INTERCEPTOR_CONSTANT;
|
|
import 'dart:_interceptors'
|
|
show
|
|
Interceptor,
|
|
LegacyJavaScriptObject,
|
|
PlainJavaScriptObject,
|
|
UnknownJavaScriptObject;
|
|
|
|
// Test for safe formatting of JavaScript objects by Error.safeToString.
|
|
|
|
@Native('PPPP')
|
|
class Purple {}
|
|
|
|
@Native('QQQQ')
|
|
class Q {}
|
|
|
|
@Native('RRRR')
|
|
class Rascal {
|
|
toString() => 'RRRRRRRR';
|
|
}
|
|
|
|
makeA() native;
|
|
makeB() native;
|
|
makeC() native;
|
|
makeD() native;
|
|
makeE() native;
|
|
makeP() native;
|
|
makeQ() native;
|
|
makeR() native;
|
|
|
|
void setup() {
|
|
JS('', r"""
|
|
(function(){
|
|
self.makeA = function(){return {hello: 123};};
|
|
|
|
function BB(){}
|
|
self.makeB = function(){return new BB();};
|
|
|
|
function CC(){}
|
|
self.makeC = function(){
|
|
var x = new CC();
|
|
x.constructor = null; // Foils constructor lookup.
|
|
return x;
|
|
};
|
|
|
|
function DD(){}
|
|
self.makeD = function(){
|
|
var x = new DD();
|
|
x.constructor = {name: 'DDxxx'}; // Foils constructor lookup.
|
|
return x;
|
|
};
|
|
|
|
function EE(){}
|
|
self.makeE = function(){
|
|
var x = new EE();
|
|
x.constructor = function Liar(){}; // Looks like a legitimate constructor.
|
|
return x;
|
|
};
|
|
|
|
function PPPP(){}
|
|
self.makeP = function(){return new PPPP();};
|
|
|
|
function QQQQ(){}
|
|
self.makeQ = function(){return new QQQQ();};
|
|
|
|
function RRRR(){}
|
|
self.makeR = function(){return new RRRR();};
|
|
|
|
self.nativeConstructor(PPPP);
|
|
self.nativeConstructor(QQQQ);
|
|
self.nativeConstructor(RRRR);
|
|
})()""");
|
|
applyTestExtensions(['PPPP', 'QQQQ', 'RRRR']);
|
|
}
|
|
|
|
expectTypeName(expectedName, s) {
|
|
var m = new RegExp(r"Instance of '(.*)'").firstMatch(s);
|
|
Expect.isNotNull(m);
|
|
var name = m!.group(1);
|
|
Expect.isTrue(
|
|
expectedName == name ||
|
|
name!.length <= 3 ||
|
|
name!.startsWith('minified:'),
|
|
"Is '$expectedName' or minified: '$name'");
|
|
}
|
|
|
|
final plainJsString =
|
|
Error.safeToString(JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject));
|
|
|
|
final unknownJsString =
|
|
Error.safeToString(JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject));
|
|
|
|
final interceptorString =
|
|
Error.safeToString(JS_INTERCEPTOR_CONSTANT(Interceptor));
|
|
|
|
testDistinctInterceptors() {
|
|
// Test invariants needed for the other tests.
|
|
|
|
Expect.notEquals(plainJsString, unknownJsString);
|
|
Expect.notEquals(plainJsString, interceptorString);
|
|
Expect.notEquals(unknownJsString, interceptorString);
|
|
|
|
expectTypeName('PlainJavaScriptObject', plainJsString);
|
|
expectTypeName('UnknownJavaScriptObject', unknownJsString);
|
|
expectTypeName('Interceptor', interceptorString);
|
|
|
|
// Sometimes interceptor *objects* are used instead of the prototypes. Check
|
|
// these work too.
|
|
var plain2 = Error.safeToString(const PlainJavaScriptObject());
|
|
Expect.equals(plainJsString, plain2);
|
|
|
|
var unk2 = Error.safeToString(const UnknownJavaScriptObject());
|
|
Expect.equals(unknownJsString, unk2);
|
|
}
|
|
|
|
testExternal() {
|
|
var x = makeA();
|
|
Expect.equals(plainJsString, Error.safeToString(x));
|
|
|
|
x = makeB();
|
|
// Gets name from constructor, regardless of minification.
|
|
Expect.equals("Instance of 'BB'", Error.safeToString(x));
|
|
|
|
x = makeC();
|
|
Expect.equals(unknownJsString, Error.safeToString(x));
|
|
|
|
x = makeD();
|
|
Expect.equals(unknownJsString, Error.safeToString(x));
|
|
|
|
x = makeE();
|
|
Expect.equals("Instance of 'Liar'", Error.safeToString(x));
|
|
}
|
|
|
|
testNative() {
|
|
var x = makeP();
|
|
Expect.isTrue(x is Purple); // This test forces Purple to be distinguished.
|
|
Expect.notEquals(plainJsString, Error.safeToString(x));
|
|
Expect.notEquals(unknownJsString, Error.safeToString(x));
|
|
Expect.notEquals(interceptorString, Error.safeToString(x));
|
|
// And not the native class constructor.
|
|
Expect.notEquals("Instance of 'PPPP'", Error.safeToString(x));
|
|
expectTypeName('Purple', Error.safeToString(x));
|
|
|
|
x = makeQ();
|
|
print('Q: $x ${Error.safeToString(x)}');
|
|
// We are going to get either the general interceptor or the JavaScript
|
|
// constructor.
|
|
Expect.isTrue("Instance of 'QQQQ'" == Error.safeToString(x) ||
|
|
interceptorString == Error.safeToString(x));
|
|
|
|
x = makeR();
|
|
|
|
// Rascal overrides 'toString'. The toString() call causes Rascal to be
|
|
// distinguished.
|
|
x.toString();
|
|
Expect.notEquals(plainJsString, Error.safeToString(x));
|
|
Expect.notEquals(unknownJsString, Error.safeToString(x));
|
|
Expect.notEquals(interceptorString, Error.safeToString(x));
|
|
// And not the native class constructor.
|
|
Expect.notEquals("Instance of 'RRRR'", Error.safeToString(x));
|
|
expectTypeName('Rascal', Error.safeToString(x));
|
|
}
|
|
|
|
main() {
|
|
nativeTesting();
|
|
setup();
|
|
|
|
testDistinctInterceptors();
|
|
testExternal();
|
|
testNative();
|
|
}
|