| 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 * This library contains an Expect class with static methods that can be used | 6 * This library contains an Expect class with static methods that can be used |
| 7 * for simple unit-tests. | 7 * for simple unit-tests. |
| 8 */ | 8 */ |
| 9 library expect; | 9 library expect; |
| 10 | 10 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 | 343 |
| 344 for (final val in extraSet) { | 344 for (final val in extraSet) { |
| 345 sb.write('$val '); | 345 sb.write('$val '); |
| 346 } | 346 } |
| 347 _fail(sb.toString()); | 347 _fail(sb.toString()); |
| 348 } | 348 } |
| 349 | 349 |
| 350 /** | 350 /** |
| 351 * Checks that [expected] is equivalent to [actual]. | 351 * Checks that [expected] is equivalent to [actual]. |
| 352 * | 352 * |
| 353 * If the objects are lists or maps, recurses into them. | 353 * If the objects are iterables or maps, recurses into them. |
| 354 */ | 354 */ |
| 355 static void deepEquals(Object expected, Object actual) { | 355 static void deepEquals(Object expected, Object actual) { |
| 356 // Early exit check for equality. | 356 // Early exit check for equality. |
| 357 if (expected == actual) return; | 357 if (expected == actual) return; |
| 358 | 358 |
| 359 if (expected is List && actual is List) { | 359 if (expected is String && actual is String) { |
| 360 int n = | 360 stringEquals(expected, actual); |
| 361 (expected.length < actual.length) ? expected.length : actual.length; | 361 } else if (expected is Iterable && actual is Iterable) { |
| 362 for (int i = 0; i < n; i++) { | 362 var expectedLength = expected.length; |
| 363 deepEquals(expected[i], actual[i]); | 363 var actualLength = actual.length; |
| 364 |
| 365 var length = |
| 366 expectedLength < actualLength ? expectedLength : actualLength; |
| 367 for (var i = 0; i < length; i++) { |
| 368 deepEquals(expected.elementAt(i), actual.elementAt(i)); |
| 364 } | 369 } |
| 365 | 370 |
| 366 // We check on length at the end in order to provide better error | 371 // We check on length at the end in order to provide better error |
| 367 // messages when an unexpected item is inserted in a list. | 372 // messages when an unexpected item is inserted in a list. |
| 368 if (expected.length != actual.length) { | 373 if (expectedLength != actualLength) { |
| 374 var nextElement = |
| 375 (expectedLength > length ? expected : actual).elementAt(length); |
| 369 _fail('Expect.deepEquals(list length, ' | 376 _fail('Expect.deepEquals(list length, ' |
| 370 'expected: <${expected.length}>, actual: <${actual.length}>) ' | 377 'expected: <$expectedLength>, actual: <$actualLength>) ' |
| 371 'fails: Next element <' | 378 'fails: Next element <$nextElement>'); |
| 372 '${expected.length > n ? expected[n] : actual[n]}>'); | |
| 373 } | 379 } |
| 374 } else if (expected is Map && actual is Map) { | 380 } else if (expected is Map && actual is Map) { |
| 375 // Make sure all of the values are present in both and match. | 381 // Make sure all of the values are present in both and match. |
| 376 for (final key in expected.keys) { | 382 for (final key in expected.keys) { |
| 377 if (!actual.containsKey(key)) { | 383 if (!actual.containsKey(key)) { |
| 378 _fail('Expect.deepEquals(missing expected key: <$key>) fails'); | 384 _fail('Expect.deepEquals(missing expected key: <$key>) fails'); |
| 379 } | 385 } |
| 380 | 386 |
| 381 Expect.deepEquals(expected[key], actual[key]); | 387 Expect.deepEquals(expected[key], actual[key]); |
| 382 } | 388 } |
| 383 | 389 |
| 384 // Make sure the actual map doesn't have any extra keys. | 390 // Make sure the actual map doesn't have any extra keys. |
| 385 for (final key in actual.keys) { | 391 for (final key in actual.keys) { |
| 386 if (!expected.containsKey(key)) { | 392 if (!expected.containsKey(key)) { |
| 387 _fail('Expect.deepEquals(unexpected key: <$key>) fails'); | 393 _fail('Expect.deepEquals(unexpected key: <$key>) fails'); |
| 388 } | 394 } |
| 389 } | 395 } |
| 390 } else if (expected is String && actual is String) { | |
| 391 String stringDifference = _stringDifference(expected, actual); | |
| 392 // If we get here, they should not be equal. | |
| 393 assert(stringDifference != null); | |
| 394 _fail("Expect.deepEquals($stringDifference) fails."); | |
| 395 } else { | 396 } else { |
| 396 _fail("Expect.deepEquals(expected: <$expected>, actual: <$actual>) " | 397 _fail("Expect.deepEquals(expected: <$expected>, actual: <$actual>) " |
| 397 "fails."); | 398 "fails."); |
| 398 } | 399 } |
| 399 } | 400 } |
| 400 | 401 |
| 401 /** | 402 /** |
| 402 * Calls the function [f] and verifies that it throws an exception. | 403 * Calls the function [f] and verifies that it throws an exception. |
| 403 * The optional [check] function can provide additional validation | 404 * The optional [check] function can provide additional validation |
| 404 * that the correct exception is being thrown. For example, to check | 405 * that the correct exception is being thrown. For example, to check |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 const TrustTypeAnnotations(); | 467 const TrustTypeAnnotations(); |
| 467 } | 468 } |
| 468 | 469 |
| 469 /// Annotation class for testing of dart2js. Use this as metadata on method | 470 /// Annotation class for testing of dart2js. Use this as metadata on method |
| 470 /// declarations to disable closed world assumptions on parameters, effectively | 471 /// declarations to disable closed world assumptions on parameters, effectively |
| 471 /// assuming that the runtime arguments could be any value. Note that the | 472 /// assuming that the runtime arguments could be any value. Note that the |
| 472 /// constraints due to [TrustTypeAnnotations] still apply. | 473 /// constraints due to [TrustTypeAnnotations] still apply. |
| 473 class AssumeDynamic { | 474 class AssumeDynamic { |
| 474 const AssumeDynamic(); | 475 const AssumeDynamic(); |
| 475 } | 476 } |
| OLD | NEW |