OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, 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 import "dart:collection"; | |
6 import "dart:typed_data"; | |
7 import "package:expect/expect.dart"; | |
8 | |
9 void main() { | |
10 // Typed lists - fixed length and can only contain integers. | |
11 testTypedList(new Uint8List(4)); | |
12 testTypedList(new Int8List(4)); | |
13 testTypedList(new Uint16List(4)); | |
14 testTypedList(new Int16List(4)); | |
15 testTypedList(new Uint32List(4)); | |
16 testTypedList(new Int32List(4)); | |
17 testTypedList(new Uint8List(4).toList(growable: false)); | |
18 testTypedList(new Int8List(4).toList(growable: false)); | |
19 testTypedList(new Uint16List(4).toList(growable: false)); | |
20 testTypedList(new Int16List(4).toList(growable: false)); | |
21 testTypedList(new Uint32List(4).toList(growable: false)); | |
22 testTypedList(new Int32List(4).toList(growable: false)); | |
23 | |
24 // Fixed length lists, length 4. | |
25 testFixedLengthList(new List(4)); | |
26 testFixedLengthList(new List(4).toList(growable: false)); | |
27 testFixedLengthList((new List()..length = 4).toList(growable: false)); | |
28 // ListBase implementation of List. | |
29 testFixedLengthList(new MyFixedList(new List(4))); | |
30 testFixedLengthList(new MyFixedList(new List(4)).toList(growable: false)); | |
31 | |
32 // Growable lists. Initial length 0. | |
33 testGrowableList(new List()); | |
34 testGrowableList(new List().toList()); | |
35 testGrowableList(new List(0).toList()); | |
36 testGrowableList(new List.filled(0, null, growable: true)); | |
37 testGrowableList([]); | |
38 testGrowableList((const []).toList()); | |
39 testGrowableList(new MyList([])); | |
40 testGrowableList(new MyList([]).toList()); | |
41 | |
42 testTypedGrowableList(new Uint8List(0).toList()); | |
43 testTypedGrowableList(new Int8List(0).toList()); | |
44 testTypedGrowableList(new Uint16List(0).toList()); | |
45 testTypedGrowableList(new Int16List(0).toList()); | |
46 testTypedGrowableList(new Uint32List(0).toList()); | |
47 testTypedGrowableList(new Int32List(0).toList()); | |
48 | |
49 testListConstructor(); | |
50 | |
51 testErrors(); | |
52 } | |
53 | |
54 void testErrors() { | |
55 // Regression for issue http://dartbug.com/24295 | |
56 testIndexError(list, index, name) { | |
57 try { | |
58 list[list.length]; | |
59 } catch (err, s) { | |
60 Expect.isTrue(err is RangeError, "$name[$index]"); | |
61 Expect.equals(list.length, err.invalidValue, "$name[$index] value"); | |
62 Expect.equals(list.length - 1, err.end, "$name[$index] end"); | |
63 Expect.equals(0, err.start, "$name[$index] start"); | |
64 } | |
65 } | |
66 | |
67 testIndex(list, name) { | |
68 testIndexError(list, list.length, name); // Just too big. | |
69 testIndexError(list, -1, name); // Negative. | |
70 testIndexError(list, 0x123456789, name); // > 2^32. | |
71 testIndexError(list, -0x123456789, name); // < -2^32. | |
72 } | |
73 | |
74 // Slices. | |
75 testSliceError(list, start, end, name) { | |
76 name = "$name[$start:$end]"; | |
77 var realError; | |
78 try { | |
79 RangeError.checkValidRange(start, end, list.length); | |
80 } catch (e) { | |
81 realError = e; | |
82 } | |
83 var result; | |
84 try { | |
85 result = list.sublist(start, end); | |
86 } catch (actualError) { | |
87 Expect.isNotNull(realError, "$name should not fail"); | |
88 Expect.isTrue(actualError is RangeError, "$name is-error: $actualError"); | |
89 Expect.equals(realError.name, actualError.name, "$name name"); | |
90 Expect.equals(realError.invalidValue, actualError.invalidValue, | |
91 "$name[0:l+1] value"); | |
92 Expect.equals(realError.start, actualError.start, "$name[0:l+1] start"); | |
93 Expect.equals(realError.end, actualError.end, "$name[0:l+1] end"); | |
94 return; | |
95 } | |
96 // Didn't throw. | |
97 Expect.isNull(realError, "$name should fail"); | |
98 Expect.equals(end - start, result.length, "$name result length"); | |
99 } | |
100 | |
101 testSlice(list, name) { | |
102 testSliceError(list, 0, list.length, name); // Should not fail. | |
103 testSliceError(list, 0, list.length + 1, name); | |
104 testSliceError(list, 0, 0x123456789, name); | |
105 testSliceError(list, -1, list.length, name); | |
106 testSliceError(list, -0x123456789, list.length, name); | |
107 testSliceError(list, list.length + 1, list.length + 1, name); | |
108 testSliceError(list, -1, null, name); | |
109 if (list.length > 0) { | |
110 testSliceError(list, list.length, list.length - 1, name); | |
111 } | |
112 } | |
113 | |
114 testRangeErrors(list, name) { | |
115 testIndex(list, "$name#${list.length} index"); | |
116 testSlice(list, "$name#${list.length} slice"); | |
117 } | |
118 | |
119 // Empty lists. | |
120 testRangeErrors([], "list"); | |
121 testRangeErrors(new List(0), "fixed-list"); | |
122 testRangeErrors(const [], "const-list"); | |
123 testRangeErrors(new List.unmodifiable([]), "unmodifiable"); | |
124 testRangeErrors(new Uint8List(0), "typed-list"); | |
125 testRangeErrors(new Uint8List.view(new Uint8List(0).buffer), "typed-list"); | |
126 testRangeErrors([1, 2, 3].sublist(1, 1), "sub-list"); | |
127 // Non-empty lists. | |
128 testRangeErrors([1, 2, 3], "list"); | |
129 testRangeErrors(new List(3), "fixed-list"); | |
130 testRangeErrors(const [1, 2, 3], "const-list"); | |
131 testRangeErrors(new List.unmodifiable([1, 2, 3]), "unmodifiable"); | |
132 testRangeErrors(new Uint8List(3), "typed-list"); | |
133 testRangeErrors(new Uint8List.view(new Uint8List(3).buffer), "typed-list"); | |
134 testRangeErrors([1, 2, 3, 4, 5].sublist(1, 3), "sub-list"); | |
135 } | |
136 | |
137 void testLength(int length, List list) { | |
138 Expect.equals(length, list.length); | |
139 (length == 0 ? Expect.isTrue : Expect.isFalse)(list.isEmpty); | |
140 (length != 0 ? Expect.isTrue : Expect.isFalse)(list.isNotEmpty); | |
141 } | |
142 | |
143 void testTypedLengthInvariantOperations(List list) { | |
144 // length | |
145 Expect.equals(list.length, 4); | |
146 // operators [], []=. | |
147 for (int i = 0; i < 4; i++) list[i] = 0; | |
148 list[0] = 4; | |
149 Expect.listEquals([4, 0, 0, 0], list); | |
150 list[1] = 7; | |
151 Expect.listEquals([4, 7, 0, 0], list); | |
152 list[3] = 2; | |
153 Expect.listEquals([4, 7, 0, 2], list); | |
154 | |
155 for (int i = 0; i < list.length; i++) { | |
156 list[i] = i; | |
157 } | |
158 | |
159 // indexOf, lastIndexOf | |
160 for (int i = 0; i < 4; i++) { | |
161 Expect.equals(i, list[i]); | |
162 Expect.equals(i, list.indexOf(i)); | |
163 Expect.equals(i, list.lastIndexOf(i)); | |
164 } | |
165 | |
166 // setRange. | |
167 list.setRange(0, 4, [3, 2, 1, 0]); | |
168 Expect.listEquals([3, 2, 1, 0], list); | |
169 | |
170 list.setRange(1, 4, list); | |
171 Expect.listEquals([3, 3, 2, 1], list); | |
172 | |
173 list.setRange(0, 3, list, 1); | |
174 Expect.listEquals([3, 2, 1, 1], list); | |
175 list.setRange(0, 3, list, 1); | |
176 Expect.listEquals([2, 1, 1, 1], list); | |
177 | |
178 list.setRange(2, 4, list, 0); | |
179 Expect.listEquals([2, 1, 2, 1], list); | |
180 | |
181 // setAll. | |
182 list.setAll(0, [3, 2, 0, 1]); | |
183 Expect.listEquals([3, 2, 0, 1], list); | |
184 list.setAll(1, [0, 1]); | |
185 Expect.listEquals([3, 0, 1, 1], list); | |
186 | |
187 // fillRange. | |
188 list.fillRange(1, 3, 7); | |
189 Expect.listEquals([3, 7, 7, 1], list); | |
190 list.fillRange(0, 0, 9); | |
191 Expect.listEquals([3, 7, 7, 1], list); | |
192 list.fillRange(4, 4, 9); | |
193 Expect.listEquals([3, 7, 7, 1], list); | |
194 list.fillRange(0, 4, 9); | |
195 Expect.listEquals([9, 9, 9, 9], list); | |
196 | |
197 // sort. | |
198 list.setRange(0, 4, [3, 2, 1, 0]); | |
199 list.sort(); | |
200 Expect.listEquals([0, 1, 2, 3], list); | |
201 list.setRange(0, 4, [1, 2, 3, 0]); | |
202 list.sort(); | |
203 Expect.listEquals([0, 1, 2, 3], list); | |
204 list.setRange(0, 4, [1, 3, 0, 2]); | |
205 list.sort((a, b) => b - a); // reverse compare. | |
206 Expect.listEquals([3, 2, 1, 0], list); | |
207 list.setRange(0, 4, [1, 2, 3, 0]); | |
208 list.sort((a, b) => b - a); | |
209 Expect.listEquals([3, 2, 1, 0], list); | |
210 | |
211 // Some Iterable methods. | |
212 | |
213 list.setRange(0, 4, [0, 1, 2, 3]); | |
214 // map. | |
215 testMap(val) { | |
216 return val * 2 + 10; | |
217 } | |
218 | |
219 List mapped = list.map(testMap).toList(); | |
220 Expect.equals(mapped.length, list.length); | |
221 for (var i = 0; i < list.length; i++) { | |
222 Expect.equals(mapped[i], list[i] * 2 + 10); | |
223 } | |
224 | |
225 matchAll(val) => true; | |
226 matchSome(val) { | |
227 return (val == 1 || val == 2); | |
228 } | |
229 | |
230 matchSomeFirst(val) { | |
231 return val == 0; | |
232 } | |
233 | |
234 matchSomeLast(val) { | |
235 return val == 3; | |
236 } | |
237 | |
238 matchNone(val) => false; | |
239 | |
240 // where. | |
241 Iterable filtered = list.where(matchSome); | |
242 Expect.equals(filtered.length, 2); | |
243 | |
244 // every | |
245 Expect.isTrue(list.every(matchAll)); | |
246 Expect.isFalse(list.every(matchSome)); | |
247 Expect.isFalse(list.every(matchNone)); | |
248 | |
249 // any | |
250 Expect.isTrue(list.any(matchAll)); | |
251 Expect.isTrue(list.any(matchSome)); | |
252 Expect.isTrue(list.any(matchSomeFirst)); | |
253 Expect.isTrue(list.any(matchSomeLast)); | |
254 Expect.isFalse(list.any(matchNone)); | |
255 | |
256 // Argument checking isn't implemented for typed arrays in browsers, | |
257 // so it's moved to the method below for now. | |
258 } | |
259 | |
260 void testLengthInvariantOperations(List list) { | |
261 testTypedLengthInvariantOperations(list); | |
262 // Tests that need untyped lists. | |
263 list.setAll(0, [0, 1, 2, 3]); | |
264 Expect.equals(-1, list.indexOf(100)); | |
265 Expect.equals(-1, list.lastIndexOf(100)); | |
266 list[2] = new Yes(); | |
267 Expect.equals(2, list.indexOf(100)); | |
268 Expect.equals(2, list.lastIndexOf(100)); | |
269 list[3] = new Yes(); | |
270 Expect.equals(2, list.indexOf(100)); | |
271 Expect.equals(3, list.lastIndexOf(100)); | |
272 list[2] = 2; | |
273 Expect.equals(3, list.indexOf(100)); | |
274 Expect.equals(3, list.lastIndexOf(100)); | |
275 list[3] = 3; | |
276 Expect.equals(-1, list.indexOf(100)); | |
277 Expect.equals(-1, list.lastIndexOf(100)); | |
278 | |
279 // Argument errors on bad indices. List is still [0, 1, 2, 3]. | |
280 testArgumentError(action()) { | |
281 Expect.throws(action, (e) => e is ArgumentError); | |
282 } | |
283 | |
284 // Direct indices (0 <= index < length). | |
285 testArgumentError(() => list[-1]); | |
286 testArgumentError(() => list[4]); | |
287 testArgumentError(() => list[-1] = 99); | |
288 testArgumentError(() => list[4] = 99); | |
289 testArgumentError(() => list.elementAt(-1)); | |
290 testArgumentError(() => list.elementAt(4)); | |
291 // Ranges (0 <= start <= end <= length). | |
292 testArgumentError(() => list.sublist(-1, 2)); | |
293 testArgumentError(() => list.sublist(-1, 5)); | |
294 testArgumentError(() => list.sublist(2, 5)); | |
295 testArgumentError(() => list.sublist(4, 2)); | |
296 testArgumentError(() => list.getRange(-1, 2)); | |
297 testArgumentError(() => list.getRange(-1, 5)); | |
298 testArgumentError(() => list.getRange(2, 5)); | |
299 testArgumentError(() => list.getRange(4, 2)); | |
300 testArgumentError(() => list.setRange(-1, 2, [1, 2, 3])); | |
301 testArgumentError(() => list.setRange(-1, 5, [1, 2, 3, 4, 5, 6])); | |
302 testArgumentError(() => list.setRange(2, 5, [1, 2, 3])); | |
303 testArgumentError(() => list.setRange(4, 2, [1, 2])); | |
304 // for setAll, end is implicitly start + values.length. | |
305 testArgumentError(() => list.setAll(-1, [])); | |
306 testArgumentError(() => list.setAll(5, [])); | |
307 testArgumentError(() => list.setAll(2, [1, 2, 3])); | |
308 testArgumentError(() => list.fillRange(-1, 2)); | |
309 testArgumentError(() => list.fillRange(-1, 5)); | |
310 testArgumentError(() => list.fillRange(2, 5)); | |
311 testArgumentError(() => list.fillRange(4, 2)); | |
312 } | |
313 | |
314 void testTypedList(List list) { | |
315 testTypedLengthInvariantOperations(list); | |
316 testCannotChangeLength(list); | |
317 } | |
318 | |
319 void testFixedLengthList(List list) { | |
320 testLengthInvariantOperations(list); | |
321 testCannotChangeLength(list); | |
322 } | |
323 | |
324 void testCannotChangeLength(List list) { | |
325 isUnsupported(action()) { | |
326 Expect.throws(action, (e) => e is UnsupportedError); | |
327 } | |
328 | |
329 isUnsupported(() => list.add(0)); | |
330 isUnsupported(() => list.addAll([0])); | |
331 isUnsupported(() => list.removeLast()); | |
332 isUnsupported(() => list.insert(0, 1)); | |
333 isUnsupported(() => list.insertAll(0, [1])); | |
334 isUnsupported(() => list.clear()); | |
335 isUnsupported(() => list.remove(1)); | |
336 isUnsupported(() => list.removeAt(1)); | |
337 isUnsupported(() => list.removeRange(0, 1)); | |
338 isUnsupported(() => list.replaceRange(0, 1, [])); | |
339 } | |
340 | |
341 void testTypedGrowableList(List list) { | |
342 testLength(0, list); | |
343 // set length. | |
344 list.length = 4; | |
345 testLength(4, list); | |
346 | |
347 testTypedLengthInvariantOperations(list); | |
348 | |
349 testGrowableListOperations(list); | |
350 } | |
351 | |
352 void testGrowableList(List list) { | |
353 testLength(0, list); | |
354 // set length. | |
355 list.length = 4; | |
356 testLength(4, list); | |
357 | |
358 testLengthInvariantOperations(list); | |
359 | |
360 testGrowableListOperations(list); | |
361 } | |
362 | |
363 void testGrowableListOperations(List list) { | |
364 // add, removeLast. | |
365 list.clear(); | |
366 testLength(0, list); | |
367 list.add(4); | |
368 testLength(1, list); | |
369 Expect.equals(4, list.removeLast()); | |
370 testLength(0, list); | |
371 | |
372 for (int i = 0; i < 100; i++) { | |
373 list.add(i); | |
374 } | |
375 | |
376 Expect.equals(list.length, 100); | |
377 for (int i = 0; i < 100; i++) { | |
378 Expect.equals(i, list[i]); | |
379 } | |
380 | |
381 Expect.equals(17, list.indexOf(17)); | |
382 Expect.equals(17, list.lastIndexOf(17)); | |
383 Expect.equals(-1, list.indexOf(999)); | |
384 Expect.equals(-1, list.lastIndexOf(999)); | |
385 | |
386 Expect.equals(99, list.removeLast()); | |
387 testLength(99, list); | |
388 | |
389 // remove. | |
390 Expect.isTrue(list.remove(4)); | |
391 testLength(98, list); | |
392 Expect.isFalse(list.remove(4)); | |
393 testLength(98, list); | |
394 list.clear(); | |
395 testLength(0, list); | |
396 | |
397 list.add(4); | |
398 list.add(4); | |
399 testLength(2, list); | |
400 Expect.isTrue(list.remove(4)); | |
401 testLength(1, list); | |
402 Expect.isTrue(list.remove(4)); | |
403 testLength(0, list); | |
404 Expect.isFalse(list.remove(4)); | |
405 testLength(0, list); | |
406 | |
407 // removeWhere, retainWhere | |
408 for (int i = 0; i < 100; i++) { | |
409 list.add(i); | |
410 } | |
411 testLength(100, list); | |
412 list.removeWhere((int x) => x.isOdd); | |
413 testLength(50, list); | |
414 for (int i = 0; i < list.length; i++) { | |
415 Expect.isTrue(list[i].isEven); | |
416 } | |
417 list.retainWhere((int x) => (x % 3) == 0); | |
418 testLength(17, list); | |
419 for (int i = 0; i < list.length; i++) { | |
420 Expect.isTrue((list[i] % 6) == 0); | |
421 } | |
422 | |
423 // insert, remove, removeAt | |
424 list.clear(); | |
425 testLength(0, list); | |
426 | |
427 list.insert(0, 0); | |
428 Expect.listEquals([0], list); | |
429 | |
430 list.insert(0, 1); | |
431 Expect.listEquals([1, 0], list); | |
432 | |
433 list.insert(0, 2); | |
434 Expect.listEquals([2, 1, 0], list); | |
435 | |
436 Expect.isTrue(list.remove(1)); | |
437 Expect.listEquals([2, 0], list); | |
438 | |
439 list.insert(1, 1); | |
440 Expect.listEquals([2, 1, 0], list); | |
441 | |
442 list.removeAt(1); | |
443 Expect.listEquals([2, 0], list); | |
444 | |
445 list.removeAt(1); | |
446 Expect.listEquals([2], list); | |
447 | |
448 // insertAll | |
449 list.insertAll(0, [1, 2, 3]); | |
450 Expect.listEquals([1, 2, 3, 2], list); | |
451 | |
452 list.insertAll(2, []); | |
453 Expect.listEquals([1, 2, 3, 2], list); | |
454 | |
455 list.insertAll(4, [7, 9]); | |
456 Expect.listEquals([1, 2, 3, 2, 7, 9], list); | |
457 | |
458 // addAll | |
459 list.addAll(list.reversed.toList()); | |
460 Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list); | |
461 | |
462 list.addAll([]); | |
463 Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list); | |
464 | |
465 // replaceRange | |
466 list.replaceRange(3, 7, [0, 0]); | |
467 Expect.listEquals([1, 2, 3, 0, 0, 7, 2, 3, 2, 1], list); | |
468 | |
469 list.replaceRange(2, 3, [5, 5, 5]); | |
470 Expect.listEquals([1, 2, 5, 5, 5, 0, 0, 7, 2, 3, 2, 1], list); | |
471 | |
472 list.replaceRange(2, 4, [6, 6]); | |
473 Expect.listEquals([1, 2, 6, 6, 5, 0, 0, 7, 2, 3, 2, 1], list); | |
474 | |
475 list.replaceRange(6, 8, []); | |
476 Expect.listEquals([1, 2, 6, 6, 5, 0, 2, 3, 2, 1], list); | |
477 | |
478 // Operations that change the length cause ConcurrentModificationError. | |
479 void testConcurrentModification(action()) { | |
480 testIterator(int when) { | |
481 list.length = 4; | |
482 list.setAll(0, [0, 1, 2, 3]); | |
483 Expect.throws(() { | |
484 for (var element in list) { | |
485 if (element == when) action(); | |
486 } | |
487 }, (e) => e is ConcurrentModificationError); | |
488 } | |
489 | |
490 testForEach(int when) { | |
491 list.length = 4; | |
492 list.setAll(0, [0, 1, 2, 3]); | |
493 Expect.throws(() { | |
494 list.forEach((var element) { | |
495 if (element == when) action(); | |
496 }); | |
497 }, (e) => e is ConcurrentModificationError); | |
498 } | |
499 | |
500 // Test the change at different points of the iteration. | |
501 testIterator(0); | |
502 testIterator(1); | |
503 testIterator(3); | |
504 testForEach(0); | |
505 testForEach(1); | |
506 testForEach(3); | |
507 } | |
508 | |
509 testConcurrentModification(() => list.add(5)); | |
510 testConcurrentModification(() => list.addAll([5, 6])); | |
511 testConcurrentModification(() => list.removeLast()); | |
512 for (int i = 0; i < 4; i++) { | |
513 testConcurrentModification(() => list.remove(i)); | |
514 testConcurrentModification(() => list.removeAt(i)); | |
515 testConcurrentModification(() => list.removeWhere((x) => x == i)); | |
516 testConcurrentModification(() => list.retainWhere((x) => x != i)); | |
517 testConcurrentModification(() => list.insert(i, 5)); | |
518 testConcurrentModification(() => list.insertAll(i, [5, 6])); | |
519 testConcurrentModification(() => list.removeRange(i, i + 1)); | |
520 testConcurrentModification(() => list.replaceRange(i, i + 1, [5, 6])); | |
521 } | |
522 | |
523 // Any operation that doesn't change the length should be safe for iteration. | |
524 testSafeConcurrentModification(action()) { | |
525 list.length = 4; | |
526 list.setAll(0, [0, 1, 2, 3]); | |
527 for (var i in list) { | |
528 action(); | |
529 } | |
530 list.forEach((e) => action()); | |
531 } | |
532 | |
533 testSafeConcurrentModification(() { | |
534 list.add(5); | |
535 list.removeLast(); | |
536 }); | |
537 testSafeConcurrentModification(() { | |
538 list.add(list[0]); | |
539 list.removeAt(0); | |
540 }); | |
541 testSafeConcurrentModification(() { | |
542 list.insert(0, list.removeLast()); | |
543 }); | |
544 testSafeConcurrentModification(() { | |
545 list.replaceRange(1, 3, list.sublist(1, 3).reversed); | |
546 }); | |
547 | |
548 // Argument errors on bad indices for methods that are only allowed | |
549 // on growable lists. | |
550 list.length = 4; | |
551 list.setAll(0, [0, 1, 2, 3]); | |
552 testArgumentError(action()) { | |
553 Expect.throws(action, (e) => e is ArgumentError); | |
554 } | |
555 | |
556 // Direct indices (0 <= index < length). | |
557 testArgumentError(() => list.removeAt(-1)); | |
558 testArgumentError(() => list.removeAt(4)); | |
559 // Direct indices including end (0 <= index <= length). | |
560 testArgumentError(() => list.insert(-1, 0)); | |
561 testArgumentError(() => list.insert(5, 0)); | |
562 testArgumentError(() => list.insertAll(-1, [0])); | |
563 testArgumentError(() => list.insertAll(5, [0])); | |
564 testArgumentError(() => list.insertAll(-1, [0])); | |
565 testArgumentError(() => list.insertAll(5, [0])); | |
566 // Ranges (0 <= start <= end <= length). | |
567 testArgumentError(() => list.removeRange(-1, 2)); | |
568 testArgumentError(() => list.removeRange(2, 5)); | |
569 testArgumentError(() => list.removeRange(-1, 5)); | |
570 testArgumentError(() => list.removeRange(4, 2)); | |
571 testArgumentError(() => list.replaceRange(-1, 2, [9])); | |
572 testArgumentError(() => list.replaceRange(2, 5, [9])); | |
573 testArgumentError(() => list.replaceRange(-1, 5, [9])); | |
574 testArgumentError(() => list.replaceRange(4, 2, [9])); | |
575 } | |
576 | |
577 class Yes { | |
578 operator ==(var other) => true; | |
579 int get hashCode => 0; | |
580 } | |
581 | |
582 class MyList<E> extends ListBase<E> { | |
583 List<E> _source; | |
584 MyList(this._source); | |
585 int get length => _source.length; | |
586 void set length(int length) { | |
587 _source.length = length; | |
588 } | |
589 | |
590 E operator [](int index) => _source[index]; | |
591 void operator []=(int index, E value) { | |
592 _source[index] = value; | |
593 } | |
594 } | |
595 | |
596 class MyFixedList<E> extends ListBase<E> { | |
597 List<E> _source; | |
598 MyFixedList(this._source); | |
599 int get length => _source.length; | |
600 void set length(int length) { | |
601 throw new UnsupportedError("Fixed length!"); | |
602 } | |
603 | |
604 E operator [](int index) => _source[index]; | |
605 void operator []=(int index, E value) { | |
606 _source[index] = value; | |
607 } | |
608 } | |
609 | |
610 void testListConstructor() { | |
611 // Is fixed-length. | |
612 Expect.throws(() { | |
613 new List(0).add(4); | |
614 }); | |
615 Expect.throws(() { new List(-2); }); // Not negative. //# 01: ok | |
616 // Not null. | |
617 Expect.throws(() { | |
618 new List(null); | |
619 }); | |
620 Expect.listEquals([4], new List()..add(4)); | |
621 // Is fixed-length. | |
622 Expect.throws(() { | |
623 new List.filled(0, 42).add(4); | |
624 }); | |
625 // Not negative. | |
626 Expect.throws(() { | |
627 new List.filled(-2, 42); | |
628 }); | |
629 // Not null. | |
630 Expect.throws(() { | |
631 new List.filled(null, 42); | |
632 }); | |
633 } | |
OLD | NEW |