Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(42)

Unified Diff: tests/html/js_util_test.dart

Issue 2150313003: Add JSNative utility class with static methods methods to efficiently manipulate typed JSInterop ob… (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix analyzer warnings in js_util_test, skip js_util_test in csp mode and baseline expectations for … Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tests/html/js_util_test.dart
diff --git a/tests/html/js_util_test.dart b/tests/html/js_util_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..b0130b24d6b6779daca7fbaa96e86cfc4d9f06f0
--- /dev/null
+++ b/tests/html/js_util_test.dart
@@ -0,0 +1,347 @@
+// Copyright (c) 2013, 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.
+
+@JS()
+library js_native_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'dart:typed_data' show ByteBuffer, Int32List;
+import 'dart:indexed_db' show IdbFactory, KeyRange;
+
+import 'package:js/js.dart';
+import 'package:js/js_util.dart' as js_util;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+
+_injectJs() {
+ final script = new ScriptElement();
+ script.type = 'text/javascript';
+ script.innerHtml = r"""
+var x = 42;
+
+var _x = 123;
+
+var myArray = ["value1"];
+
+function returnThis() {
+ return this;
+}
+
+function getTypeOf(o) {
+ return typeof(o);
+}
+
+function Foo(a) {
+ this.a = a;
+}
+
+Foo.b = 38;
+
+Foo.prototype.bar = function() {
+ return this.a;
+}
+Foo.prototype.toString = function() {
+ return "I'm a Foo a=" + this.a;
+}
+
+var container = new Object();
+container.Foo = Foo;
+
+function checkMap(m, key, value) {
+ if (m.hasOwnProperty(key))
+ return m[key] == value;
+ else
+ return false;
+}
+
+""";
+ document.body.append(script);
+}
+
+@JS()
+external bool checkMap(m, String, value);
+
+@JS('JSON.stringify')
+external String stringify(o);
+
+@JS('Node')
+external get JSNodeType;
+
+@JS('Element')
+external get JSElementType;
+
+@JS('Text')
+external get JSTextType;
+
+@JS('HTMLCanvasElement')
+external get JSHtmlCanvasElementType;
+
+@JS()
+class Foo {
+ external Foo(num a);
+
+ external num get a;
+ external num bar();
+}
+
+@JS('Foo')
+external get JSFooType;
+
+@JS()
+@anonymous
+class ExampleTypedLiteral {
+ external factory ExampleTypedLiteral({a, b, JS$_c, JS$class});
+
+ external get a;
+ external get b;
+ external get JS$_c;
+ external set JS$_c(v);
+ // Identical to JS$_c but only accessible within the library.
+ external get _c;
+ external get JS$class;
+ external set JS$class(v);
+}
+
+@JS("Object.prototype.hasOwnProperty")
+external get _hasOwnProperty;
+
+bool hasOwnProperty(o, String name) {
+ return js_util.callMethod(_hasOwnProperty, 'call', [o, name]);
+}
+
+main() {
+ _injectJs();
+ useHtmlIndividualConfiguration();
+
+ group('js_util.jsify()', () {
+ test('convert a List', () {
+ final list = [1, 2, 3, 4, 5, 6, 7, 8];
+ var array = js_util.jsify(list);
+ expect(array is List, isTrue);
+ expect(identical(array, list), isFalse);
+ expect(array.length, equals(list.length));
+ for (var i = 0; i < list.length; i++) {
+ expect(array[i], equals(list[i]));
+ }
+ });
+
+ test('convert an Iterable', () {
+ final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]);
+ var array = js_util.jsify(set);
+ expect(array is List, isTrue);
+ expect(array.length, equals(set.length));
+ for (var i = 0; i < array.length; i++) {
+ expect(set.contains(array[i]), isTrue);
+ }
+ });
+
+ test('convert a Map', () {
+ var map = {'a': 1, 'b': 2, 'c': 3};
+ var jsMap = js_util.jsify(map);
+ expect(jsMap is! List, isTrue);
+ for (var key in map.keys) {
+ expect(checkMap(jsMap, key, map[key]), isTrue);
+ }
+ });
+
+ test('deep convert a complex object', () {
+ final object = {
+ 'a': [
+ 1,
+ [2, 3]
+ ],
+ 'b': {'c': 3, 'd': new Foo(42)},
+ 'e': null
+ };
+ var jsObject = js_util.jsify(object);
+ expect(js_util.getProperty(jsObject, 'a')[0], equals(object['a'][0]));
+ expect(
+ js_util.getProperty(jsObject, 'a')[1][0], equals(object['a'][1][0]));
+ expect(
+ js_util.getProperty(jsObject, 'a')[1][1], equals(object['a'][1][1]));
+ expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'c'),
+ equals(object['b']['c']));
+ expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+ equals(object['b']['d']));
+ expect(
+ js_util.callMethod(
+ js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'),
+ 'bar', []),
+ equals(42));
+ expect(js_util.getProperty(jsObject, 'e'), isNull);
+ });
+
+ test('throws if object is not a Map or Iterable', () {
+ expect(() => js_util.jsify('a'),
+ throwsA(new isInstanceOf<ArgumentError>()));
+ });
+ });
+
+ group('js_util.newObject', () {
+ test('create', () {
+ expect(identical(js_util.newObject(), js_util.newObject()), isFalse);
+ });
+
+ test('callMethod', () {
+ var o = js_util.newObject();
+ expect(js_util.callMethod(o, 'toString', []), equals('[object Object]'));
+ expect(stringify(o), equals('{}'));
+ });
+
+ test('properties', () {
+ var o = js_util.newObject();
+ expect(js_util.hasProperty(o, 'foo bar'), isFalse);
+ expect(js_util.hasProperty(o, 'toString'), isTrue);
+ expect(hasOwnProperty(o, 'toString'), isFalse);
+ expect(hasOwnProperty(o, 'foo bar'), isFalse);
+ js_util.setProperty(o, 'foo bar', 42);
+ expect(hasOwnProperty(o, 'foo bar'), isTrue);
+ expect(js_util.getProperty(o, 'foo bar'), equals(42));
+ expect(js_util.hasProperty(o, 'foo bar'), isTrue);
+ expect(stringify(o), equals('{"foo bar":42}'));
+ });
+ });
+
+ group('hasProperty', () {
+ test('typed object', () {
+ var f = new Foo(42);
+ expect(js_util.hasProperty(f, 'a'), isTrue);
+ expect(js_util.hasProperty(f, 'toString'), isTrue);
+ js_util.setProperty(f, '__proto__', null);
+ expect(js_util.hasProperty(f, 'toString'), isFalse);
+ });
+ test('typed literal', () {
+ var l =
+ new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: null, JS$class: true);
+ expect(js_util.hasProperty(l, 'a'), isTrue);
+ expect(js_util.hasProperty(l, 'b'), isTrue);
+ expect(js_util.hasProperty(l, '_c'), isTrue);
+ expect(l.JS$_c, isNull);
+ expect(js_util.hasProperty(l, 'class'), isTrue);
+ // JS$_c escapes to _c so the property JS$_c will not exist on the object.
+ expect(js_util.hasProperty(l, r'JS$_c'), isFalse);
+ expect(js_util.hasProperty(l, r'JS$class'), isFalse);
+ expect(l.JS$class, isTrue);
+
+ l = new ExampleTypedLiteral(a: null);
+ expect(js_util.hasProperty(l, 'a'), isTrue);
+ expect(js_util.hasProperty(l, 'b'), isFalse);
+ expect(js_util.hasProperty(l, '_c'), isFalse);
+ expect(js_util.hasProperty(l, 'class'), isFalse);
+
+ l = new ExampleTypedLiteral(JS$_c: 74);
+ expect(js_util.hasProperty(l, '_c'), isTrue);
+ expect(l.JS$_c, equals(74));
+ });
+ });
+
+ group('getProperty', () {
+ test('typed object', () {
+ var f = new Foo(42);
+ expect(js_util.getProperty(f, 'a'), equals(42));
+ expect(js_util.getProperty(f, 'toString') is Function, isTrue);
+ js_util.setProperty(f, '__proto__', null);
+ expect(js_util.getProperty(f, 'toString'), isNull);
+ });
+
+ test('typed literal', () {
+ var l = new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: 7, JS$class: true);
+ expect(js_util.getProperty(l, 'a'), equals('x'));
+ expect(js_util.getProperty(l, 'b'), equals(42));
+ expect(js_util.getProperty(l, '_c'), equals(7));
+ expect(l.JS$_c, equals(7));
+ expect(js_util.getProperty(l, 'class'), isTrue);
+ expect(js_util.getProperty(l, r'JS$_c'), isNull);
+ expect(js_util.getProperty(l, r'JS$class'), isNull);
+ });
+ });
+
+ group('setProperty', () {
+ test('typed object', () {
+ var f = new Foo(42);
+ expect(js_util.getProperty(f, 'a'), equals(42));
+ js_util.setProperty(f, 'a', 100);
+ expect(f.a, equals(100));
+ expect(js_util.getProperty(f, 'a'), equals(100));
+ });
+
+ test('typed literal', () {
+ var l = new ExampleTypedLiteral();
+ js_util.setProperty(l, 'a', 'foo');
+ expect(js_util.getProperty(l, 'a'), equals('foo'));
+ expect(l.a, equals('foo'));
+ js_util.setProperty(l, 'a', l);
+ expect(identical(l.a, l), isTrue);
+ var list = ['arr'];
+ js_util.setProperty(l, 'a', list);
+ expect(identical(l.a, list), isTrue);
+ l.JS$class = 42;
+ expect(l.JS$class, equals(42));
+ js_util.setProperty(l, 'class', 100);
+ expect(l.JS$class, equals(100));
+ });
+ });
+
+ group('callMethod', () {
+ test('html object', () {
+ var canvas = new Element.tag('canvas');
+ expect(
+ identical(canvas.getContext('2d'),
+ js_util.callMethod(canvas, 'getContext', ['2d'])),
+ isTrue);
+ });
+
+ test('typed object', () {
+ var f = new Foo(42);
+ expect(js_util.callMethod(f, 'bar', []), equals(42));
+ });
+ });
+
+ group('instanceof', () {
+ test('html object', () {
+ var canvas = new Element.tag('canvas');
+ expect(js_util.instanceof(canvas, JSNodeType), isTrue);
+ expect(js_util.instanceof(canvas, JSTextType), isFalse);
+ expect(js_util.instanceof(canvas, JSElementType), isTrue);
+ expect(js_util.instanceof(canvas, JSHtmlCanvasElementType), isTrue);
+ var div = new Element.tag('div');
+ expect(js_util.instanceof(div, JSNodeType), isTrue);
+ expect(js_util.instanceof(div, JSTextType), isFalse);
+ expect(js_util.instanceof(div, JSElementType), isTrue);
+ expect(js_util.instanceof(div, JSHtmlCanvasElementType), isFalse);
+
+ var text = new Text('foo');
+ expect(js_util.instanceof(text, JSNodeType), isTrue);
+ expect(js_util.instanceof(text, JSTextType), isTrue);
+ expect(js_util.instanceof(text, JSElementType), isFalse);
+ });
+
+ test('typed object', () {
+ var f = new Foo(42);
+ expect(js_util.instanceof(f, JSFooType), isTrue);
+ expect(js_util.instanceof(f, JSNodeType), isFalse);
+ });
+
+ test('typed literal', () {
+ var l = new ExampleTypedLiteral();
+ expect(js_util.instanceof(l, JSFooType), isFalse);
+ });
+ });
+
+ group('callConstructor', () {
+ test('html object', () {
+ var textNode = js_util.callConstructor(JSTextType, ['foo']);
+ expect(js_util.instanceof(textNode, JSTextType), isTrue);
+ expect(textNode is Text, isTrue);
+ expect(textNode.text, equals('foo'));
+ });
+
+ test('typed object', () {
+ Foo f = js_util.callConstructor(JSFooType, [42]);
+ expect(f.a, equals(42));
+ });
+ });
+}

Powered by Google App Engine
This is Rietveld 408576698