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

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

Issue 1213873004: Enhance dart:js interop in a backwards compatible manner. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: about to land Created 5 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 unified diff | Download patch
« no previous file with comments | « tests/html/html.status ('k') | tests/html/js_typed_interop_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 jsArrayTest;
6
7 import 'dart:html';
8 import 'dart:js';
9
10 import 'package:unittest/unittest.dart';
11 import 'package:unittest/html_config.dart';
12
13 _injectJs() {
14 document.body.append(new ScriptElement()
15 ..type = 'text/javascript'
16 ..innerHtml = r"""
17 function callJsMethod(jsObj, jsMethodName, args) {
18 return jsObj[jsMethodName].apply(jsObj, args);
19 }
20
21 function jsEnumerateIndices(obj) {
22 var ret = [];
23 for(var i in obj) {
24 ret.push(i);
25 }
26 return ret;
27 }
28
29 function setValue(obj, index, value) {
30 return obj[index] = value;
31 }
32
33 function getValue(obj, index) {
34 return obj[index];
35 }
36
37 function checkIsArray(obj) {
38 return Array.isArray(obj);
39 }
40
41 function concatValues(obj) {
42 return obj.concat("a", "b", ["c", "d"], 42, {foo: 10});
43 }
44
45 function concatOntoArray(obj) {
46 return [1,2,3].concat(obj, "foo");
47 }
48
49 function repeatedConcatOntoArray(obj) {
50 return [1,2,3].concat(obj, obj);
51 }
52
53 function everyGreaterThanZero(obj) {
54 return obj.every(function(currentValue, index, array) {
55 return currentValue > 0;
56 });
57 }
58
59 function everyGreaterThanZeroCheckThisArg(obj) {
60 var j = 0;
61 return obj.every(function(currentValue, index, array) {
62 if (j != index) {
63 throw "Unxpected index";
64 }
65 j++;
66 if (array !== obj) {
67 throw "Array argument doesn't match obj";
68 }
69 return currentValue > 0;
70 });
71 }
72
73 function filterGreater42(obj) {
74 return obj.filter(function(currentValue, index, array) {
75 return currentValue > 42;
76 });
77 }
78
79 function forEachCollectResult(array, callback) {
80 var result = [];
81 array.forEach(function(currentValue) {
82 result.push(currentValue * 2);
83 });
84 return result;
85 }
86
87 function someEqual42(array, callback) {
88 return array.some(function(currentValue) {
89 return currentValue == 42;
90 });
91 }
92
93 function sortNumbersBackwards(array) {
94 return array.sort(function(a, b) {
95 return b - a;
96 });
97 }
98
99 function spliceDummyItems(array) {
100 return array.splice(1, 2, "quick" ,"brown", "fox");
101 }
102
103 function spliceTestStringArgs(array) {
104 return array.splice("1.2", "2.01", "quick" ,"brown", "fox");
105 }
106
107 function splicePastEnd(array) {
108 return array.splice(1, 5332, "quick" ,"brown", "fox");
109 }
110
111 function callJsToString(array) {
112 return array.toString();
113 }
114
115 function mapAddIndexToEachElement(array) {
116 return array.map(function(currentValue, index) {
117 return currentValue + index;
118 });
119 }
120
121 function reduceSumDoubledElements(array) {
122 return array.reduce(function(previousValue, currentValue) {
123 return previousValue + currentValue*2;
124 },
125 0);
126 }
127
128 // TODO(jacobr): add a test that distinguishes reduce from reduceRight.
129 function reduceRightSumDoubledElements(array) {
130 return array.reduceRight(function(previousValue, currentValue) {
131 return previousValue + currentValue*2;
132 },
133 0);
134 }
135
136 function identical(o1, o2) {
137 return o1 === o2;
138 }
139
140 function getOwnPropertyDescriptorJson(array, property) {
141 return JSON.stringify(Object.getOwnPropertyDescriptor(array, property));
142 }
143
144 function setLength(array, len) {
145 return array.length = len;
146 }
147
148 function jsonStringify(o) {
149 return JSON.stringify(o);
150 }
151
152 // Calling a method from Dart List on an arbitrary target object.
153 function callListMethodOnTarget(dartArray, target, methodName, args) {
154 return dartArray[methodName].apply(target, args);
155 }
156
157 """);
158 }
159
160 class Foo {}
161
162 callJsMethod(List array, String methodName, List args) =>
163 context.callMethod("callJsMethod", [array, methodName, args]);
164
165 callIndexOf(List array, value) => callJsMethod(array, "indexOf", [value]);
166 callLastIndexOf(List array, value) =>
167 callJsMethod(array, "lastIndexOf", [value]);
168
169 callPop(List array) => callJsMethod(array, "pop", []);
170 callPush(List array, element) => callJsMethod(array, "push", [element]);
171 callShift(List array) => callJsMethod(array, "shift", []);
172 callReverse(List array) => callJsMethod(array, "reverse", []);
173 callSetLength(List array, length) =>
174 context.callMethod("setLength", [array, length]);
175
176 callListMethodOnObject(JsObject object, String methodName, List args) => context
177 .callMethod("callListMethodOnTarget", [[], object, methodName, args]);
178
179 jsonStringify(JsObject object) => context.callMethod("jsonStringify", [object]);
180
181 main() {
182 _injectJs();
183 useHtmlConfiguration();
184
185 group('indexOf', () {
186 var div = new DivElement();
187 var list = [3, 42, "foo", 42, div];
188 test('found', () {
189 expect(callIndexOf(list, 3), equals(0));
190 expect(callIndexOf(list, 42), equals(1));
191 expect(callIndexOf(list, "foo"), equals(2));
192 expect(callIndexOf(list, div), equals(4));
193 });
194
195 test('missing', () {
196 expect(callIndexOf(list, 31), equals(-1));
197 expect(callIndexOf(list, "42"), equals(-1));
198 expect(callIndexOf(list, null), equals(-1));
199 });
200 });
201
202 group('set length', () {
203 test('larger', () {
204 var list = ["a", "b", "c", "d"];
205 expect(callSetLength(list, 10), equals(10));
206 expect(list.length, equals(10));
207 expect(list.last, equals(null));
208 expect(list[3], equals("d"));
209 });
210
211 test('smaller', () {
212 var list = ["a", "b", "c", "d"];
213 expect(callSetLength(list, 2), equals(2));
214 expect(list.first, equals("a"));
215 expect(list.last, equals("b"));
216 expect(list.length, equals(2));
217 expect(callSetLength(list, 0), equals(0));
218 expect(list.length, equals(0));
219 expect(callSetLength(list, 2), equals(2));
220 expect(list.first, equals(null));
221 });
222
223 test('invalid', () {
224 var list = ["a", "b", "c", "d"];
225 expect(() => callSetLength(list, 2.3), throws);
226 expect(list.length, equals(4));
227 expect(() => callSetLength(list, -1), throws);
228 expect(list.length, equals(4));
229 // Make sure we are coercing to a JS number.
230 expect(callSetLength(list, "2"), equals("2"));
231 expect(list.length, equals(2));
232 });
233 });
234
235 group('join', () {
236 var list = [3, 42, "foo"];
237 var listWithDartClasses = [3, new Foo(), 42, "foo", new Object()];
238 test('default', () {
239 expect(callJsMethod(list, "join", []), equals("3,42,foo"));
240 expect(callJsMethod(listWithDartClasses, "join", []),
241 equals("3,Instance of 'Foo',42,foo,Instance of 'Object'"));
242 });
243
244 test('custom separator', () {
245 expect(callJsMethod(list, "join", ["##"]), equals("3##42##foo"));
246 });
247 });
248
249 group('lastIndexOf', () {
250 var list = [3, 42, "foo", 42];
251 test('found', () {
252 expect(callLastIndexOf(list, 3), equals(0));
253 expect(callLastIndexOf(list, 42), equals(3));
254 expect(callLastIndexOf(list, "foo"), equals(2));
255 });
256
257 test('missing', () {
258 expect(callLastIndexOf(list, 31), equals(-1));
259 expect(callLastIndexOf(list, "42"), equals(-1));
260 expect(callLastIndexOf(list, null), equals(-1));
261 });
262 });
263
264 group('pop', () {
265 test('all', () {
266 var foo = new Foo();
267 var div = new DivElement();
268 var list = [3, 42, "foo", foo, div];
269 expect(callPop(list), equals(div));
270 expect(list.length, equals(4));
271 expect(callPop(list), equals(foo));
272 expect(list.length, equals(3));
273 expect(callPop(list), equals("foo"));
274 expect(list.length, equals(2));
275 expect(callPop(list), equals(42));
276 expect(list.length, equals(1));
277 expect(callPop(list), equals(3));
278 expect(list.length, equals(0));
279 expect(callPop(list), equals(null));
280 expect(list.length, equals(0));
281 });
282 });
283
284 group('push', () {
285 test('strings', () {
286 var list = [];
287 var div = new DivElement();
288 expect(callPush(list, "foo"), equals(1));
289 expect(callPush(list, "bar"), equals(2));
290 // Calling push with 0 elements should do nothing.
291 expect(callJsMethod(list, "push", []), equals(2));
292 expect(callPush(list, "baz"), equals(3));
293 expect(callPush(list, div), equals(4));
294 expect(callJsMethod(list, "push", ["a", "b"]), equals(6));
295 expect(list, equals(["foo", "bar", "baz", div, "a", "b"]));
296 });
297 });
298
299 group('shift', () {
300 test('all', () {
301 var foo = new Foo();
302 var div = new DivElement();
303 var list = [3, 42, "foo", foo, div];
304 expect(callShift(list), equals(3));
305 expect(list.length, equals(4));
306 expect(callShift(list), equals(42));
307 expect(list.length, equals(3));
308 expect(callShift(list), equals("foo"));
309 expect(list.length, equals(2));
310 expect(callShift(list), equals(foo));
311 expect(list.length, equals(1));
312 expect(callShift(list), equals(div));
313 expect(list.length, equals(0));
314 expect(callShift(list), equals(null));
315 expect(list.length, equals(0));
316 });
317 });
318
319 group('reverse', () {
320 test('simple', () {
321 var foo = new Foo();
322 var div = new DivElement();
323 var list = [div, 42, foo];
324 callReverse(list);
325 expect(list, equals([foo, 42, div]));
326 list = [3, 42];
327 callReverse(list);
328 expect(list, equals([42, 3]));
329 });
330 });
331
332 group('slice', () {
333 test('copy', () {
334 var foo = new Foo();
335 var div = new DivElement();
336 var list = [3, 42, "foo", foo, div];
337 var copy = callJsMethod(list, "slice", []);
338 expect(identical(list, copy), isFalse);
339 expect(copy.length, equals(list.length));
340 for (var i = 0; i < list.length; i++) {
341 expect(list[i], equals(copy[i]));
342 }
343 expect(identical(list[3], copy[3]), isTrue);
344 expect(identical(list[4], copy[4]), isTrue);
345
346 copy.add("dummy");
347 expect(list.length + 1, equals(copy.length));
348 });
349
350 test('specify start', () {
351 var list = [3, 42, "foo"];
352 var copy = callJsMethod(list, "slice", [1]);
353 expect(copy.first, equals(42));
354 });
355
356 test('specify start and end', () {
357 var list = [3, 42, 92, "foo"];
358 var copy = callJsMethod(list, "slice", [1, 3]);
359 expect(copy.first, equals(42));
360 expect(copy.last, equals(92));
361 });
362
363 test('from end', () {
364 var list = [3, 42, 92, "foo"];
365 expect(callJsMethod(list, "slice", [-2]), equals([92, "foo"]));
366
367 // Past the end of the front of the array.
368 expect(callJsMethod(list, "slice", [-2, 3]), equals([92]));
369
370 // Past the end of the front of the array.
371 expect(callJsMethod(list, "slice", [-10, 2]), equals([3, 42]));
372 });
373 });
374
375 group("js snippet tests", () {
376 test("enumerate indices", () {
377 var list = ["a", "b", "c", "d"];
378 var indices = context.callMethod('jsEnumerateIndices', [list]);
379 expect(indices.length, equals(4));
380 for (int i = 0; i < 4; i++) {
381 expect(indices[i], equals('$i'));
382 }
383 });
384
385 test("set element", () {
386 var list = ["a", "b", "c", "d"];
387 context.callMethod('setValue', [list, 0, 42]);
388 expect(list[0], equals(42));
389 context.callMethod('setValue', [list, 1, 84]);
390 expect(list[1], equals(84));
391 context.callMethod(
392 'setValue', [list, 6, 100]); // Off the end of the list.
393 expect(list.length, equals(7));
394 expect(list[4], equals(null));
395 expect(list[6], equals(100));
396
397 // These tests have to be commented out because we don't persist
398 // JS proxies for Dart objects like we could/should.
399 // context.callMethod('setValue', [list, -1, "foo"]); // Not a valid array index
400 // expect(context.callMethod('getValue', [list, -1]), equals("foo"));
401 // expect(context.callMethod('getValue', [list, "-1"]), equals("foo"));
402 });
403
404 test("get element", () {
405 var list = ["a", "b", "c", "d"];
406 expect(context.callMethod('getValue', [list, 0]), equals("a"));
407 expect(context.callMethod('getValue', [list, 1]), equals("b"));
408 expect(context.callMethod('getValue', [list, 6]), equals(null));
409 expect(context.callMethod('getValue', [list, -1]), equals(null));
410
411 expect(context.callMethod('getValue', [list, "0"]), equals("a"));
412 expect(context.callMethod('getValue', [list, "1"]), equals("b"));
413 });
414
415 test("is array", () {
416 var list = ["a", "b"];
417 expect(context.callMethod("checkIsArray", [list]), isTrue);
418 });
419
420 test("property descriptors", () {
421 // This test matters to make behavior consistent with JS native arrays
422 // and to make devtools integration work well.
423 var list = ["a", "b"];
424 expect(context.callMethod("getOwnPropertyDescriptorJson", [list, 0]),
425 equals('{"value":"a",'
426 '"writable":true,'
427 '"enumerable":true,'
428 '"configurable":true}'));
429
430 expect(
431 context.callMethod("getOwnPropertyDescriptorJson", [list, "length"]),
432 equals('{"value":2,'
433 '"writable":true,'
434 '"enumerable":false,'
435 '"configurable":false}'));
436 });
437
438 test("concat js arrays", () {
439 var list = ["1", "2"];
440 // Tests that calling the concat method from JS will flatten out JS arrays
441 // We concat the array with "a", "b", ["c", "d"], 42, {foo: 10}
442 // which should generate ["1", "2", "a", "b", ["c", "d"], 42, {foo: 10}]
443 var ret = context.callMethod("concatValues", [list]);
444 expect(list.length, equals(2));
445 expect(ret.length, equals(8));
446 expect(ret[0], equals("1"));
447 expect(ret[3], equals("b"));
448 expect(ret[5], equals("d"));
449 expect(ret[6], equals(42));
450 expect(ret[7]['foo'], equals(10));
451 });
452
453 test("concat onto arrays", () {
454 // This test only passes if we have monkey patched the core Array object
455 // prototype to handle Dart Lists.
456 var list = ["a", "b"];
457 var ret = context.callMethod("concatOntoArray", [list]);
458 expect(list.length, equals(2));
459 expect(ret, equals([1, 2, 3, "a", "b", "foo"]));
460 });
461
462 test("dart arrays on dart arrays", () {
463 // This test only passes if we have monkey patched the core Array object
464 // prototype to handle Dart Lists.
465 var list = ["a", "b"];
466 var ret = callJsMethod(list, "concat", [["c", "d"], "e", ["f", "g"]]);
467 expect(list.length, equals(2));
468 expect(ret, equals(["a", "b", "c", "d", "e", "f", "g"]));
469 });
470
471 test("every greater than zero", () {
472 expect(context.callMethod("everyGreaterThanZero", [[1, 5]]), isTrue);
473 expect(context.callMethod("everyGreaterThanZeroCheckThisArg", [[1, 5]]),
474 isTrue);
475 expect(context.callMethod("everyGreaterThanZero", [[1, 0]]), isFalse);
476 expect(context.callMethod("everyGreaterThanZero", [[]]), isTrue);
477 });
478
479 test("filter greater than 42", () {
480 expect(context.callMethod("filterGreater42", [[1, 5]]), equals([]));
481 expect(context.callMethod("filterGreater42", [[43, 5, 49]]),
482 equals([43, 49]));
483 expect(context.callMethod("filterGreater42", [["43", "5", "49"]]),
484 equals(["43", "49"]));
485 });
486
487 test("for each collect result", () {
488 expect(context.callMethod("forEachCollectResult", [[1, 5, 7]]),
489 equals([2, 10, 14]));
490 });
491
492 test("some", () {
493 expect(context.callMethod("someEqual42", [[1, 5, 9]]), isFalse);
494 expect(context.callMethod("someEqual42", [[1, 42, 9]]), isTrue);
495 });
496
497 test("sort backwards", () {
498 var arr = [1, 5, 9];
499 var ret = context.callMethod("sortNumbersBackwards", [arr]);
500 expect(identical(arr, ret), isTrue);
501 expect(ret, equals([9, 5, 1]));
502 });
503
504 test("splice dummy items", () {
505 var list = [1, 2, 3, 4];
506 var removed = context.callMethod("spliceDummyItems", [list]);
507 expect(removed.length, equals(2));
508 expect(removed[0], equals(2));
509 expect(removed[1], equals(3));
510 expect(list.first, equals(1));
511 expect(list[1], equals("quick"));
512 expect(list[2], equals("brown"));
513 expect(list[3], equals("fox"));
514 expect(list.last, equals(4));
515 });
516
517 test("splice string args", () {
518 var list = [1, 2, 3, 4];
519 var removed = context.callMethod("spliceTestStringArgs", [list]);
520 expect(removed.length, equals(2));
521 expect(removed[0], equals(2));
522 expect(removed[1], equals(3));
523 expect(list.first, equals(1));
524 expect(list[1], equals("quick"));
525 expect(list[2], equals("brown"));
526 expect(list[3], equals("fox"));
527 expect(list.last, equals(4));
528 });
529
530 test("splice pastEndOfArray", () {
531 var list = [1, 2, 3, 4];
532 var removed = context.callMethod("splicePastEnd", [list]);
533 expect(removed.length, equals(3));
534 expect(list.first, equals(1));
535 expect(list.length, equals(4));
536 expect(list[1], equals("quick"));
537 expect(list[2], equals("brown"));
538 expect(list[3], equals("fox"));
539 });
540
541 test("splice both bounds past end of array", () {
542 var list = [1];
543 var removed = context.callMethod("splicePastEnd", [list]);
544 expect(removed.length, equals(0));
545 expect(list.first, equals(1));
546 expect(list.length, equals(4));
547 expect(list[1], equals("quick"));
548 expect(list[2], equals("brown"));
549 expect(list[3], equals("fox"));
550 });
551
552 test("call List method on JavaScript object", () {
553 var jsObject = new JsObject.jsify({});
554 callListMethodOnObject(jsObject, 'push', ["a"]);
555 callListMethodOnObject(jsObject, 'push', ["b"]);
556 callListMethodOnObject(jsObject, 'push', ["c", "d"]);
557 callListMethodOnObject(jsObject, 'push', []);
558
559 expect(jsonStringify(jsObject),
560 equals('{"0":"a","1":"b","2":"c","3":"d","length":4}'));
561
562 expect(callListMethodOnObject(jsObject, 'pop', []), equals("d"));
563 expect(callListMethodOnObject(jsObject, 'join', ["#"]), equals("a#b#c"));
564
565 var jsArray = new JsObject.jsify([]);
566 callListMethodOnObject(jsArray, 'push', ["a"]);
567 callListMethodOnObject(jsArray, 'push', ["b"]);
568 callListMethodOnObject(jsArray, 'push', ["c", "d"]);
569 callListMethodOnObject(jsArray, 'push', []);
570
571 expect(jsonStringify(jsArray), equals('["a","b","c","d"]'));
572 });
573 });
574
575 // This test group is disabled until we figure out an efficient way to
576 // distinguish between "array" Dart List types and non-array Dart list types.
577 /*
578 group('Non-array Lists', () {
579 test('opaque proxy', () {
580 // Dartium could easily support making LinkedList and all other classes
581 // implementing List behave like a JavaScript array but that would
582 // be challenging to implement in dart2js until browsers support ES6.
583 var list = ["a", "b", "c", "d"];
584 var listView = new UnmodifiableListView(list.getRange(1,3));
585 expect(listView is List, isTrue);
586 expect(listView.length, equals(2));
587 expect(context.callMethod("checkIsArray", [listView]), isFalse);
588 expect(context.callMethod("checkIsArray", [listView.toList()]), isTrue);
589 expect(context.callMethod("getOwnPropertyDescriptorJson",
590 [listView, "length"]), equals("null"));
591 });
592 });
593 */
594 }
OLDNEW
« no previous file with comments | « tests/html/html.status ('k') | tests/html/js_typed_interop_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698