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)); |
+ }); |
+ }); |
+} |