OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 "package:expect/expect.dart"; | |
6 import 'dart:collection'; | |
7 import 'dart:typed_data'; | |
8 | |
9 class MyList extends ListBase { | |
10 List list; | |
11 MyList(this.list); | |
12 | |
13 get length => list.length; | |
14 set length(val) { | |
15 list.length = val; | |
16 } | |
17 | |
18 operator [](index) => list[index]; | |
19 operator []=(index, val) => list[index] = val; | |
20 } | |
21 | |
22 id(x) => x; | |
23 | |
24 main() { | |
25 // Test functionality. | |
26 for (var iterable in [ | |
27 const [1, 2, 3], | |
28 [1, 2, 3], | |
29 new List(3) | |
30 ..[0] = 1 | |
31 ..[1] = 2 | |
32 ..[2] = 3, | |
33 {1: 1, 2: 2, 3: 3}.keys, | |
34 {1: 1, 2: 2, 3: 3}.values, | |
35 new Iterable.generate(3, (x) => x + 1), | |
36 new List.generate(3, (x) => x + 1), | |
37 [0, 1, 2, 3].where((x) => x > 0), | |
38 [0, 1, 2].map((x) => x + 1), | |
39 [ | |
40 [1, 2], | |
41 [3] | |
42 ].expand(id), | |
43 [3, 2, 1].reversed, | |
44 [0, 1, 2, 3].skip(1), | |
45 [1, 2, 3, 4].take(3), | |
46 new Uint8List(3) | |
47 ..[0] = 1 | |
48 ..[1] = 2 | |
49 ..[2] = 3, | |
50 (new HashMap() | |
51 ..[1] = 1 | |
52 ..[2] = 2 | |
53 ..[3] = 3) | |
54 .keys, | |
55 (new HashMap() | |
56 ..[1] = 1 | |
57 ..[2] = 2 | |
58 ..[3] = 3) | |
59 .values, | |
60 (new SplayTreeMap() | |
61 ..[1] = 0 | |
62 ..[2] = 0 | |
63 ..[3] = 0) | |
64 .keys, | |
65 (new SplayTreeMap() | |
66 ..[0] = 1 | |
67 ..[1] = 2 | |
68 ..[2] = 3) | |
69 .values, | |
70 new HashSet()..add(1)..add(2)..add(3), | |
71 new LinkedHashSet()..add(1)..add(2)..add(3), | |
72 new SplayTreeSet()..add(1)..add(2)..add(3), | |
73 "\x01\x02\x03".codeUnits, | |
74 "\x01\x02\x03".runes, | |
75 new MyList([1, 2, 3]), | |
76 ]) { | |
77 int callCount = 0; | |
78 var result = iterable.reduce((x, y) { | |
79 callCount++; | |
80 return x + y; | |
81 }); | |
82 Expect.equals(6, result, "${iterable.runtimeType}"); | |
83 Expect.equals(2, callCount); | |
84 } | |
85 | |
86 // Empty iterables not allowed. | |
87 for (var iterable in [ | |
88 const [], | |
89 [], | |
90 new List(0), | |
91 {}.keys, | |
92 {}.values, | |
93 new Iterable.generate(0, (x) => x + 1), | |
94 new List.generate(0, (x) => x + 1), | |
95 [0, 1, 2, 3].where((x) => false), | |
96 [].map((x) => x + 1), | |
97 [[], []].expand(id), | |
98 [].reversed, | |
99 [0, 1, 2, 3].skip(4), | |
100 [1, 2, 3, 4].take(0), | |
101 new Uint8List(0), | |
102 (new HashMap()).keys, | |
103 (new HashMap()).values, | |
104 (new SplayTreeMap()).keys, | |
105 (new SplayTreeMap()).values, | |
106 new HashSet(), | |
107 new LinkedHashSet(), | |
108 new SplayTreeSet(), | |
109 "".codeUnits, | |
110 "".runes, | |
111 new MyList([]), | |
112 ]) { | |
113 Expect.throws(() { | |
114 iterable.reduce((x, y) => throw "Unreachable"); | |
115 }, (e) => e is StateError); | |
116 } | |
117 | |
118 // Singleton iterables not calling reduce function. | |
119 for (var iterable in [ | |
120 const [1], | |
121 [1], | |
122 new List(1)..[0] = 1, | |
123 {1: 1}.keys, | |
124 {1: 1}.values, | |
125 new Iterable.generate(1, (x) => x + 1), | |
126 new List.generate(1, (x) => x + 1), | |
127 [0, 1, 2, 3].where((x) => x == 1), | |
128 [0].map((x) => x + 1), | |
129 [ | |
130 [], | |
131 [1] | |
132 ].expand(id), | |
133 [1].reversed, | |
134 [0, 1].skip(1), | |
135 [1, 2, 3, 4].take(1), | |
136 new Uint8List(1)..[0] = 1, | |
137 (new HashMap()..[1] = 0).keys, | |
138 (new HashMap()..[0] = 1).values, | |
139 (new SplayTreeMap()..[1] = 0).keys, | |
140 (new SplayTreeMap()..[0] = 1).values, | |
141 new HashSet()..add(1), | |
142 new LinkedHashSet()..add(1), | |
143 new SplayTreeSet()..add(1), | |
144 "\x01".codeUnits, | |
145 "\x01".runes, | |
146 new MyList([1]), | |
147 ]) { | |
148 Expect.equals(1, iterable.reduce((x, y) => throw "Unreachable")); | |
149 } | |
150 | |
151 // Concurrent modifications not allowed. | |
152 testModification(base, modify, transform) { | |
153 var iterable = transform(base); | |
154 Expect.throws(() { | |
155 iterable.reduce((x, y) { | |
156 modify(base); | |
157 return x + y; | |
158 }); | |
159 }, (e) => e is ConcurrentModificationError); | |
160 } | |
161 | |
162 void add4(collection) { | |
163 collection.add(4); | |
164 } | |
165 | |
166 void put4(map) { | |
167 map[4] = 4; | |
168 } | |
169 | |
170 testModification([1, 2, 3], add4, id); | |
171 testModification(new HashSet()..add(1)..add(2)..add(3), add4, id); | |
172 testModification(new LinkedHashSet()..add(1)..add(2)..add(3), add4, id); | |
173 testModification(new SplayTreeSet()..add(1)..add(2)..add(3), add4, id); | |
174 testModification(new MyList([1, 2, 3]), add4, id); | |
175 | |
176 testModification([0, 1, 2, 3], add4, (x) => x.where((x) => x > 0)); | |
177 testModification([0, 1, 2], add4, (x) => x.map((x) => x + 1)); | |
178 testModification([ | |
179 [1, 2], | |
180 [3] | |
181 ], add4, (x) => x.expand((x) => x)); | |
182 testModification([3, 2, 1], add4, (x) => x.reversed); | |
183 testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.keys); | |
184 testModification({1: 1, 2: 2, 3: 3}, put4, (x) => x.values); | |
185 var hashMap = new HashMap() | |
186 ..[1] = 1 | |
187 ..[2] = 2 | |
188 ..[3] = 3; | |
189 testModification(hashMap, put4, (x) => x.keys); | |
190 hashMap = new HashMap() | |
191 ..[1] = 1 | |
192 ..[2] = 2 | |
193 ..[3] = 3; | |
194 testModification(hashMap, put4, (x) => x.values); | |
195 var splayMap = new SplayTreeMap() | |
196 ..[1] = 1 | |
197 ..[2] = 2 | |
198 ..[3] = 3; | |
199 testModification(splayMap, put4, (x) => x.keys); | |
200 splayMap = new SplayTreeMap() | |
201 ..[1] = 1 | |
202 ..[2] = 2 | |
203 ..[3] = 3; | |
204 testModification(splayMap, put4, (x) => x.values); | |
205 } | |
OLD | NEW |