OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 @JS() |
| 6 library js_native_test; |
| 7 |
| 8 import 'dart:async'; |
| 9 import 'dart:html'; |
| 10 import 'dart:typed_data' show ByteBuffer, Int32List; |
| 11 import 'dart:indexed_db' show IdbFactory, KeyRange; |
| 12 |
| 13 import 'package:js/js.dart'; |
| 14 import 'package:js/js_util.dart' as js_util; |
| 15 |
| 16 import 'package:unittest/unittest.dart'; |
| 17 import 'package:unittest/html_individual_config.dart'; |
| 18 |
| 19 _injectJs() { |
| 20 final script = new ScriptElement(); |
| 21 script.type = 'text/javascript'; |
| 22 script.innerHtml = r""" |
| 23 var x = 42; |
| 24 |
| 25 var _x = 123; |
| 26 |
| 27 var myArray = ["value1"]; |
| 28 |
| 29 function returnThis() { |
| 30 return this; |
| 31 } |
| 32 |
| 33 function getTypeOf(o) { |
| 34 return typeof(o); |
| 35 } |
| 36 |
| 37 function Foo(a) { |
| 38 this.a = a; |
| 39 } |
| 40 |
| 41 Foo.b = 38; |
| 42 |
| 43 Foo.prototype.bar = function() { |
| 44 return this.a; |
| 45 } |
| 46 Foo.prototype.toString = function() { |
| 47 return "I'm a Foo a=" + this.a; |
| 48 } |
| 49 |
| 50 var container = new Object(); |
| 51 container.Foo = Foo; |
| 52 |
| 53 function checkMap(m, key, value) { |
| 54 if (m.hasOwnProperty(key)) |
| 55 return m[key] == value; |
| 56 else |
| 57 return false; |
| 58 } |
| 59 |
| 60 """; |
| 61 document.body.append(script); |
| 62 } |
| 63 |
| 64 @JS() |
| 65 external bool checkMap(m, String, value); |
| 66 |
| 67 @JS('JSON.stringify') |
| 68 external String stringify(o); |
| 69 |
| 70 @JS('Node') |
| 71 external get JSNodeType; |
| 72 |
| 73 @JS('Element') |
| 74 external get JSElementType; |
| 75 |
| 76 @JS('Text') |
| 77 external get JSTextType; |
| 78 |
| 79 @JS('HTMLCanvasElement') |
| 80 external get JSHtmlCanvasElementType; |
| 81 |
| 82 @JS() |
| 83 class Foo { |
| 84 external Foo(num a); |
| 85 |
| 86 external num get a; |
| 87 external num bar(); |
| 88 } |
| 89 |
| 90 @JS('Foo') |
| 91 external get JSFooType; |
| 92 |
| 93 @JS() |
| 94 @anonymous |
| 95 class ExampleTypedLiteral { |
| 96 external factory ExampleTypedLiteral({a, b, JS$_c, JS$class}); |
| 97 |
| 98 external get a; |
| 99 external get b; |
| 100 external get JS$_c; |
| 101 external set JS$_c(v); |
| 102 // Identical to JS$_c but only accessible within the library. |
| 103 external get _c; |
| 104 external get JS$class; |
| 105 external set JS$class(v); |
| 106 } |
| 107 |
| 108 @JS("Object.prototype.hasOwnProperty") |
| 109 external get _hasOwnProperty; |
| 110 |
| 111 bool hasOwnProperty(o, String name) { |
| 112 return js_util.callMethod(_hasOwnProperty, 'call', [o, name]); |
| 113 } |
| 114 |
| 115 main() { |
| 116 _injectJs(); |
| 117 useHtmlIndividualConfiguration(); |
| 118 |
| 119 group('js_util.jsify()', () { |
| 120 test('convert a List', () { |
| 121 final list = [1, 2, 3, 4, 5, 6, 7, 8]; |
| 122 var array = js_util.jsify(list); |
| 123 expect(array is List, isTrue); |
| 124 expect(identical(array, list), isFalse); |
| 125 expect(array.length, equals(list.length)); |
| 126 for (var i = 0; i < list.length; i++) { |
| 127 expect(array[i], equals(list[i])); |
| 128 } |
| 129 }); |
| 130 |
| 131 test('convert an Iterable', () { |
| 132 final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]); |
| 133 var array = js_util.jsify(set); |
| 134 expect(array is List, isTrue); |
| 135 expect(array.length, equals(set.length)); |
| 136 for (var i = 0; i < array.length; i++) { |
| 137 expect(set.contains(array[i]), isTrue); |
| 138 } |
| 139 }); |
| 140 |
| 141 test('convert a Map', () { |
| 142 var map = {'a': 1, 'b': 2, 'c': 3}; |
| 143 var jsMap = js_util.jsify(map); |
| 144 expect(jsMap is! List, isTrue); |
| 145 for (var key in map.keys) { |
| 146 expect(checkMap(jsMap, key, map[key]), isTrue); |
| 147 } |
| 148 }); |
| 149 |
| 150 test('deep convert a complex object', () { |
| 151 final object = { |
| 152 'a': [ |
| 153 1, |
| 154 [2, 3] |
| 155 ], |
| 156 'b': {'c': 3, 'd': new Foo(42)}, |
| 157 'e': null |
| 158 }; |
| 159 var jsObject = js_util.jsify(object); |
| 160 expect(js_util.getProperty(jsObject, 'a')[0], equals(object['a'][0])); |
| 161 expect( |
| 162 js_util.getProperty(jsObject, 'a')[1][0], equals(object['a'][1][0])); |
| 163 expect( |
| 164 js_util.getProperty(jsObject, 'a')[1][1], equals(object['a'][1][1])); |
| 165 expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'c'), |
| 166 equals(object['b']['c'])); |
| 167 expect(js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'), |
| 168 equals(object['b']['d'])); |
| 169 expect( |
| 170 js_util.callMethod( |
| 171 js_util.getProperty(js_util.getProperty(jsObject, 'b'), 'd'), |
| 172 'bar', []), |
| 173 equals(42)); |
| 174 expect(js_util.getProperty(jsObject, 'e'), isNull); |
| 175 }); |
| 176 |
| 177 test('throws if object is not a Map or Iterable', () { |
| 178 expect(() => js_util.jsify('a'), |
| 179 throwsA(new isInstanceOf<ArgumentError>())); |
| 180 }); |
| 181 }); |
| 182 |
| 183 group('js_util.newObject', () { |
| 184 test('create', () { |
| 185 expect(identical(js_util.newObject(), js_util.newObject()), isFalse); |
| 186 }); |
| 187 |
| 188 test('callMethod', () { |
| 189 var o = js_util.newObject(); |
| 190 expect(js_util.callMethod(o, 'toString', []), equals('[object Object]')); |
| 191 expect(stringify(o), equals('{}')); |
| 192 }); |
| 193 |
| 194 test('properties', () { |
| 195 var o = js_util.newObject(); |
| 196 expect(js_util.hasProperty(o, 'foo bar'), isFalse); |
| 197 expect(js_util.hasProperty(o, 'toString'), isTrue); |
| 198 expect(hasOwnProperty(o, 'toString'), isFalse); |
| 199 expect(hasOwnProperty(o, 'foo bar'), isFalse); |
| 200 js_util.setProperty(o, 'foo bar', 42); |
| 201 expect(hasOwnProperty(o, 'foo bar'), isTrue); |
| 202 expect(js_util.getProperty(o, 'foo bar'), equals(42)); |
| 203 expect(js_util.hasProperty(o, 'foo bar'), isTrue); |
| 204 expect(stringify(o), equals('{"foo bar":42}')); |
| 205 }); |
| 206 }); |
| 207 |
| 208 group('hasProperty', () { |
| 209 test('typed object', () { |
| 210 var f = new Foo(42); |
| 211 expect(js_util.hasProperty(f, 'a'), isTrue); |
| 212 expect(js_util.hasProperty(f, 'toString'), isTrue); |
| 213 js_util.setProperty(f, '__proto__', null); |
| 214 expect(js_util.hasProperty(f, 'toString'), isFalse); |
| 215 }); |
| 216 test('typed literal', () { |
| 217 var l = |
| 218 new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: null, JS$class: true); |
| 219 expect(js_util.hasProperty(l, 'a'), isTrue); |
| 220 expect(js_util.hasProperty(l, 'b'), isTrue); |
| 221 expect(js_util.hasProperty(l, '_c'), isTrue); |
| 222 expect(l.JS$_c, isNull); |
| 223 expect(js_util.hasProperty(l, 'class'), isTrue); |
| 224 // JS$_c escapes to _c so the property JS$_c will not exist on the object. |
| 225 expect(js_util.hasProperty(l, r'JS$_c'), isFalse); |
| 226 expect(js_util.hasProperty(l, r'JS$class'), isFalse); |
| 227 expect(l.JS$class, isTrue); |
| 228 |
| 229 l = new ExampleTypedLiteral(a: null); |
| 230 expect(js_util.hasProperty(l, 'a'), isTrue); |
| 231 expect(js_util.hasProperty(l, 'b'), isFalse); |
| 232 expect(js_util.hasProperty(l, '_c'), isFalse); |
| 233 expect(js_util.hasProperty(l, 'class'), isFalse); |
| 234 |
| 235 l = new ExampleTypedLiteral(JS$_c: 74); |
| 236 expect(js_util.hasProperty(l, '_c'), isTrue); |
| 237 expect(l.JS$_c, equals(74)); |
| 238 }); |
| 239 }); |
| 240 |
| 241 group('getProperty', () { |
| 242 test('typed object', () { |
| 243 var f = new Foo(42); |
| 244 expect(js_util.getProperty(f, 'a'), equals(42)); |
| 245 expect(js_util.getProperty(f, 'toString') is Function, isTrue); |
| 246 js_util.setProperty(f, '__proto__', null); |
| 247 expect(js_util.getProperty(f, 'toString'), isNull); |
| 248 }); |
| 249 |
| 250 test('typed literal', () { |
| 251 var l = new ExampleTypedLiteral(a: 'x', b: 42, JS$_c: 7, JS$class: true); |
| 252 expect(js_util.getProperty(l, 'a'), equals('x')); |
| 253 expect(js_util.getProperty(l, 'b'), equals(42)); |
| 254 expect(js_util.getProperty(l, '_c'), equals(7)); |
| 255 expect(l.JS$_c, equals(7)); |
| 256 expect(js_util.getProperty(l, 'class'), isTrue); |
| 257 expect(js_util.getProperty(l, r'JS$_c'), isNull); |
| 258 expect(js_util.getProperty(l, r'JS$class'), isNull); |
| 259 }); |
| 260 }); |
| 261 |
| 262 group('setProperty', () { |
| 263 test('typed object', () { |
| 264 var f = new Foo(42); |
| 265 expect(js_util.getProperty(f, 'a'), equals(42)); |
| 266 js_util.setProperty(f, 'a', 100); |
| 267 expect(f.a, equals(100)); |
| 268 expect(js_util.getProperty(f, 'a'), equals(100)); |
| 269 }); |
| 270 |
| 271 test('typed literal', () { |
| 272 var l = new ExampleTypedLiteral(); |
| 273 js_util.setProperty(l, 'a', 'foo'); |
| 274 expect(js_util.getProperty(l, 'a'), equals('foo')); |
| 275 expect(l.a, equals('foo')); |
| 276 js_util.setProperty(l, 'a', l); |
| 277 expect(identical(l.a, l), isTrue); |
| 278 var list = ['arr']; |
| 279 js_util.setProperty(l, 'a', list); |
| 280 expect(identical(l.a, list), isTrue); |
| 281 l.JS$class = 42; |
| 282 expect(l.JS$class, equals(42)); |
| 283 js_util.setProperty(l, 'class', 100); |
| 284 expect(l.JS$class, equals(100)); |
| 285 }); |
| 286 }); |
| 287 |
| 288 group('callMethod', () { |
| 289 test('html object', () { |
| 290 var canvas = new Element.tag('canvas'); |
| 291 expect( |
| 292 identical(canvas.getContext('2d'), |
| 293 js_util.callMethod(canvas, 'getContext', ['2d'])), |
| 294 isTrue); |
| 295 }); |
| 296 |
| 297 test('typed object', () { |
| 298 var f = new Foo(42); |
| 299 expect(js_util.callMethod(f, 'bar', []), equals(42)); |
| 300 }); |
| 301 }); |
| 302 |
| 303 group('instanceof', () { |
| 304 test('html object', () { |
| 305 var canvas = new Element.tag('canvas'); |
| 306 expect(js_util.instanceof(canvas, JSNodeType), isTrue); |
| 307 expect(js_util.instanceof(canvas, JSTextType), isFalse); |
| 308 expect(js_util.instanceof(canvas, JSElementType), isTrue); |
| 309 expect(js_util.instanceof(canvas, JSHtmlCanvasElementType), isTrue); |
| 310 var div = new Element.tag('div'); |
| 311 expect(js_util.instanceof(div, JSNodeType), isTrue); |
| 312 expect(js_util.instanceof(div, JSTextType), isFalse); |
| 313 expect(js_util.instanceof(div, JSElementType), isTrue); |
| 314 expect(js_util.instanceof(div, JSHtmlCanvasElementType), isFalse); |
| 315 |
| 316 var text = new Text('foo'); |
| 317 expect(js_util.instanceof(text, JSNodeType), isTrue); |
| 318 expect(js_util.instanceof(text, JSTextType), isTrue); |
| 319 expect(js_util.instanceof(text, JSElementType), isFalse); |
| 320 }); |
| 321 |
| 322 test('typed object', () { |
| 323 var f = new Foo(42); |
| 324 expect(js_util.instanceof(f, JSFooType), isTrue); |
| 325 expect(js_util.instanceof(f, JSNodeType), isFalse); |
| 326 }); |
| 327 |
| 328 test('typed literal', () { |
| 329 var l = new ExampleTypedLiteral(); |
| 330 expect(js_util.instanceof(l, JSFooType), isFalse); |
| 331 }); |
| 332 }); |
| 333 |
| 334 group('callConstructor', () { |
| 335 test('html object', () { |
| 336 var textNode = js_util.callConstructor(JSTextType, ['foo']); |
| 337 expect(js_util.instanceof(textNode, JSTextType), isTrue); |
| 338 expect(textNode is Text, isTrue); |
| 339 expect(textNode.text, equals('foo')); |
| 340 }); |
| 341 |
| 342 test('typed object', () { |
| 343 Foo f = js_util.callConstructor(JSFooType, [42]); |
| 344 expect(f.a, equals(42)); |
| 345 }); |
| 346 }); |
| 347 } |
OLD | NEW |