Chromium Code Reviews| 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 |