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 library json_map_test; | |
6 | |
7 import "package:expect/expect.dart"; | |
8 import 'dart:convert' show JSON; | |
9 import 'dart:collection' show LinkedHashMap, HashMap; | |
10 | |
11 bool useReviver = false; | |
12 Map jsonify(Map map) { | |
13 String encoded = JSON.encode(map); | |
14 return useReviver | |
15 ? JSON.decode(encoded, reviver: (key, value) => value) | |
16 : JSON.decode(encoded); | |
17 } | |
18 | |
19 List listEach(Map map) { | |
20 var result = []; | |
21 map.forEach((String key, value) { | |
22 result.add(key); | |
23 result.add(value); | |
24 }); | |
25 return result; | |
26 } | |
27 | |
28 void main() { | |
29 test(false); | |
30 test(true); | |
31 } | |
32 | |
33 void test(bool revive) { | |
34 useReviver = revive; | |
35 testEmpty(jsonify({})); | |
36 testAtoB(jsonify({'a': 'b'})); | |
37 | |
38 Map map = jsonify({}); | |
39 map['a'] = 'b'; | |
40 testAtoB(map); | |
41 | |
42 map = jsonify({}); | |
43 Expect.equals('b', map.putIfAbsent('a', () => 'b')); | |
44 testAtoB(map); | |
45 | |
46 map = jsonify({}); | |
47 map.addAll({'a': 'b'}); | |
48 testAtoB(map); | |
49 | |
50 testOrder(['a', 'b', 'c', 'd', 'e', 'f']); | |
51 | |
52 testProto(); | |
53 testToString(); | |
54 testConcurrentModifications(); | |
55 testType(); | |
56 testClear(); | |
57 | |
58 testListEntry(); | |
59 testMutation(); | |
60 } | |
61 | |
62 void testEmpty(Map map) { | |
63 for (int i = 0; i < 2; i++) { | |
64 Expect.equals(0, map.length); | |
65 Expect.isTrue(map.isEmpty); | |
66 Expect.isFalse(map.isNotEmpty); | |
67 Expect.listEquals([], map.keys.toList()); | |
68 Expect.listEquals([], map.values.toList()); | |
69 Expect.isNull(map['a']); | |
70 Expect.listEquals([], listEach(map)); | |
71 Expect.isFalse(map.containsKey('a')); | |
72 Expect.isFalse(map.containsValue('a')); | |
73 Expect.isNull(map.remove('a')); | |
74 testLookupNonExistingKeys(map); | |
75 testLookupNonExistingValues(map); | |
76 map.clear(); | |
77 } | |
78 } | |
79 | |
80 void testAtoB(Map map) { | |
81 Expect.equals(1, map.length); | |
82 Expect.isFalse(map.isEmpty); | |
83 Expect.isTrue(map.isNotEmpty); | |
84 Expect.listEquals(['a'], map.keys.toList()); | |
85 Expect.listEquals(['b'], map.values.toList()); | |
86 Expect.equals('b', map['a']); | |
87 Expect.listEquals(['a', 'b'], listEach(map)); | |
88 Expect.isTrue(map.containsKey('a')); | |
89 Expect.isFalse(map.containsKey('b')); | |
90 Expect.isTrue(map.containsValue('b')); | |
91 Expect.isFalse(map.containsValue('a')); | |
92 | |
93 testLookupNonExistingKeys(map); | |
94 testLookupNonExistingValues(map); | |
95 Expect.equals('b', map.remove('a')); | |
96 Expect.isNull(map.remove('b')); | |
97 testLookupNonExistingKeys(map); | |
98 testLookupNonExistingValues(map); | |
99 | |
100 map.clear(); | |
101 testEmpty(map); | |
102 } | |
103 | |
104 void testLookupNonExistingKeys(Map map) { | |
105 for (String key in ['__proto__', 'null', null]) { | |
106 Expect.isNull(map[key]); | |
107 Expect.isFalse(map.containsKey(key)); | |
108 } | |
109 } | |
110 | |
111 void testLookupNonExistingValues(Map map) { | |
112 for (var value in ['__proto__', 'null', null]) { | |
113 Expect.isFalse(map.containsValue(value)); | |
114 } | |
115 } | |
116 | |
117 void testOrder(List list) { | |
118 if (list.isEmpty) | |
119 return; | |
120 else | |
121 testOrder(list.skip(1).toList()); | |
122 | |
123 Map original = {}; | |
124 for (int i = 0; i < list.length; i++) { | |
125 original[list[i]] = i; | |
126 } | |
127 | |
128 Map map = jsonify(original); | |
129 Expect.equals(list.length, map.length); | |
130 Expect.listEquals(list, map.keys.toList()); | |
131 | |
132 for (int i = 0; i < 10; i++) { | |
133 map["$i"] = i; | |
134 Expect.equals(list.length + i + 1, map.length); | |
135 Expect.listEquals(list, map.keys.take(list.length).toList()); | |
136 } | |
137 } | |
138 | |
139 void testProto() { | |
140 Map map = jsonify({'__proto__': 0}); | |
141 Expect.equals(1, map.length); | |
142 Expect.isTrue(map.containsKey('__proto__')); | |
143 Expect.listEquals(['__proto__'], map.keys.toList()); | |
144 Expect.equals(0, map['__proto__']); | |
145 Expect.equals(0, map.remove('__proto__')); | |
146 testEmpty(map); | |
147 | |
148 map = jsonify({'__proto__': null}); | |
149 Expect.equals(1, map.length); | |
150 Expect.isTrue(map.containsKey('__proto__')); | |
151 Expect.listEquals(['__proto__'], map.keys.toList()); | |
152 Expect.isNull(map['__proto__']); | |
153 Expect.isNull(map.remove('__proto__')); | |
154 testEmpty(map); | |
155 } | |
156 | |
157 void testToString() { | |
158 Expect.equals("{}", jsonify({}).toString()); | |
159 Expect.equals("{a: 0}", jsonify({'a': 0}).toString()); | |
160 } | |
161 | |
162 void testConcurrentModifications() { | |
163 void testIterate(Map map, Iterable iterable, Function f) { | |
164 Iterator iterator = iterable.iterator; | |
165 f(map); | |
166 iterator.moveNext(); | |
167 } | |
168 | |
169 void testKeys(Map map, Function f) => testIterate(map, map.keys, f); | |
170 void testValues(Map map, Function f) => testIterate(map, map.values, f); | |
171 | |
172 void testForEach(Map map, Function f) { | |
173 map.forEach((key, value) { | |
174 f(map); | |
175 }); | |
176 } | |
177 | |
178 bool throwsCME(Function f) { | |
179 try { | |
180 f(); | |
181 } on ConcurrentModificationError catch (e) { | |
182 return true; | |
183 } catch (e) { | |
184 return false; | |
185 } | |
186 return false; | |
187 } | |
188 | |
189 Map map = {}; | |
190 Expect.isTrue(throwsCME(() => testKeys(jsonify(map), (map) => map['a'] = 0))); | |
191 Expect | |
192 .isTrue(throwsCME(() => testValues(jsonify(map), (map) => map['a'] = 0))); | |
193 Expect.isFalse( | |
194 throwsCME(() => testForEach(jsonify(map), (map) => map['a'] = 0))); | |
195 | |
196 Expect.isFalse(throwsCME(() => testKeys(jsonify(map), (map) => map.clear()))); | |
197 Expect | |
198 .isFalse(throwsCME(() => testValues(jsonify(map), (map) => map.clear()))); | |
199 Expect.isFalse( | |
200 throwsCME(() => testForEach(jsonify(map), (map) => map.clear()))); | |
201 | |
202 Expect.isFalse( | |
203 throwsCME(() => testKeys(jsonify(map), (map) => map.remove('a')))); | |
204 Expect.isFalse( | |
205 throwsCME(() => testValues(jsonify(map), (map) => map.remove('a')))); | |
206 Expect.isFalse( | |
207 throwsCME(() => testForEach(jsonify(map), (map) => map.remove('a')))); | |
208 | |
209 Expect.isTrue(throwsCME( | |
210 () => testKeys(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
211 Expect.isTrue(throwsCME( | |
212 () => testValues(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
213 Expect.isFalse(throwsCME( | |
214 () => testForEach(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
215 | |
216 Expect.isFalse( | |
217 throwsCME(() => testKeys(jsonify(map), (map) => map.addAll({})))); | |
218 Expect.isFalse( | |
219 throwsCME(() => testValues(jsonify(map), (map) => map.addAll({})))); | |
220 Expect.isFalse( | |
221 throwsCME(() => testForEach(jsonify(map), (map) => map.addAll({})))); | |
222 | |
223 Expect.isTrue( | |
224 throwsCME(() => testKeys(jsonify(map), (map) => map.addAll({'a': 0})))); | |
225 Expect.isTrue( | |
226 throwsCME(() => testValues(jsonify(map), (map) => map.addAll({'a': 0})))); | |
227 Expect.isFalse(throwsCME( | |
228 () => testForEach(jsonify(map), (map) => map.addAll({'a': 0})))); | |
229 | |
230 map = {'a': 1}; | |
231 Expect | |
232 .isFalse(throwsCME(() => testKeys(jsonify(map), (map) => map['a'] = 0))); | |
233 Expect.isFalse( | |
234 throwsCME(() => testValues(jsonify(map), (map) => map['a'] = 0))); | |
235 Expect.isFalse( | |
236 throwsCME(() => testForEach(jsonify(map), (map) => map['a'] = 0))); | |
237 | |
238 Expect.isTrue(throwsCME(() => testKeys(jsonify(map), (map) => map['b'] = 0))); | |
239 Expect | |
240 .isTrue(throwsCME(() => testValues(jsonify(map), (map) => map['b'] = 0))); | |
241 Expect.isTrue( | |
242 throwsCME(() => testForEach(jsonify(map), (map) => map['b'] = 0))); | |
243 | |
244 Expect.isTrue(throwsCME(() => testKeys(jsonify(map), (map) => map.clear()))); | |
245 Expect | |
246 .isTrue(throwsCME(() => testValues(jsonify(map), (map) => map.clear()))); | |
247 Expect | |
248 .isTrue(throwsCME(() => testForEach(jsonify(map), (map) => map.clear()))); | |
249 | |
250 Expect.isTrue( | |
251 throwsCME(() => testKeys(jsonify(map), (map) => map.remove('a')))); | |
252 Expect.isTrue( | |
253 throwsCME(() => testValues(jsonify(map), (map) => map.remove('a')))); | |
254 Expect.isTrue( | |
255 throwsCME(() => testForEach(jsonify(map), (map) => map.remove('a')))); | |
256 | |
257 Expect.isFalse( | |
258 throwsCME(() => testKeys(jsonify(map), (map) => map.remove('b')))); | |
259 Expect.isFalse( | |
260 throwsCME(() => testValues(jsonify(map), (map) => map.remove('b')))); | |
261 Expect.isFalse( | |
262 throwsCME(() => testForEach(jsonify(map), (map) => map.remove('b')))); | |
263 | |
264 Expect.isFalse(throwsCME( | |
265 () => testKeys(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
266 Expect.isFalse(throwsCME( | |
267 () => testValues(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
268 Expect.isFalse(throwsCME( | |
269 () => testForEach(jsonify(map), (map) => map.putIfAbsent('a', () => 0)))); | |
270 | |
271 Expect.isTrue(throwsCME( | |
272 () => testKeys(jsonify(map), (map) => map.putIfAbsent('b', () => 0)))); | |
273 Expect.isTrue(throwsCME( | |
274 () => testValues(jsonify(map), (map) => map.putIfAbsent('b', () => 0)))); | |
275 Expect.isTrue(throwsCME( | |
276 () => testForEach(jsonify(map), (map) => map.putIfAbsent('b', () => 0)))); | |
277 | |
278 Expect.isFalse( | |
279 throwsCME(() => testKeys(jsonify(map), (map) => map.addAll({})))); | |
280 Expect.isFalse( | |
281 throwsCME(() => testValues(jsonify(map), (map) => map.addAll({})))); | |
282 Expect.isFalse( | |
283 throwsCME(() => testForEach(jsonify(map), (map) => map.addAll({})))); | |
284 | |
285 Expect.isFalse( | |
286 throwsCME(() => testKeys(jsonify(map), (map) => map.addAll({'a': 0})))); | |
287 Expect.isFalse( | |
288 throwsCME(() => testValues(jsonify(map), (map) => map.addAll({'a': 0})))); | |
289 Expect.isFalse(throwsCME( | |
290 () => testForEach(jsonify(map), (map) => map.addAll({'a': 0})))); | |
291 | |
292 Expect.isTrue( | |
293 throwsCME(() => testKeys(jsonify(map), (map) => map.addAll({'b': 0})))); | |
294 Expect.isTrue( | |
295 throwsCME(() => testValues(jsonify(map), (map) => map.addAll({'b': 0})))); | |
296 Expect.isTrue(throwsCME( | |
297 () => testForEach(jsonify(map), (map) => map.addAll({'b': 0})))); | |
298 } | |
299 | |
300 void testType() { | |
301 Expect.isTrue(jsonify({}) is Map); | |
302 Expect.isTrue(jsonify({}) is Map<String, dynamic>); | |
303 Expect.isFalse(jsonify({}) is Map<int, dynamic>); | |
304 } | |
305 | |
306 void testClear() { | |
307 Map map = jsonify({'a': 0}); | |
308 map.clear(); | |
309 Expect.equals(0, map.length); | |
310 } | |
311 | |
312 void testListEntry() { | |
313 Map map = jsonify({ | |
314 'a': [ | |
315 7, | |
316 8, | |
317 {'b': 9} | |
318 ] | |
319 }); | |
320 List list = map['a']; | |
321 Expect.equals(3, list.length); | |
322 Expect.equals(7, list[0]); | |
323 Expect.equals(8, list[1]); | |
324 Expect.equals(9, list[2]['b']); | |
325 } | |
326 | |
327 void testMutation() { | |
328 Map map = jsonify({'a': 0}); | |
329 Expect.listEquals(['a', 0], listEach(map)); | |
330 map['a'] = 1; | |
331 Expect.listEquals(['a', 1], listEach(map)); | |
332 map['a']++; | |
333 Expect.listEquals(['a', 2], listEach(map)); | |
334 } | |
OLD | NEW |