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

Side by Side Diff: tests/html/js_test.dart

Issue 27514003: A few API changes: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library jsTest; 5 library jsTest;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:html'; 8 import 'dart:html';
9 import 'dart:typed_data' show ByteBuffer, Int32List;
10 import 'dart:indexed_db' show IdbFactory, KeyRange;
9 import 'dart:js'; 11 import 'dart:js';
10 12
11 import '../../pkg/unittest/lib/unittest.dart'; 13 import '../../pkg/unittest/lib/unittest.dart';
12 import '../../pkg/unittest/lib/html_config.dart'; 14 import '../../pkg/unittest/lib/html_config.dart';
13 15
14 _injectJs() { 16 _injectJs() {
15 final script = new ScriptElement(); 17 final script = new ScriptElement();
16 script.type = 'text/javascript'; 18 script.type = 'text/javascript';
17 script.innerHtml = r""" 19 script.innerHtml = r"""
18 var x = 42; 20 var x = 42;
19 21
20 var _x = 123; 22 var _x = 123;
21 23
22 var myArray = ["value1"]; 24 var myArray = ["value1"];
23 25
24 var foreignDoc = (function(){ 26 var foreignDoc = (function(){
25 var doc = document.implementation.createDocument("", "root", null); 27 var doc = document.implementation.createDocument("", "root", null);
26 var element = doc.createElement('element'); 28 var element = doc.createElement('element');
27 element.setAttribute('id', 'abc'); 29 element.setAttribute('id', 'abc');
28 doc.documentElement.appendChild(element); 30 doc.documentElement.appendChild(element);
29 return doc; 31 return doc;
30 })(); 32 })();
31 33
32 function razzle() { 34 function razzle() {
33 return x; 35 return x;
34 } 36 }
35 37
38 function returnThis() {
39 return this;
40 }
41
36 function getTypeOf(o) { 42 function getTypeOf(o) {
37 return typeof(o); 43 return typeof(o);
38 } 44 }
39 45
40 function varArgs() { 46 function varArgs() {
41 var args = arguments; 47 var args = arguments;
42 var sum = 0; 48 var sum = 0;
43 for (var i = 0; i < args.length; ++i) { 49 for (var i = 0; i < args.length; ++i) {
44 sum += args[i]; 50 sum += args[i];
45 } 51 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 } 96 }
91 97
92 function addClassAttributes(list) { 98 function addClassAttributes(list) {
93 var result = ""; 99 var result = "";
94 for (var i=0; i < list.length; i++) { 100 for (var i=0; i < list.length; i++) {
95 result += list[i].getAttribute("class"); 101 result += list[i].getAttribute("class");
96 } 102 }
97 return result; 103 return result;
98 } 104 }
99 105
106 function getNewDate() {
107 return new Date(1995, 11, 17);
108 }
109
100 function getNewDivElement() { 110 function getNewDivElement() {
101 return document.createElement("div"); 111 return document.createElement("div");
102 } 112 }
103 113
114 function getNewBlob() {
115 var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
116 return new Blob(fileParts, {type : 'text/html'});
117 }
118
119 function getNewIDBKeyRange() {
120 return IDBKeyRange.only(1);
121 }
122
123 function getNewImageData() {
124 var canvas = document.createElement('canvas');
125 var context = canvas.getContext('2d');
126 return context.createImageData(1, 1);
127 }
128
129 function getNewInt32Array() {
130 return new Int32Array([1, 2, 3, 4, 5, 6, 7, 8]);
131 }
132
133 function getNewArrayBuffer() {
134 return new ArrayBuffer(8);
135 }
136
137 function isPropertyInstanceOf(property, type) {
138 return window[property] instanceof type;
139 }
140
104 function testJsMap(callback) { 141 function testJsMap(callback) {
105 var result = callback(); 142 var result = callback();
106 return result['value']; 143 return result['value'];
107 } 144 }
108 145
146 function addTestProperty(o) {
147 o.testProperty = "test";
148 }
149
109 function Bar() { 150 function Bar() {
110 return "ret_value"; 151 return "ret_value";
111 } 152 }
112 Bar.foo = "property_value"; 153 Bar.foo = "property_value";
113 154
114 function Baz(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) { 155 function Baz(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) {
115 this.f1 = p1; 156 this.f1 = p1;
116 this.f2 = p2; 157 this.f2 = p2;
117 this.f3 = p3; 158 this.f3 = p3;
118 this.f4 = p4; 159 this.f4 = p4;
119 this.f5 = p5; 160 this.f5 = p5;
120 this.f6 = p6; 161 this.f6 = p6;
121 this.f7 = p7; 162 this.f7 = p7;
122 this.f8 = p8; 163 this.f8 = p8;
123 this.f9 = p9; 164 this.f9 = p9;
124 this.f10 = p10; 165 this.f10 = p10;
125 this.f11 = p11; 166 this.f11 = p11;
126 } 167 }
127 168
169 function Liar(){}
170
171 Liar.prototype.toString = function() {
172 return 1;
173 }
174
128 function identical(o1, o2) { 175 function identical(o1, o2) {
129 return o1 === o2; 176 return o1 === o2;
130 } 177 }
178
131 """; 179 """;
132 document.body.append(script); 180 document.body.append(script);
133 } 181 }
134 182
135 class Foo implements Serializable<JsObject> { 183 class Foo {
136 final JsObject _proxy; 184 final JsObject _proxy;
137 185
138 Foo(num a) : this._proxy = new JsObject(context['Foo'], [a]); 186 Foo(num a) : this._proxy = new JsObject(context['Foo'], [a]);
139 187
140 JsObject toJs() => _proxy; 188 JsObject toJs() => _proxy;
141 189
142 num get a => _proxy['a']; 190 num get a => _proxy['a'];
143 num bar() => _proxy.callMethod('bar'); 191 num bar() => _proxy.callMethod('bar');
144 } 192 }
145 193
146 class Color implements Serializable<String> { 194 class Color {
147 static final RED = new Color._("red"); 195 static final RED = new Color._("red");
148 static final BLUE = new Color._("blue"); 196 static final BLUE = new Color._("blue");
149 String _value; 197 String _value;
150 Color._(this._value); 198 Color._(this._value);
151 String toJs() => this._value; 199 String toJs() => this._value;
152 } 200 }
153 201
154 class TestDartObject {} 202 class TestDartObject {}
155 203
156 main() { 204 main() {
157 _injectJs(); 205 _injectJs();
158 useHtmlConfiguration(); 206 useHtmlConfiguration();
159 207
160 group('identity', () { 208 group('identity', () {
161 209
162 test('context instances should be identical', () { 210 test('context instances should be identical', () {
163 var c1 = context; 211 var c1 = context;
164 var c2 = context; 212 var c2 = context;
165 expect(identical(c1, c2), isTrue); 213 expect(identical(c1, c2), isTrue);
166 }); 214 });
167 215
216 /*
217 TODO(jacobr): enable this test when dartium supports maintaining proxy
218 equality.
219
168 test('identical JS objects should have identical proxies', () { 220 test('identical JS objects should have identical proxies', () {
169 var o1 = new JsObject(context['Foo'], [1]); 221 var o1 = new JsObject(context['Foo'], [1]);
170 context['f1'] = o1; 222 context['f1'] = o1;
171 var o2 = context['f1']; 223 var o2 = context['f1'];
172 expect(identical(o1, o2), isTrue); 224 expect(equals(o1, o2), isTrue);
173 });
174
175 test('identical JS functions should have identical proxies', () {
176 var f1 = context['Object'];
177 var f2 = context['Object'];
178 expect(identical(f1, f2), isTrue);
179 }); 225 });
180 226
181 test('identical Dart objects should have identical proxies', () { 227 test('identical Dart objects should have identical proxies', () {
182 var o1 = new TestDartObject(); 228 var o1 = new TestDartObject();
183 expect(context.callMethod('identical', [o1, o1]), isTrue); 229 expect(context.callMethod('identical', [o1, o1]), isTrue);
184 }); 230 });
185 231
186 test('identical Dart functions should have identical proxies', () { 232 test('identical Dart functions should have identical proxies', () {
187 var f1 = () => print("I'm a Function!"); 233 var f1 = () => print("I'm a Function!");
188 expect(context.callMethod('identical', [f1, f1]), isTrue); 234 expect(context.callMethod('identical', [f1, f1]), isTrue);
189 }); 235 });
236 */
237
238 // TODO(jacobr): switch from equals to indentical when dartium supports
239 // maintaining proxy equality.
240 test('identical JS functions should have equal proxies', () {
241 var f1 = context['Object'];
242 var f2 = context['Object'];
243 expect(f1, equals(f2));
244 });
190 245
191 // TODO(justinfagnani): old tests duplicate checks above, remove 246 // TODO(justinfagnani): old tests duplicate checks above, remove
192 // on test next cleanup pass 247 // on test next cleanup pass
193 test('test proxy equality', () { 248 test('test proxy equality', () {
194 var foo1 = new JsObject(context['Foo'], [1]); 249 var foo1 = new JsObject(context['Foo'], [1]);
195 var foo2 = new JsObject(context['Foo'], [2]); 250 var foo2 = new JsObject(context['Foo'], [2]);
196 context['foo1'] = foo1; 251 context['foo1'] = foo1;
197 context['foo2'] = foo2; 252 context['foo2'] = foo2;
198 expect(foo1, isNot(equals(context['foo2']))); 253 expect(foo1, isNot(equals(context['foo2'])));
199 expect(foo2, same(context['foo2'])); 254 expect(foo2, equals(context['foo2']));
200 context.deleteProperty('foo1'); 255 context.deleteProperty('foo1');
201 context.deleteProperty('foo2'); 256 context.deleteProperty('foo2');
202 }); 257 });
203 258
259
204 test('retrieve same dart Object', () { 260 test('retrieve same dart Object', () {
205 final date = new DateTime.now(); 261 final obj = new Object();
206 context['dartDate'] = date; 262 context['obj'] = obj;
207 expect(context['dartDate'], same(date)); 263 expect(context['obj'], same(obj));
208 context.deleteProperty('dartDate'); 264 context.deleteProperty('obj');
209 }); 265 });
210 266
211 }); 267 });
212 268
213 test('read global field', () { 269 group('context', () {
214 expect(context['x'], equals(42)); 270
215 expect(context['y'], isNull); 271 test('read global field', () {
216 }); 272 expect(context['x'], equals(42));
217 273 expect(context['y'], isNull);
218 test('read global field with underscore', () { 274 });
219 expect(context['_x'], equals(123)); 275
220 expect(context['y'], isNull); 276 test('read global field with underscore', () {
221 }); 277 expect(context['_x'], equals(123));
222 278 expect(context['y'], isNull);
223 test('hashCode and operator==(other)', () { 279 });
224 final o1 = context['Object']; 280
225 final o2 = context['Object']; 281 test('write global field', () {
226 expect(o1 == o2, isTrue); 282 context['y'] = 42;
227 expect(o1.hashCode == o2.hashCode, isTrue); 283 expect(context['y'], equals(42));
228 final d = context['document']; 284 });
229 expect(o1 == d, isFalse); 285
230 }); 286 });
231 287
232 test('js instantiation : new Foo()', () { 288 group('new JsObject()', () {
233 final Foo2 = context['container']['Foo']; 289
234 final foo = new JsObject(Foo2, [42]); 290 test('new Foo()', () {
235 expect(foo['a'], 42); 291 var foo = new JsObject(context['Foo'], [42]);
236 expect(Foo2['b'], 38); 292 expect(foo['a'], equals(42));
237 }); 293 expect(foo.callMethod('bar'), equals(42));
238 294 expect(() => foo.callMethod('baz'), throwsA(isNoSuchMethodError));
239 test('js instantiation : new Array()', () { 295 });
240 final a = new JsObject(context['Array']); 296
241 expect(a, isNotNull); 297 test('new container.Foo()', () {
242 expect(a['length'], equals(0)); 298 final Foo2 = context['container']['Foo'];
243 299 final foo = new JsObject(Foo2, [42]);
244 a.callMethod('push', ["value 1"]); 300 expect(foo['a'], 42);
245 expect(a['length'], equals(1)); 301 expect(Foo2['b'], 38);
246 expect(a[0], equals("value 1")); 302 });
247 303
248 a.callMethod('pop'); 304 test('new Array()', () {
249 expect(a['length'], equals(0)); 305 final a = new JsObject(context['Array']);
250 }); 306 expect(a, isNotNull);
251 307 expect(a['length'], equals(0));
252 test('js instantiation : new Date()', () { 308
253 final a = new JsObject(context['Date']); 309 a.callMethod('push', ["value 1"]);
254 expect(a.callMethod('getTime'), isNotNull); 310 expect(a['length'], equals(1));
255 }); 311 expect(a[0], equals("value 1"));
256 312
257 test('js instantiation : new Date(12345678)', () { 313 a.callMethod('pop');
258 final a = new JsObject(context['Date'], [12345678]); 314 expect(a['length'], equals(0));
259 expect(a.callMethod('getTime'), equals(12345678)); 315 });
260 }); 316
261 317 test('new Date()', () {
262 test('js instantiation : new Date("December 17, 1995 03:24:00 GMT")', 318 final a = new JsObject(context['Date']);
263 () { 319 expect(a.callMethod('getTime'), isNotNull);
264 final a = new JsObject(context['Date'], 320 });
265 ["December 17, 1995 03:24:00 GMT"]); 321
266 expect(a.callMethod('getTime'), equals(819170640000)); 322 test('new Date(12345678)', () {
267 }); 323 final a = new JsObject(context['Date'], [12345678]);
268 324 expect(a.callMethod('getTime'), equals(12345678));
269 test('js instantiation : new Date(1995,11,17)', () { 325 });
270 // Note: JS Date counts months from 0 while Dart counts from 1. 326
271 final a = new JsObject(context['Date'], [1995, 11, 17]); 327 test('new Date("December 17, 1995 03:24:00 GMT")',
272 final b = new DateTime(1995, 12, 17); 328 () {
273 expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch)); 329 final a = new JsObject(context['Date'],
274 }); 330 ["December 17, 1995 03:24:00 GMT"]);
275 331 expect(a.callMethod('getTime'), equals(819170640000));
276 test('js instantiation : new Date(1995,11,17,3,24,0)', () { 332 });
277 // Note: JS Date counts months from 0 while Dart counts from 1. 333
278 final a = new JsObject(context['Date'], 334 test('new Date(1995,11,17)', () {
279 [1995, 11, 17, 3, 24, 0]); 335 // Note: JS Date counts months from 0 while Dart counts from 1.
280 final b = new DateTime(1995, 12, 17, 3, 24, 0); 336 final a = new JsObject(context['Date'], [1995, 11, 17]);
281 expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch)); 337 final b = new DateTime(1995, 12, 17);
282 }); 338 expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch));
283 339 });
284 test('js instantiation : new Object()', () { 340
285 final a = new JsObject(context['Object']); 341 test('new Date(1995,11,17,3,24,0)', () {
286 expect(a, isNotNull); 342 // Note: JS Date counts months from 0 while Dart counts from 1.
287 343 final a = new JsObject(context['Date'],
288 a['attr'] = "value"; 344 [1995, 11, 17, 3, 24, 0]);
289 expect(a['attr'], equals("value")); 345 final b = new DateTime(1995, 12, 17, 3, 24, 0);
290 }); 346 expect(a.callMethod('getTime'), equals(b.millisecondsSinceEpoch));
291 347 });
292 test(r'js instantiation : new RegExp("^\w+$")', () { 348
293 final a = new JsObject(context['RegExp'], [r'^\w+$']); 349 test('new Object()', () {
294 expect(a, isNotNull); 350 final a = new JsObject(context['Object']);
295 expect(a.callMethod('test', ['true']), isTrue); 351 expect(a, isNotNull);
296 expect(a.callMethod('test', [' false']), isFalse); 352
297 }); 353 a['attr'] = "value";
298 354 expect(a['attr'], equals("value"));
299 test('js instantiation via map notation : new Array()', () { 355 });
300 final a = new JsObject(context['Array']); 356
301 expect(a, isNotNull); 357 test(r'new RegExp("^\w+$")', () {
302 expect(a['length'], equals(0)); 358 final a = new JsObject(context['RegExp'], [r'^\w+$']);
303 359 expect(a, isNotNull);
304 a['push'].apply(a, ["value 1"]); 360 expect(a.callMethod('test', ['true']), isTrue);
305 expect(a['length'], equals(1)); 361 expect(a.callMethod('test', [' false']), isFalse);
306 expect(a[0], equals("value 1")); 362 });
307 363
308 a['pop'].apply(a); 364 test('js instantiation via map notation : new Array()', () {
309 expect(a['length'], equals(0)); 365 final a = new JsObject(context['Array']);
310 }); 366 expect(a, isNotNull);
311 367 expect(a['length'], equals(0));
312 test('js instantiation via map notation : new Date()', () { 368
313 final a = new JsObject(context['Date']); 369 a.callMethod('push', ["value 1"]);
314 expect(a['getTime'].apply(a), isNotNull); 370 expect(a['length'], equals(1));
315 }); 371 expect(a[0], equals("value 1"));
316 372
317 test('js instantiation : typed array', () { 373 a.callMethod('pop');
318 if (Platform.supportsTypedData) { 374 expect(a['length'], equals(0));
319 // Safari's ArrayBuffer is not a Function and so doesn't support bind 375 });
320 // which JsObject's constructor relies on. 376
321 // bug: https://bugs.webkit.org/show_bug.cgi?id=122976 377 test('js instantiation via map notation : new Date()', () {
322 if (context['ArrayBuffer']['bind'] != null) { 378 final a = new JsObject(context['Date']);
323 final codeUnits = "test".codeUnits; 379 expect(a.callMethod('getTime'), isNotNull);
324 final buf = new JsObject(context['ArrayBuffer'], [codeUnits.length]); 380 });
325 final bufView = new JsObject(context['Uint8Array'], [buf]); 381
326 for (var i = 0; i < codeUnits.length; i++) { 382 test('typed array', () {
327 bufView[i] = codeUnits[i]; 383 if (Platform.supportsTypedData) {
384 // Safari's ArrayBuffer is not a Function and so doesn't support bind
385 // which JsObject's constructor relies on.
386 // bug: https://bugs.webkit.org/show_bug.cgi?id=122976
387 if (context['ArrayBuffer']['bind'] != null) {
388 final codeUnits = "test".codeUnits;
389 final buf = new JsObject(context['ArrayBuffer'], [codeUnits.length]);
390 final bufView = new JsObject(context['Uint8Array'], [buf]);
391 for (var i = 0; i < codeUnits.length; i++) {
392 bufView[i] = codeUnits[i];
393 }
328 } 394 }
329 } 395 }
330 } 396 });
331 }); 397
332 398 test('>10 parameters', () {
333 test('js instantiation : >10 parameters', () { 399 final o = new JsObject(context['Baz'], [1,2,3,4,5,6,7,8,9,10,11]);
334 final o = new JsObject(context['Baz'], [1,2,3,4,5,6,7,8,9,10,11]); 400 for (var i = 1; i <= 11; i++) {
335 for (var i = 1; i <= 11; i++) { 401 expect(o["f$i"], i);
336 expect(o["f$i"], i); 402 }
337 } 403 expect(o['constructor'], equals(context['Baz']));
338 expect(o['constructor'], same(context['Baz'])); 404 });
339 }); 405 });
340 406
341 test('write global field', () { 407 group('JsFunction and callMethod', () {
342 context['y'] = 42; 408
343 expect(context['y'], equals(42)); 409 test('JsFunction.apply on a function defined in JS', () {
344 }); 410 expect(context['razzle'].apply([]), equals(42));
345 411 });
346 test('get JS JsFunction', () { 412
347 var razzle = context['razzle']; 413 test('JsFunction.apply on a function that uses "this"', () {
348 expect(razzle.apply(context), equals(42)); 414 var object = new Object();
349 }); 415 expect(context['returnThis'].apply([], thisArg: object), same(object));
350 416 });
351 test('call JS function', () { 417
352 expect(context.callMethod('razzle'), equals(42)); 418 test('JsObject.callMethod on a function defined in JS', () {
353 expect(() => context.callMethod('dazzle'), throwsA(isNoSuchMethodError)); 419 expect(context.callMethod('razzle'), equals(42));
354 }); 420 expect(() => context.callMethod('dazzle'), throwsA(isNoSuchMethodError));
355 421 });
356 test('call JS function via map notation', () { 422
357 expect(context['razzle'].apply(context), equals(42)); 423 test('callMethod with many arguments', () {
358 expect(() => context['dazzle'].apply(context), 424 expect(context.callMethod('varArgs', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
359 throwsA(isNoSuchMethodError)); 425 equals(55));
360 }); 426 });
361 427
362 test('call JS function with varargs', () { 428 test('access a property of a function', () {
363 expect(context.callMethod('varArgs', [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), 429 expect(context.callMethod('Bar'), "ret_value");
364 equals(55)); 430 expect(context['Bar']['foo'], "property_value");
365 }); 431 });
366 432 /*
367 test('allocate JS object', () { 433 TODO(jacobr): evaluate whether we should be in the business of throwing
368 var foo = new JsObject(context['Foo'], [42]); 434 ArgumentError outside of checked mode. In unchecked mode this should just
369 expect(foo['a'], equals(42)); 435 return a NoSuchMethodError as the class lacks a method "true".
370 expect(foo.callMethod('bar'), equals(42)); 436
371 expect(() => foo.callMethod('baz'), throwsA(isNoSuchMethodError)); 437 test('callMethod throws if name is not a String or num', () {
372 }); 438 expect(() => context.callMethod(true),
373 439 throwsA(new isInstanceOf<ArgumentError>()));
374 test('call toString()', () { 440 });
375 var foo = new JsObject(context['Foo'], [42]); 441 */
376 expect(foo.toString(), equals("I'm a Foo a=42")); 442 });
377 var container = context['container']; 443
378 expect(container.toString(), equals("[object Object]")); 444 group('JsObject.fromBrowserObject()', () {
379 }); 445
380 446 test('Nodes are proxied', () {
381 test('allocate simple JS array', () { 447 var node = new JsObject.fromBrowserObject(new DivElement());
382 final list = [1, 2, 3, 4, 5, 6, 7, 8]; 448 context['addTestProperty'].apply([node]);
383 var array = jsify(list); 449 expect(node is JsObject, isTrue);
384 expect(context.callMethod('isArray', [array]), isTrue); 450 expect(node.instanceof(context['HTMLDivElement']), isTrue);
385 expect(array['length'], equals(list.length)); 451 expect(node['testProperty'], 'test');
386 for (var i = 0; i < list.length ; i++) { 452 });
387 expect(array[i], equals(list[i])); 453
388 } 454 test('primitives and null throw ArgumentError', () {
389 }); 455 for (var v in ['a', 1, 2.0, true, null]) {
390 456 expect(() => new JsObject.fromBrowserObject(v),
391 test('allocate JS array with iterable', () { 457 throwsA(new isInstanceOf<ArgumentError>()));
392 final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]); 458 }
393 var array = jsify(set); 459 });
394 expect(context.callMethod('isArray', [array]), isTrue); 460
395 expect(array['length'], equals(set.length)); 461 });
396 for (var i = 0; i < array['length'] ; i++) { 462
397 expect(set.contains(array[i]), isTrue); 463 group('Dart callback', () {
398 } 464 test('invoke Dart callback from JS', () {
399 }); 465 expect(() => context.callMethod('invokeCallback'), throws);
400 466
401 test('allocate simple JS map', () { 467 context['callback'] = () => 42;
402 var map = {'a': 1, 'b': 2, 'c': 3}; 468 expect(context.callMethod('invokeCallback'), equals(42));
403 var jsMap = jsify(map); 469
404 expect(!context.callMethod('isArray', [jsMap]), isTrue); 470 context.deleteProperty('callback');
405 for (final key in map.keys) { 471 });
406 expect(context.callMethod('checkMap', [jsMap, key, map[key]]), isTrue); 472
407 } 473 test('callback as parameter', () {
408 }); 474 expect(context.callMethod('getTypeOf', [context['razzle']]),
409 475 equals("function"));
410 test('allocate complex JS object', () { 476 });
411 final object = 477
412 { 478 test('invoke Dart callback from JS with this', () {
479 // A JavaScript constructor function implemented in Dart which
480 // uses 'this'
481 final constructor = new JsFunction.withThis(($this, arg1) {
482 var t = $this;
483 $this['a'] = 42;
484 });
485 var o = new JsObject(constructor, ["b"]);
486 expect(o['a'], equals(42));
487 });
488
489 test('invoke Dart callback from JS with 11 parameters', () {
490 context['callbackWith11params'] = (p1, p2, p3, p4, p5, p6, p7,
491 p8, p9, p10, p11) => '$p1$p2$p3$p4$p5$p6$p7$p8$p9$p10$p11';
492 expect(context.callMethod('invokeCallbackWith11params'),
493 equals('1234567891011'));
494 });
495
496 test('return a JS proxy to JavaScript', () {
497 var result = context.callMethod('testJsMap', [() => new JsObject.jsify({'v alue': 42})]);
498 expect(result, 42);
499 });
500
501 });
502
503 group('JsObject.jsify()', () {
504
505 test('convert a List', () {
506 final list = [1, 2, 3, 4, 5, 6, 7, 8];
507 var array = new JsObject.jsify(list);
508 expect(context.callMethod('isArray', [array]), isTrue);
509 expect(array['length'], equals(list.length));
510 for (var i = 0; i < list.length ; i++) {
511 expect(array[i], equals(list[i]));
512 }
513 });
514
515 test('convert an Iterable', () {
516 final set = new Set.from([1, 2, 3, 4, 5, 6, 7, 8]);
517 var array = new JsObject.jsify(set);
518 expect(context.callMethod('isArray', [array]), isTrue);
519 expect(array['length'], equals(set.length));
520 for (var i = 0; i < array['length'] ; i++) {
521 expect(set.contains(array[i]), isTrue);
522 }
523 });
524
525 test('convert a Map', () {
526 var map = {'a': 1, 'b': 2, 'c': 3};
527 var jsMap = new JsObject.jsify(map);
528 expect(!context.callMethod('isArray', [jsMap]), isTrue);
529 for (final key in map.keys) {
530 expect(context.callMethod('checkMap', [jsMap, key, map[key]]), isTrue);
531 }
532 });
533
534 test('deep convert a complex object', () {
535 final object = {
413 'a': [1, [2, 3]], 536 'a': [1, [2, 3]],
414 'b': { 537 'b': {
415 'c': 3, 538 'c': 3,
416 'd': new JsObject(context['Foo'], [42]) 539 'd': new JsObject(context['Foo'], [42])
417 }, 540 },
418 'e': null 541 'e': null
419 }; 542 };
420 var jsObject = jsify(object); 543 var jsObject = new JsObject.jsify(object);
421 expect(jsObject['a'][0], equals(object['a'][0])); 544 expect(jsObject['a'][0], equals(object['a'][0]));
422 expect(jsObject['a'][1][0], equals(object['a'][1][0])); 545 expect(jsObject['a'][1][0], equals(object['a'][1][0]));
423 expect(jsObject['a'][1][1], equals(object['a'][1][1])); 546 expect(jsObject['a'][1][1], equals(object['a'][1][1]));
424 expect(jsObject['b']['c'], equals(object['b']['c'])); 547 expect(jsObject['b']['c'], equals(object['b']['c']));
425 expect(jsObject['b']['d'], equals(object['b']['d'])); 548 expect(jsObject['b']['d'], equals(object['b']['d']));
426 expect(jsObject['b']['d'].callMethod('bar'), equals(42)); 549 expect(jsObject['b']['d'].callMethod('bar'), equals(42));
427 expect(jsObject['e'], isNull); 550 expect(jsObject['e'], isNull);
551 });
552
553 test('throws if object is not a Map or Iterable', () {
554 expect(() => new JsObject.jsify('a'),
555 throwsA(new isInstanceOf<ArgumentError>()));
556 });
428 }); 557 });
429 558
430 test('invoke Dart callback from JS', () { 559 group('JsObject methods', () {
431 expect(() => context.callMethod('invokeCallback'), throws); 560
432 561 test('hashCode and ==', () {
433 context['callback'] = new Callback(() => 42); 562 final o1 = context['Object'];
434 expect(context.callMethod('invokeCallback'), equals(42)); 563 final o2 = context['Object'];
435 564 expect(o1 == o2, isTrue);
436 context.deleteProperty('callback'); 565 expect(o1.hashCode == o2.hashCode, isTrue);
437 expect(() => context.callMethod('invokeCallback'), throws); 566 final d = context['document'];
438 567 expect(o1 == d, isFalse);
439 context['callback'] = () => 42; 568 });
440 expect(context.callMethod('invokeCallback'), equals(42)); 569
441 570 test('toString', () {
442 context.deleteProperty('callback'); 571 var foo = new JsObject(context['Foo'], [42]);
572 expect(foo.toString(), equals("I'm a Foo a=42"));
573 var container = context['container'];
574 expect(container.toString(), equals("[object Object]"));
575 });
576
577 test('toString returns a String even if the JS object does not', () {
578 var foo = new JsObject(context['Liar']);
579 expect(foo.callMethod('toString'), 1);
580 expect(foo.toString(), '1');
581 });
582
583 test('instanceof', () {
584 var foo = new JsObject(context['Foo'], [1]);
585 expect(foo.instanceof(context['Foo']), isTrue);
586 expect(foo.instanceof(context['Object']), isTrue);
587 expect(foo.instanceof(context['String']), isFalse);
588 });
589
590 test('deleteProperty', () {
591 var object = new JsObject.jsify({});
592 object['a'] = 1;
593 expect(context['Object'].callMethod('keys', [object])['length'], 1);
594 expect(context['Object'].callMethod('keys', [object])[0], "a");
595 object.deleteProperty("a");
596 expect(context['Object'].callMethod('keys', [object])['length'], 0);
597 });
598
599 /* TODO(jacobr): this is another test that is inconsistent with JS semantics.
600 test('deleteProperty throws if name is not a String or num', () {
601 var object = new JsObject.jsify({});
602 expect(() => object.deleteProperty(true),
603 throwsA(new isInstanceOf<ArgumentError>()));
604 });
605 */
606
607 test('hasProperty', () {
608 var object = new JsObject.jsify({});
609 object['a'] = 1;
610 expect(object.hasProperty('a'), isTrue);
611 expect(object.hasProperty('b'), isFalse);
612 });
613
614 /* TODO(jacobr): is this really the correct unchecked mode behavior?
615 test('hasProperty throws if name is not a String or num', () {
616 var object = new JsObject.jsify({});
617 expect(() => object.hasProperty(true),
618 throwsA(new isInstanceOf<ArgumentError>()));
619 });
620 */
621
622 test('[] and []=', () {
623 final myArray = context['myArray'];
624 expect(myArray['length'], equals(1));
625 expect(myArray[0], equals("value1"));
626 myArray[0] = "value2";
627 expect(myArray['length'], equals(1));
628 expect(myArray[0], equals("value2"));
629
630 final foo = new JsObject(context['Foo'], [1]);
631 foo["getAge"] = () => 10;
632 expect(foo.callMethod('getAge'), equals(10));
633 });
634
635 /* TODO(jacobr): remove as we should only throw this in checked mode.
636 test('[] and []= throw if name is not a String or num', () {
637 var object = new JsObject.jsify({});
638 expect(() => object[true],
639 throwsA(new isInstanceOf<ArgumentError>()));
640 expect(() => object[true] = 1,
641 throwsA(new isInstanceOf<ArgumentError>()));
642 });
643 */
443 }); 644 });
444 645
445 test('callback as parameter', () { 646 group('transferrables', () {
446 expect(context.callMethod('getTypeOf', [context['razzle']]), 647
447 equals("function")); 648 group('JS->Dart', () {
448 }); 649
449 650 test('Date', () {
450 test('invoke Dart callback from JS with this', () { 651 var date = context.callMethod('getNewDate');
451 final constructor = new Callback.withThis(($this, arg1) { 652 expect(date is Date, isTrue);
452 $this['a'] = 42; 653 });
453 $this['b'] = jsify(["a", arg1]); 654
454 }); 655 test('window', () {
455 var o = new JsObject(constructor, ["b"]); 656 expect(context['window'] is Window, isFalse);
456 expect(o['a'], equals(42)); 657 });
457 expect(o['b'][0], equals("a")); 658
458 expect(o['b'][1], equals("b")); 659 test('document', () {
459 }); 660 expect(context['document'] is Document, isTrue);
460 661 });
461 test('invoke Dart callback from JS with 11 parameters', () { 662
462 context['callbackWith11params'] = new Callback((p1, p2, p3, p4, p5, p6, p7, 663 test('Blob', () {
463 p8, p9, p10, p11) => '$p1$p2$p3$p4$p5$p6$p7$p8$p9$p10$p11'); 664 var blob = context.callMethod('getNewBlob');
464 expect(context.callMethod('invokeCallbackWith11params'), 665 expect(blob is Blob, isTrue);
465 equals('1234567891011')); 666 expect(blob.type, equals('text/html'));
466 }); 667 });
467 668
468 test('return a JS proxy to JavaScript', () { 669 test('unattached DivElement', () {
469 var result = context.callMethod('testJsMap', [() => jsify({'value': 42})]); 670 var node = context.callMethod('getNewDivElement');
470 expect(result, 42); 671 expect(node is Div, isTrue);
471 }); 672 });
472 673
473 test('test instanceof', () { 674 test('KeyRange', () {
474 var foo = new JsObject(context['Foo'], [1]); 675 if (IdbFactory.supported) {
475 expect(foo.instanceof(context['Foo']), isTrue); 676 var node = context.callMethod('getNewIDBKeyRange');
476 expect(foo.instanceof(context['Object']), isTrue); 677 expect(node is KeyRange, isTrue);
477 expect(foo.instanceof(context['String']), isFalse); 678 }
478 }); 679 });
479 680
480 test('test deleteProperty', () { 681 test('ImageData', () {
481 var object = jsify({}); 682 var node = context.callMethod('getNewImageData');
482 object['a'] = 1; 683 expect(node is ImageData, isTrue);
483 expect(context['Object'].callMethod('keys', [object])['length'], 1); 684 });
484 expect(context['Object'].callMethod('keys', [object])[0], "a"); 685
485 object.deleteProperty("a"); 686 test('typed data: Int32Array', () {
486 expect(context['Object'].callMethod('keys', [object])['length'], 0); 687 var list = context.callMethod('getNewInt32Array');
487 }); 688 print(list);
488 689 expect(list is Int32List, isTrue);
489 test('test hasProperty', () { 690 expect(list, orderedEquals([1, 2, 3, 4, 5, 6, 7, 8]));
490 var object = jsify({}); 691 });
491 object['a'] = 1; 692
492 expect(object.hasProperty('a'), isTrue); 693 });
493 expect(object.hasProperty('b'), isFalse); 694
494 }); 695 group('Dart->JS', () {
495 696
496 test('test index get and set', () { 697 test('Date', () {
497 final myArray = context['myArray']; 698 context['o'] = new DateTime(1995, 12, 17);
498 expect(myArray['length'], equals(1)); 699 var dateType = context['Date'];
499 expect(myArray[0], equals("value1")); 700 expect(context.callMethod('isPropertyInstanceOf', ['o', dateType]),
500 myArray[0] = "value2"; 701 isTrue);
501 expect(myArray['length'], equals(1)); 702 context.deleteProperty('o');
502 expect(myArray[0], equals("value2")); 703 });
503 704
504 final foo = new JsObject(context['Foo'], [1]); 705 test('window', () {
505 foo["getAge"] = () => 10; 706 context['o'] = window;
506 expect(foo.callMethod('getAge'), equals(10)); 707 var windowType = context['Window'];
507 }); 708 expect(context.callMethod('isPropertyInstanceOf', ['o', windowType]),
508 709 isFalse);
509 test('access a property of a function', () { 710 context.deleteProperty('o');
510 expect(context.callMethod('Bar'), "ret_value"); 711 });
511 expect(context['Bar']['foo'], "property_value"); 712
512 }); 713 test('document', () {
513 714 context['o'] = document;
514 test('usage of Serializable', () { 715 var documentType = context['Document'];
515 final red = Color.RED; 716 expect(context.callMethod('isPropertyInstanceOf', ['o', documentType]),
516 context['color'] = red; 717 isTrue);
517 expect(context['color'], equals(red._value)); 718 context.deleteProperty('o');
719 });
720
721 test('Blob', () {
722 var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
723 context['o'] = new Blob(fileParts, 'text/html');
724 var blobType = context['Blob'];
725 expect(context.callMethod('isPropertyInstanceOf', ['o', blobType]),
726 isTrue);
727 context.deleteProperty('o');
728 });
729
730 test('unattached DivElement', () {
731 context['o'] = new DivElement();
732 var divType = context['HTMLDivElement'];
733 expect(context.callMethod('isPropertyInstanceOf', ['o', divType]),
734 isTrue);
735 context.deleteProperty('o');
736 });
737
738 test('KeyRange', () {
739 if (IdbFactory.supported) {
740 context['o'] = new KeyRange.only(1);
741 var keyRangeType = context['IDBKeyRange'];
742 expect(context.callMethod('isPropertyInstanceOf', ['o', keyRangeType]) ,
743 isTrue);
744 context.deleteProperty('o');
745 }
746 });
747
748 test('ImageData', () {
749 var canvas = new CanvasElement();
750 var ctx = canvas.getContext('2d');
751 context['o'] = ctx.createImageData(1, 1);
752 var imageDataType = context['ImageData'];
753 expect(context.callMethod('isPropertyInstanceOf', ['o', imageDataType]),
754 isTrue);
755 context.deleteProperty('o');
756 });
757
758 test('typed data: Int32List', () {
759 context['o'] = new Int32List.fromList([1, 2, 3, 4]);
760 var listType = context['Int32Array'];
761 // TODO(jacobr): make this test pass. Currently some type information
762 // is lost when typed arrays are passed between JS and Dart.
763 // expect(context.callMethod('isPropertyInstanceOf', ['o', listType]),
764 // isTrue);
765 context.deleteProperty('o');
766 });
767
768 });
518 }); 769 });
519 } 770 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698