| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import "package:expect/expect.dart"; | |
| import 'dart:collection'; | |
| import 'dart:typed_data'; | |
| class MyList extends ListBase { | |
| List list; | |
| MyList(this.list); | |
| get length => list.length; | |
| set length(val) { | |
| list.length = val; | |
| } | |
| operator [](index) => list[index]; | |
| operator []=(index, val) => list[index] = val; | |
| } | |
| Iterable id(Iterable x) => x; | |
| main() { | |
| for (dynamic iterable in [ | |
| const [1, 2, 3], | |
| [1, 2, 3], | |
| new List<int?>.filled(3, null) | |
| ..[0] = 1 | |
| ..[1] = 2 | |
| ..[2] = 3, | |
| {1: 1, 2: 2, 3: 3}.keys, | |
| {1: 1, 2: 2, 3: 3}.values, | |
| new Iterable.generate(3, (x) => x + 1), | |
| new List.generate(3, (x) => x + 1), | |
| [0, 1, 2, 3].where((x) => x > 0), | |
| [0, 1, 2].map((x) => x + 1), | |
| [ | |
| [1, 2], | |
| [3], | |
| ].expand(id), | |
| [3, 2, 1].reversed, | |
| [0, 1, 2, 3].skip(1), | |
| [1, 2, 3, 4].take(3), | |
| new Uint8List(3) | |
| ..[0] = 1 | |
| ..[1] = 2 | |
| ..[2] = 3, | |
| (new HashMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3) | |
| .keys, | |
| (new HashMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3) | |
| .values, | |
| (new SplayTreeMap() | |
| ..[1] = 0 | |
| ..[2] = 0 | |
| ..[3] = 0) | |
| .keys, | |
| (new SplayTreeMap() | |
| ..[0] = 1 | |
| ..[1] = 2 | |
| ..[2] = 3) | |
| .values, | |
| new HashSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| new LinkedHashSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| new SplayTreeSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| "\x01\x02\x03".codeUnits, | |
| "\x01\x02\x03".runes, | |
| new MyList([1, 2, 3]), | |
| ]) { | |
| int callCount = 0; | |
| var result = iterable.fold(0, (x, y) { | |
| callCount++; | |
| return x + y; | |
| }); | |
| Expect.equals(6, result, "${iterable.runtimeType}"); | |
| Expect.equals(3, callCount); | |
| } | |
| // Empty iterables are allowed. | |
| for (var iterable in [ | |
| const [], | |
| [], | |
| new List.empty(), | |
| {}.keys, | |
| {}.values, | |
| new Iterable.generate(0, (x) => x + 1), | |
| new List.generate(0, (x) => x + 1), | |
| [0, 1, 2, 3].where((x) => false), | |
| [].map((x) => x + 1), | |
| [[], []].expand(id), | |
| [].reversed, | |
| [0, 1, 2, 3].skip(4), | |
| [1, 2, 3, 4].take(0), | |
| new Uint8List(0), | |
| (new HashMap()).keys, | |
| (new HashMap()).values, | |
| (new SplayTreeMap()).keys, | |
| (new SplayTreeMap()).values, | |
| new HashSet(), | |
| new LinkedHashSet(), | |
| new SplayTreeSet(), | |
| "".codeUnits, | |
| "".runes, | |
| new MyList([]), | |
| ]) { | |
| Expect.equals(42, iterable.fold(42, (x, y) => throw "Unreachable")); | |
| } | |
| // Singleton iterables are calling reduce function. | |
| for (dynamic iterable in [ | |
| const [1], | |
| [1], | |
| new List.filled(1, 1), | |
| {1: 1}.keys, | |
| {1: 1}.values, | |
| new Iterable.generate(1, (x) => x + 1), | |
| new List.generate(1, (x) => x + 1), | |
| [0, 1, 2, 3].where((x) => x == 1), | |
| [0].map((x) => x + 1), | |
| [ | |
| [], | |
| [1], | |
| ].expand(id), | |
| [1].reversed, | |
| [0, 1].skip(1), | |
| [1, 2, 3, 4].take(1), | |
| new Uint8List(1)..[0] = 1, | |
| (new HashMap()..[1] = 0).keys, | |
| (new HashMap()..[0] = 1).values, | |
| (new SplayTreeMap()..[1] = 0).keys, | |
| (new SplayTreeMap()..[0] = 1).values, | |
| new HashSet()..add(1), | |
| new LinkedHashSet()..add(1), | |
| new SplayTreeSet()..add(1), | |
| "\x01".codeUnits, | |
| "\x01".runes, | |
| new MyList([1]), | |
| ]) { | |
| Expect.equals(43, iterable.fold(42, (x, y) => x + y)); | |
| } | |
| // Concurrent modifications not allowed. | |
| testModification(base, modify, transform) { | |
| var iterable = transform(base); | |
| Expect.throws(() { | |
| iterable.fold(0, (x, y) { | |
| modify(base); | |
| return x + y; | |
| }); | |
| }, (e) => e is ConcurrentModificationError); | |
| } | |
| void add4(collection) { | |
| collection.add(4); | |
| } | |
| void addListOf4(collection) { | |
| collection.add([4]); | |
| } | |
| void put4(map) { | |
| map[4] = 4; | |
| } | |
| testModification([1, 2, 3], add4, id); | |
| testModification( | |
| new HashSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| add4, | |
| id, | |
| ); | |
| testModification( | |
| new LinkedHashSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| add4, | |
| id, | |
| ); | |
| testModification( | |
| new SplayTreeSet() | |
| ..add(1) | |
| ..add(2) | |
| ..add(3), | |
| add4, | |
| id, | |
| ); | |
| testModification(new MyList([1, 2, 3]), add4, id); | |
| testModification([0, 1, 2, 3], add4, (x) => x.where((int x) => x > 0)); | |
| testModification([0, 1, 2], add4, (x) => x.map((x) => x + 1)); | |
| testModification( | |
| [ | |
| [1, 2], | |
| [3], | |
| ], | |
| addListOf4, | |
| (x) => x.expand((List<int> x) => x), | |
| ); | |
| testModification([3, 2, 1], add4, (x) => x.reversed); | |
| testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.keys); | |
| testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.values); | |
| var hashMap = new HashMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3; | |
| testModification(hashMap, put4, (x) => x.keys); | |
| hashMap = new HashMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3; | |
| testModification(hashMap, put4, (x) => x.values); | |
| var splayMap = new SplayTreeMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3; | |
| testModification(splayMap, put4, (x) => x.keys); | |
| splayMap = new SplayTreeMap() | |
| ..[1] = 1 | |
| ..[2] = 2 | |
| ..[3] = 3; | |
| testModification(splayMap, put4, (x) => x.values); | |
| } |