OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Tests for the toString methods on collections and maps. | 6 * Tests for the toString methods on collections and maps. |
7 */ | 7 */ |
8 | 8 |
9 library collection_to_string; | 9 library collection_to_string; |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 * Generate a bunch of random collections (including Maps), and test that | 74 * Generate a bunch of random collections (including Maps), and test that |
75 * there string form is as expected. The collections include collections | 75 * there string form is as expected. The collections include collections |
76 * as elements, keys, and values, and include recursive references. | 76 * as elements, keys, and values, and include recursive references. |
77 * | 77 * |
78 * This test restricts itself to collections with well-defined iteration | 78 * This test restricts itself to collections with well-defined iteration |
79 * orders (i.e., no HashSet, HashMap). | 79 * orders (i.e., no HashSet, HashMap). |
80 */ | 80 */ |
81 void exactTest() { | 81 void exactTest() { |
82 for (int i = 0; i < NUM_TESTS; i++) { | 82 for (int i = 0; i < NUM_TESTS; i++) { |
83 // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes | 83 // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes |
84 int size = Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toIn t(); | 84 int size = |
85 Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toInt(); | |
85 | 86 |
86 StringBuffer stringRep = new StringBuffer(); | 87 StringBuffer stringRep = new StringBuffer(); |
87 Object o = randomCollection(size, stringRep, exact:true); | 88 Object o = randomCollection(size, stringRep, exact:true); |
89 print(stringRep); | |
90 print(o); | |
88 Expect.equals(o.toString(), stringRep.toString()); | 91 Expect.equals(o.toString(), stringRep.toString()); |
89 } | 92 } |
90 } | 93 } |
91 | 94 |
92 /** | 95 /** |
93 * Generate a bunch of random collections (including Maps), and test that | 96 * Generate a bunch of random collections (including Maps), and test that |
94 * there string form is as expected. The collections include collections | 97 * there string form is as expected. The collections include collections |
95 * as elements, keys, and values, and include recursive references. | 98 * as elements, keys, and values, and include recursive references. |
96 * | 99 * |
97 * This test includes collections with ill-defined iteration orders (i.e., | 100 * This test includes collections with ill-defined iteration orders (i.e., |
98 * HashSet, HashMap). As a consequence, it can't use equality tests on the | 101 * HashSet, HashMap). As a consequence, it can't use equality tests on the |
99 * string form. Instead, it performs equality tests on their "alphagrams." | 102 * string form. Instead, it performs equality tests on their "alphagrams." |
100 * This might allow false positives, but it does give a fair amount of | 103 * This might allow false positives, but it does give a fair amount of |
101 * confidence. | 104 * confidence. |
102 */ | 105 */ |
103 void inexactTest() { | 106 void inexactTest() { |
104 for (int i = 0; i < NUM_TESTS; i++) { | 107 for (int i = 0; i < NUM_TESTS; i++) { |
105 // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes | 108 // Choose a size from 0 to MAX_COLLECTION_SIZE, favoring larger sizes |
106 int size = Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toIn t(); | 109 int size = |
110 Math.sqrt(random(MAX_COLLECTION_SIZE * MAX_COLLECTION_SIZE)).toInt(); | |
107 | 111 |
108 StringBuffer stringRep = new StringBuffer(); | 112 StringBuffer stringRep = new StringBuffer(); |
109 Object o = randomCollection(size, stringRep, exact:false); | 113 Object o = randomCollection(size, stringRep, exact:false); |
114 print(stringRep); | |
115 print(o); | |
110 Expect.equals(alphagram(o.toString()), alphagram(stringRep.toString())); | 116 Expect.equals(alphagram(o.toString()), alphagram(stringRep.toString())); |
111 } | 117 } |
112 } | 118 } |
113 | 119 |
114 /** | 120 /** |
115 * Return a random collection (or Map) of the specified size, placing its | 121 * Return a random collection (or Map) of the specified size, placing its |
116 * string representation into the given string buffer. | 122 * string representation into the given string buffer. |
117 * | 123 * |
118 * If exact is true, the returned collections will not be, and will not contain | 124 * If exact is true, the returned collections will not be, and will not contain |
119 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap). | 125 * a collection with ill-defined iteration order (i.e., a HashSet or HashMap). |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 * a list of collections currently under construction, i.e., candidates for | 209 * a list of collections currently under construction, i.e., candidates for |
204 * recursive references. | 210 * recursive references. |
205 * | 211 * |
206 * If exact is true, the elements of the returned collections will not be, | 212 * If exact is true, the elements of the returned collections will not be, |
207 * and will not contain a collection with ill-defined iteration order | 213 * and will not contain a collection with ill-defined iteration order |
208 * (i.e., a HashSet or HashMap). | 214 * (i.e., a HashSet or HashMap). |
209 */ | 215 */ |
210 populateRandomCollection(int size, bool exact, | 216 populateRandomCollection(int size, bool exact, |
211 StringBuffer stringRep, List beingMade, var coll) { | 217 StringBuffer stringRep, List beingMade, var coll) { |
212 beingMade.add(coll); | 218 beingMade.add(coll); |
213 stringRep.write(coll is List ? '[' : '{'); | 219 String delimiters = "()"; // Default for iterables. |
220 if (coll is List) { | |
221 delimiters = "[]"; | |
222 } else if (coll is Set) { | |
223 delimiters = "{}"; | |
224 } | |
225 int start = stringRep.length; | |
214 | 226 |
227 stringRep.write(delimiters[0]); | |
228 | |
229 List indices = []; | |
215 for (int i = 0; i < size; i++) { | 230 for (int i = 0; i < size; i++) { |
231 indices.add(stringRep.length); | |
216 if (i != 0) stringRep.write(', '); | 232 if (i != 0) stringRep.write(', '); |
217 coll.add(randomElement(random(size), exact, stringRep, beingMade)); | 233 coll.add(randomElement(random(size), exact, stringRep, beingMade)); |
218 } | 234 } |
235 if (size > 5 && delimiters == "()") { | |
236 const int MAX_LENGTH = 80; | |
237 const int MIN_COUNT = 3; | |
238 const int MAX_COUNT = 100; | |
239 print("CHECKING OMISSIONS"); | |
floitsch
2013/10/11 09:29:43
debug print.
Lasse Reichstein Nielsen
2013/10/11 20:25:37
Done.
| |
240 // It's an iterable, it may omit some elements. | |
241 int end = stringRep.length; | |
242 if (size > MAX_COUNT) { | |
243 print("$size>100"); | |
floitsch
2013/10/11 09:29:43
debug print.
Lasse Reichstein Nielsen
2013/10/11 20:25:37
Done.
| |
244 // Last two elements are also omitted, just find the first three or | |
245 // first 60 characters. | |
246 for (int i = MIN_COUNT; i < size; i++) { | |
247 int startIndex = indices[i]; | |
248 if (startIndex - start > MAX_LENGTH - 6) { // Limit - ", ...)".length. | |
249 String prefix = stringRep.toString().substring(0, startIndex); | |
250 stringRep.clear(); | |
251 stringRep.add(prefix); | |
252 stringRep.add(", ..."); | |
253 } | |
254 } | |
255 } else if (stringRep.length - start > MAX_LENGTH - 1) { // 80 - ")".length. | |
256 print("$size<=100: $indices"); | |
floitsch
2013/10/11 09:29:43
ditto
Lasse Reichstein Nielsen
2013/10/11 20:25:37
Done.
| |
257 // Last two elements are always included. Middle ones may be omitted. | |
258 int lastTwoLength = end - indices[indices.length - 2]; | |
259 // Try to find first element to omit. | |
260 for (int i = 3; i <= size - 3; i++) { | |
261 int elementEnd = indices[i + 1]; | |
262 int lengthAfter = elementEnd - start; | |
263 int ellipsisSize = 5; // ", ...".length | |
264 if (i == size - 3) ellipsisSize = 0; // No ellipsis if we hit the end. | |
265 if (lengthAfter + ellipsisSize + lastTwoLength > MAX_LENGTH - 1) { | |
266 // Omit this element and everything up to the last two. | |
267 int elementStart = indices[i]; | |
268 // Rewrite string buffer by copying it out, clearing, and putting | |
269 // the parts back in. | |
270 String buffer = stringRep.toString(); | |
271 String prefix = buffer.substring(0, elementStart); | |
272 String suffix = buffer.substring(end - lastTwoLength, end); | |
273 stringRep.clear(); | |
274 stringRep.write(prefix); | |
275 stringRep.write(", ..."); | |
276 stringRep.write(suffix); | |
277 break; | |
278 } | |
279 } | |
280 } | |
281 } | |
219 | 282 |
220 stringRep.write(coll is List ? ']' : '}'); | 283 stringRep.write(delimiters[1]); |
221 beingMade.removeLast(); | 284 beingMade.removeLast(); |
222 return coll; | 285 return coll; |
223 } | 286 } |
224 | 287 |
225 /** Like populateRandomCollection, but for sets (elements must be hashable) */ | 288 /** Like populateRandomCollection, but for sets (elements must be hashable) */ |
226 Set populateRandomSet(int size, bool exact, StringBuffer stringRep, | 289 Set populateRandomSet(int size, bool exact, StringBuffer stringRep, |
227 List beingMade, Set set) { | 290 List beingMade, Set set) { |
228 stringRep.write('{'); | 291 stringRep.write('{'); |
229 | 292 |
230 for (int i = 0; i < size; i++) { | 293 for (int i = 0; i < size; i++) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
273 double elementTypeFrac = rand.nextDouble(); | 336 double elementTypeFrac = rand.nextDouble(); |
274 if (elementTypeFrac < 1/3) { | 337 if (elementTypeFrac < 1/3) { |
275 result = random(1000); | 338 result = random(1000); |
276 stringRep.write(result); | 339 stringRep.write(result); |
277 } else if (elementTypeFrac < 2/3) { | 340 } else if (elementTypeFrac < 2/3) { |
278 // Element Is a random (new) collection | 341 // Element Is a random (new) collection |
279 result = randomCollectionHelper(size, exact, stringRep, beingMade); | 342 result = randomCollectionHelper(size, exact, stringRep, beingMade); |
280 } else { | 343 } else { |
281 // Element Is a random recursive ref | 344 // Element Is a random recursive ref |
282 result = beingMade[random(beingMade.length)]; | 345 result = beingMade[random(beingMade.length)]; |
283 if (result is List) | 346 if (result is List) { |
284 stringRep.write('[...]'); | 347 stringRep.write('[...]'); |
285 else | 348 } else if (result is Set || result is Map) { |
286 stringRep.write('{...}'); | 349 stringRep.write('{...}'); |
350 } else { | |
351 stringRep.write('(...)'); | |
352 } | |
287 } | 353 } |
288 return result; | 354 return result; |
289 } | 355 } |
290 | 356 |
291 /** Returns a random int on [0, max) */ | 357 /** Returns a random int on [0, max) */ |
292 int random(int max) { | 358 int random(int max) { |
293 return rand.nextInt(max); | 359 return rand.nextInt(max); |
294 } | 360 } |
295 | 361 |
296 /** Returns a random boolean value. */ | 362 /** Returns a random boolean value. */ |
297 bool randomBool() { | 363 bool randomBool() { |
298 return rand.nextBool(); | 364 return rand.nextBool(); |
299 } | 365 } |
300 | 366 |
301 /** Returns the alphabetized characters in a string. */ | 367 /** Returns the alphabetized characters in a string. */ |
302 String alphagram(String s) { | 368 String alphagram(String s) { |
303 // Calling [toList] to convert unmodifiable list to normal list. | 369 // Calling [toList] to convert unmodifiable list to normal list. |
304 List<int> chars = s.codeUnits.toList(); | 370 List<int> chars = s.codeUnits.toList(); |
305 chars.sort((int a, int b) => a - b); | 371 chars.sort((int a, int b) => a - b); |
306 return new String.fromCharCodes(chars); | 372 return new String.fromCharCodes(chars); |
307 } | 373 } |
OLD | NEW |