| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012, 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 library js_tests; |
| 6 |
| 7 import 'dart:html'; |
| 8 |
| 9 import 'package:js/js.dart' as js; |
| 10 import 'package:unittest/unittest.dart'; |
| 11 import 'package:unittest/html_config.dart'; |
| 12 |
| 13 class Foo implements js.Serializable<js.Proxy> { |
| 14 final js.Proxy _proxy; |
| 15 |
| 16 Foo(num a) : this._proxy = new js.Proxy(js.context.Foo, a); |
| 17 |
| 18 js.Proxy toJs() => _proxy; |
| 19 |
| 20 num get a => _proxy.a; |
| 21 num bar() => _proxy.bar(); |
| 22 } |
| 23 |
| 24 class Color implements js.Serializable<String> { |
| 25 static final RED = new Color._("red"); |
| 26 static final BLUE = new Color._("blue"); |
| 27 String _value; |
| 28 Color._(this._value); |
| 29 String toJs() => this._value; |
| 30 } |
| 31 |
| 32 main() { |
| 33 useHtmlConfiguration(); |
| 34 |
| 35 test('read global field', () { |
| 36 expect(js.context.x, equals(42)); |
| 37 expect(js.context['x'], equals(42)); |
| 38 expect(() => js.context.y, throwsA(isNoSuchMethodError)); |
| 39 }); |
| 40 |
| 41 test('read global field with underscore', () { |
| 42 expect(js.context._x, equals(123)); |
| 43 expect(js.context['_x'], equals(123)); |
| 44 expect(() => js.context._y, throwsA(isNoSuchMethodError)); |
| 45 expect(js.context['_y'], equals(null)); |
| 46 }); |
| 47 |
| 48 test('js instantiation : new Foo()', () { |
| 49 final Foo2 = js.context.container.Foo; |
| 50 final foo = new js.Proxy(Foo2, 42); |
| 51 expect(foo.a, 42); |
| 52 expect(Foo2.b, 38); |
| 53 }); |
| 54 |
| 55 test('js instantiation : new Array()', () { |
| 56 final a = new js.Proxy(js.context.Array); |
| 57 expect(a, isNotNull); |
| 58 expect(a.length, equals(0)); |
| 59 |
| 60 a.push("value 1"); |
| 61 expect(a.length, equals(1)); |
| 62 expect(a[0], equals("value 1")); |
| 63 |
| 64 a.pop(); |
| 65 expect(a.length, equals(0)); |
| 66 }); |
| 67 |
| 68 test('js instantiation : new Date()', () { |
| 69 final a = new js.Proxy(js.context.Date); |
| 70 expect(a.getTime(), isNotNull); |
| 71 }); |
| 72 |
| 73 test('js instantiation : new Date(int)', () { |
| 74 final a = new js.Proxy(js.context.Date, 12345678); |
| 75 expect(a.getTime(), equals(12345678)); |
| 76 }); |
| 77 |
| 78 test('js instantiation : new Date(String)', () { |
| 79 final a = new js.Proxy(js.context.Date, |
| 80 "December 17, 1995 03:24:00 GMT+01:00"); |
| 81 expect(a.getTime(), equals(819167040000)); |
| 82 }); |
| 83 |
| 84 test('js instantiation : new Date(int, int, int)', () { |
| 85 // Note: JS Date counts months from 0 while Dart counts from 1. |
| 86 final a = new js.Proxy(js.context.Date, 1995, 11, 17); |
| 87 final b = new DateTime(1995, 12, 17); |
| 88 expect(a.getTime(), equals(b.millisecondsSinceEpoch)); |
| 89 }); |
| 90 |
| 91 test('js instantiation : new Date(1995,11,17,3,24,0)', () { |
| 92 // Note: JS Date counts months from 0 while Dart counts from 1. |
| 93 final a = new js.Proxy.withArgList(js.context.Date, |
| 94 [1995, 11, 17, 3, 24, 0]); |
| 95 final b = new DateTime(1995, 12, 17, 3, 24, 0); |
| 96 expect(a.getTime(), equals(b.millisecondsSinceEpoch)); |
| 97 }); |
| 98 |
| 99 test('js instantiation : new Object()', () { |
| 100 final a = new js.Proxy(js.context.Object); |
| 101 expect(a, isNotNull); |
| 102 |
| 103 a.attr = "value"; |
| 104 expect(a.attr, equals("value")); |
| 105 }); |
| 106 |
| 107 test(r'js instantiation : new RegExp("^\w+$")', () { |
| 108 final a = new js.Proxy(js.context.RegExp, r'^\w+$'); |
| 109 expect(a, isNotNull); |
| 110 expect(a.test('true'), isTrue); |
| 111 expect(a.test(' false'), isFalse); |
| 112 }); |
| 113 |
| 114 test('js instantiation via map notation : new Array()', () { |
| 115 final a = new js.Proxy(js.context['Array']); |
| 116 expect(a, isNotNull); |
| 117 expect(a['length'], equals(0)); |
| 118 |
| 119 a.push("value 1"); |
| 120 expect(a['length'], equals(1)); |
| 121 expect(a[0], equals("value 1")); |
| 122 |
| 123 a.pop(); |
| 124 expect(a['length'], equals(0)); |
| 125 }); |
| 126 |
| 127 test('js instantiation via map notation : new Date()', () { |
| 128 final a = new js.Proxy(js.context['Date']); |
| 129 expect(a.getTime(), isNotNull); |
| 130 }); |
| 131 |
| 132 test('js instantiation : typed array', () { |
| 133 final codeUnits = "test".codeUnits; |
| 134 final buf = new js.Proxy(js.context.ArrayBuffer, codeUnits.length); |
| 135 final bufView = new js.Proxy(js.context.Uint8Array, buf); |
| 136 for (var i = 0; i < codeUnits.length; i++) { |
| 137 bufView[i] = codeUnits[i]; |
| 138 } |
| 139 }); |
| 140 |
| 141 test('write global field', () { |
| 142 js.context.y = 42; |
| 143 expect(js.context.y, equals(42)); |
| 144 expect(js.context['y'], equals(42)); |
| 145 }); |
| 146 |
| 147 test('get JS FunctionProxy', () { |
| 148 var razzle = js.context.razzle; |
| 149 expect(razzle(), equals(42)); |
| 150 }); |
| 151 |
| 152 test('call JS function', () { |
| 153 expect(js.context.razzle(), equals(42)); |
| 154 expect(() => js.context.dazzle(), throwsA(isNoSuchMethodError)); |
| 155 }); |
| 156 |
| 157 test('call JS function via map notation', () { |
| 158 expect(js.context['razzle'](), equals(42)); |
| 159 expect(() => js.context['dazzle'](), throwsA(isNoSuchMethodError)); |
| 160 }); |
| 161 |
| 162 test('call JS function with varargs', () { |
| 163 expect(js.context.varArgs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), |
| 164 equals(55)); |
| 165 }); |
| 166 |
| 167 test('allocate JS object', () { |
| 168 var foo = new js.Proxy(js.context.Foo, 42); |
| 169 expect(foo.a, equals(42)); |
| 170 expect(foo.bar(), equals(42)); |
| 171 expect(() => foo.baz(), throwsA(isNoSuchMethodError)); |
| 172 }); |
| 173 |
| 174 test('call toString()', () { |
| 175 var foo = new js.Proxy(js.context.Foo, 42); |
| 176 expect(foo.toString(), equals("I'm a Foo a=42")); |
| 177 var container = js.context.container; |
| 178 expect(container.toString(), equals("[object Object]")); |
| 179 }); |
| 180 |
| 181 test('allocate simple JS array', () { |
| 182 final list = [1, 2, 3, 4, 5, 6, 7, 8]; |
| 183 var array = js.array(list); |
| 184 expect(js.context.isArray(array), isTrue); |
| 185 expect(array.length, equals(list.length)); |
| 186 for (var i = 0; i < list.length ; i++) { |
| 187 expect(array[i], equals(list[i])); |
| 188 } |
| 189 }); |
| 190 |
| 191 test('allocate JS array with iterable', () { |
| 192 final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]); |
| 193 var array = js.array(set); |
| 194 expect(js.context.isArray(array), isTrue); |
| 195 expect(array.length, equals(set.length)); |
| 196 for (var i = 0; i < array.length ; i++) { |
| 197 expect(set.contains(array[i]), isTrue); |
| 198 } |
| 199 }); |
| 200 |
| 201 test('allocate simple JS map', () { |
| 202 var map = {'a': 1, 'b': 2, 'c': 3}; |
| 203 var jsMap = js.map(map); |
| 204 expect(!js.context.isArray(jsMap), isTrue); |
| 205 for (final key in map.keys) { |
| 206 expect(js.context.checkMap(jsMap, key, map[key]), isTrue); |
| 207 } |
| 208 }); |
| 209 |
| 210 test('allocate complex JS object', () { |
| 211 final object = |
| 212 { |
| 213 'a': [1, [2, 3]], |
| 214 'b': { |
| 215 'c': 3, |
| 216 'd': new js.Proxy(js.context.Foo, 42) |
| 217 }, |
| 218 'e': null |
| 219 }; |
| 220 var jsObject = js.map(object); |
| 221 expect(jsObject['a'][0], equals(object['a'][0])); |
| 222 expect(jsObject['a'][1][0], equals(object['a'][1][0])); |
| 223 expect(jsObject['a'][1][1], equals(object['a'][1][1])); |
| 224 expect(jsObject['b']['c'], equals(object['b']['c'])); |
| 225 expect(jsObject['b']['d'], equals(object['b']['d'])); |
| 226 expect(jsObject['b']['d'].bar(), equals(42)); |
| 227 expect(jsObject['e'], isNull); |
| 228 }); |
| 229 |
| 230 test('invoke Dart callback from JS(with js.Callback)', () { |
| 231 expect(() => js.context.invokeCallback(), throws); |
| 232 |
| 233 js.context.callback = () => 42; |
| 234 expect(js.context.invokeCallback(), 42); |
| 235 |
| 236 js.deleteProperty(js.context, 'callback'); |
| 237 }); |
| 238 |
| 239 test('invoke Dart callback from JS', () { |
| 240 expect(() => js.context.invokeCallback(), throws); |
| 241 |
| 242 js.context.callback = () => 42; |
| 243 expect(js.context.invokeCallback(), equals(42)); |
| 244 |
| 245 js.deleteProperty(js.context, 'callback'); |
| 246 }); |
| 247 |
| 248 test('callback as parameter', () { |
| 249 expect(js.context.getTypeOf(js.context.razzle), equals("function")); |
| 250 }); |
| 251 |
| 252 test('invoke Dart callback from JS with this', () { |
| 253 final constructor = new js.FunctionProxy.withThis(($this, arg1) { |
| 254 $this.a = 42; |
| 255 $this.b = js.array(["a", arg1]); |
| 256 }); |
| 257 var o = new js.Proxy(constructor, "b"); |
| 258 expect(o.a, equals(42)); |
| 259 expect(o.b[0], equals("a")); |
| 260 expect(o.b[1], equals("b")); |
| 261 }); |
| 262 |
| 263 test('invoke Dart callback from JS with 11 parameters', () { |
| 264 js.context.callbackWith11params = (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, |
| 265 p11) => '$p1$p2$p3$p4$p5$p6$p7$p8$p9$p10$p11'; |
| 266 expect(js.context.invokeCallbackWith11params(), equals('1234567891011')); |
| 267 }); |
| 268 |
| 269 test('pass unattached Dom Element', () { |
| 270 final div = new DivElement(); |
| 271 div.classes.add('a'); |
| 272 expect(js.context.getElementAttribute(div, 'class'), equals('a')); |
| 273 }); |
| 274 |
| 275 test('pass unattached Dom Element two times on same call', () { |
| 276 final div = new DivElement(); |
| 277 div.classes.add('a'); |
| 278 expect(js.context.addClassAttributes(js.array([div, div])), equals('aa')); |
| 279 }); |
| 280 |
| 281 test('pass Dom Element attached to an unattached element', () { |
| 282 final div = new DivElement(); |
| 283 div.classes.add('a'); |
| 284 final container = new DivElement(); |
| 285 container.children.add(div); |
| 286 expect(js.context.getElementAttribute(div, 'class'), equals('a')); |
| 287 }); |
| 288 |
| 289 test('pass 2 Dom Elements attached to an unattached element', () { |
| 290 final div1 = new DivElement(); |
| 291 div1.classes.add('a'); |
| 292 final div2 = new DivElement(); |
| 293 div2.classes.add('b'); |
| 294 final container = new DivElement(); |
| 295 container.children.add(div1); |
| 296 container.children.add(div2); |
| 297 final f = js.context.addClassAttributes; |
| 298 expect(f(js.array([div1, div2])), equals('ab')); |
| 299 }); |
| 300 |
| 301 test('pass multiple Dom Elements unattached to document', () { |
| 302 // A is alone |
| 303 // 1 and 3 are brother |
| 304 // 2 is child of 3 |
| 305 final divA = new DivElement()..classes.add('A'); |
| 306 final div1 = new DivElement()..classes.add('1'); |
| 307 final div2 = new DivElement()..classes.add('2'); |
| 308 final div3 = new DivElement()..classes.add('3')..children.add(div2); |
| 309 final container = new DivElement()..children.addAll([div1, div3]); |
| 310 final f = js.context.addClassAttributes; |
| 311 expect(f(js.array([divA, div1, div2, div3])), equals('A123')); |
| 312 expect(f(js.array([divA, div1, div3, div2])), equals('A132')); |
| 313 expect(f(js.array([divA, div1, div1, div3, divA, div2, div3])), |
| 314 equals('A113A23')); |
| 315 expect(!document.documentElement.contains(divA), isTrue); |
| 316 expect(!document.documentElement.contains(div1), isTrue); |
| 317 expect(!document.documentElement.contains(div2), isTrue); |
| 318 expect(!document.documentElement.contains(div3), isTrue); |
| 319 expect(!document.documentElement.contains(container), isTrue); |
| 320 }); |
| 321 |
| 322 test('pass one Dom Elements unattached and another attached', () { |
| 323 final div1 = new DivElement()..classes.add('1'); |
| 324 final div2 = new DivElement()..classes.add('2'); |
| 325 document.documentElement.children.add(div2); |
| 326 final f = js.context.addClassAttributes; |
| 327 expect(f(js.array([div1, div2])), equals('12')); |
| 328 expect(!document.documentElement.contains(div1), isTrue); |
| 329 expect(document.documentElement.contains(div2), isTrue); |
| 330 }); |
| 331 |
| 332 test('pass documentElement', () { |
| 333 expect(js.context.returnElement(document.documentElement), |
| 334 equals(document.documentElement)); |
| 335 }); |
| 336 |
| 337 test('retrieve unattached Dom Element', () { |
| 338 var result = js.context.getNewDivElement(); |
| 339 expect(result is DivElement, isTrue); |
| 340 expect(!document.documentElement.contains(result), isTrue); |
| 341 }); |
| 342 |
| 343 test('return a JS proxy to JavaScript', () { |
| 344 var result = js.context.testJsMap(() => js.map({ 'value': 42 })); |
| 345 expect(result, 42); |
| 346 }); |
| 347 |
| 348 test('test proxy equality', () { |
| 349 var foo1 = new js.Proxy(js.context.Foo, 1); |
| 350 var foo2 = new js.Proxy(js.context.Foo, 2); |
| 351 js.context.foo = foo1; |
| 352 js.context.foo = foo2; |
| 353 expect(foo1, isNot(equals(js.context.foo))); |
| 354 expect(foo2, equals(js.context.foo)); |
| 355 }); |
| 356 |
| 357 test('test instanceof', () { |
| 358 var foo = new js.Proxy(js.context.Foo, 1); |
| 359 expect(js.instanceof(foo, js.context.Foo), isTrue); |
| 360 expect(js.instanceof(foo, js.context.Object), isTrue); |
| 361 expect(js.instanceof(foo, js.context.String), isFalse); |
| 362 }); |
| 363 |
| 364 test('test hasProperty', () { |
| 365 var object = js.map({}); |
| 366 object.a = 1; |
| 367 expect(js.hasProperty(object, "a"), isTrue); |
| 368 expect(js.hasProperty(object, "b"), isFalse); |
| 369 }); |
| 370 |
| 371 test('test deleteProperty', () { |
| 372 var object = js.map({}); |
| 373 object.a = 1; |
| 374 expect(js.context.Object.keys(object).length, 1); |
| 375 expect(js.context.Object.keys(object)[0], "a"); |
| 376 js.deleteProperty(object, "a"); |
| 377 expect(js.context.Object.keys(object).length, 0); |
| 378 }); |
| 379 |
| 380 test('test index get and set', () { |
| 381 final myArray = js.context.myArray; |
| 382 expect(myArray.length, equals(1)); |
| 383 expect(myArray[0], equals("value1")); |
| 384 myArray[0] = "value2"; |
| 385 expect(myArray.length, equals(1)); |
| 386 expect(myArray[0], equals("value2")); |
| 387 |
| 388 final foo = new js.Proxy(js.context.Foo, 1); |
| 389 foo["getAge"] = () => 10; |
| 390 expect(foo.getAge(), equals(10)); |
| 391 }); |
| 392 |
| 393 test('access a property of a function', () { |
| 394 expect(js.context.Bar(), "ret_value"); |
| 395 expect(js.context.Bar.foo, "property_value"); |
| 396 }); |
| 397 |
| 398 test('retrieve same dart Object', () { |
| 399 final o = new Object(); |
| 400 js.context.o = o; |
| 401 expect(js.context.o, same(o)); |
| 402 }); |
| 403 |
| 404 test('usage of Serializable', () { |
| 405 final red = Color.RED; |
| 406 js.context.color = red; |
| 407 expect(js.context.color, equals(red._value)); |
| 408 }); |
| 409 |
| 410 } |
| OLD | NEW |