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 part of unittest.matcher; | 5 part of unittest.matcher; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Returns a matcher that matches empty strings, maps or iterables | 8 * Returns a matcher that matches empty strings, maps or iterables |
| 9 * (including collections). | 9 * (including collections). |
| 10 */ | 10 */ |
| 11 const Matcher isEmpty = const _Empty(); | 11 const Matcher isEmpty = const _Empty(); |
| 12 | 12 |
| 13 class _Empty extends Matcher { | 13 class _Empty extends Matcher { |
| 14 const _Empty(); | 14 const _Empty(); |
| 15 bool matches(item, Map matchState) { | 15 bool matches(item, Map matchState) { |
| 16 if (item is Map || item is Iterable) { | 16 if (item is Map || item is Iterable) { |
| 17 return item.isEmpty; | 17 return item.isEmpty; |
| 18 } else if (item is String) { | 18 } else if (item is String) { |
| 19 return item.length == 0; | 19 return item.length == 0; |
| 20 } else { | 20 } else { |
| 21 return false; | 21 return false; |
| 22 } | 22 } |
| 23 } | 23 } |
| 24 Description describe(Description description) => | 24 Description describe(Description description) => description.add('empty'); |
| 25 description.add('empty'); | |
| 26 } | 25 } |
| 27 | 26 |
| 28 /** A matcher that matches any null value. */ | 27 /** A matcher that matches any null value. */ |
| 29 const Matcher isNull = const _IsNull(); | 28 const Matcher isNull = const _IsNull(); |
| 30 | 29 |
| 31 /** A matcher that matches any non-null value. */ | 30 /** A matcher that matches any non-null value. */ |
| 32 const Matcher isNotNull = const _IsNotNull(); | 31 const Matcher isNotNull = const _IsNotNull(); |
| 33 | 32 |
| 34 class _IsNull extends Matcher { | 33 class _IsNull extends Matcher { |
| 35 const _IsNull(); | 34 const _IsNull(); |
| 36 bool matches(item, Map matchState) => item == null; | 35 bool matches(item, Map matchState) => item == null; |
| 37 Description describe(Description description) => | 36 Description describe(Description description) => description.add('null'); |
| 38 description.add('null'); | |
| 39 } | 37 } |
| 40 | 38 |
| 41 class _IsNotNull extends Matcher { | 39 class _IsNotNull extends Matcher { |
| 42 const _IsNotNull(); | 40 const _IsNotNull(); |
| 43 bool matches(item, Map matchState) => item != null; | 41 bool matches(item, Map matchState) => item != null; |
| 44 Description describe(Description description) => | 42 Description describe(Description description) => description.add('not null'); |
| 45 description.add('not null'); | |
| 46 } | 43 } |
| 47 | 44 |
| 48 /** A matcher that matches the Boolean value true. */ | 45 /** A matcher that matches the Boolean value true. */ |
| 49 const Matcher isTrue = const _IsTrue(); | 46 const Matcher isTrue = const _IsTrue(); |
| 50 | 47 |
| 51 /** A matcher that matches anything except the Boolean value true. */ | 48 /** A matcher that matches anything except the Boolean value true. */ |
| 52 const Matcher isFalse = const _IsFalse(); | 49 const Matcher isFalse = const _IsFalse(); |
| 53 | 50 |
| 54 class _IsTrue extends Matcher { | 51 class _IsTrue extends Matcher { |
| 55 const _IsTrue(); | 52 const _IsTrue(); |
| 56 bool matches(item, Map matchState) => item == true; | 53 bool matches(item, Map matchState) => item == true; |
| 57 Description describe(Description description) => | 54 Description describe(Description description) => description.add('true'); |
| 58 description.add('true'); | |
| 59 } | 55 } |
| 60 | 56 |
| 61 class _IsFalse extends Matcher { | 57 class _IsFalse extends Matcher { |
| 62 const _IsFalse(); | 58 const _IsFalse(); |
| 63 bool matches(item, Map matchState) => item == false; | 59 bool matches(item, Map matchState) => item == false; |
| 64 Description describe(Description description) => | 60 Description describe(Description description) => description.add('false'); |
| 65 description.add('false'); | |
| 66 } | 61 } |
| 67 | 62 |
| 68 /** | 63 /** |
| 69 * Returns a matches that matches if the value is the same instance | 64 * Returns a matches that matches if the value is the same instance |
| 70 * as [expected], using [identical]. | 65 * as [expected], using [identical]. |
| 71 */ | 66 */ |
| 72 Matcher same(expected) => new _IsSameAs(expected); | 67 Matcher same(expected) => new _IsSameAs(expected); |
| 73 | 68 |
| 74 class _IsSameAs extends Matcher { | 69 class _IsSameAs extends Matcher { |
| 75 final _expected; | 70 final _expected; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 94 Matcher equals(expected, [limit=100]) => | 89 Matcher equals(expected, [limit=100]) => |
| 95 expected is String | 90 expected is String |
| 96 ? new _StringEqualsMatcher(expected) | 91 ? new _StringEqualsMatcher(expected) |
| 97 : new _DeepMatcher(expected, limit); | 92 : new _DeepMatcher(expected, limit); |
| 98 | 93 |
| 99 class _DeepMatcher extends Matcher { | 94 class _DeepMatcher extends Matcher { |
| 100 final _expected; | 95 final _expected; |
| 101 final int _limit; | 96 final int _limit; |
| 102 var count; | 97 var count; |
| 103 | 98 |
| 104 _DeepMatcher(this._expected, [limit = 1000]) : this._limit = limit; | 99 _DeepMatcher(this._expected, [limit = 1000]): this._limit = limit; |
| 105 | 100 |
| 106 // Returns a pair (reason, location) | 101 // Returns a pair (reason, location) |
| 107 List _compareIterables(expected, actual, matcher, depth, location) { | 102 List _compareIterables(expected, actual, matcher, depth, location) { |
| 108 if (actual is! Iterable) return ['is not Iterable', location]; | 103 if (actual is! Iterable) return ['is not Iterable', location]; |
| 109 | 104 |
| 110 var expectedIterator = expected.iterator; | 105 var expectedIterator = expected.iterator; |
| 111 var actualIterator = actual.iterator; | 106 var actualIterator = actual.iterator; |
| 112 for (var index = 0;; index++) { | 107 for (var index = 0; ; index++) { |
| 113 // Advance in lockstep. | 108 // Advance in lockstep. |
| 114 var expectedNext = expectedIterator.moveNext(); | 109 var expectedNext = expectedIterator.moveNext(); |
| 115 var actualNext = actualIterator.moveNext(); | 110 var actualNext = actualIterator.moveNext(); |
| 116 | 111 |
| 117 // If we reached the end of both, we succeeded. | 112 // If we reached the end of both, we succeeded. |
| 118 if (!expectedNext && !actualNext) return null; | 113 if (!expectedNext && !actualNext) return null; |
| 119 | 114 |
| 120 // Fail if their lengths are different. | 115 // Fail if their lengths are different. |
| 121 var newLocation = '${location}[${index}]'; | 116 var newLocation = '${location}[${index}]'; |
| 122 if (!expectedNext) return ['longer than expected', newLocation]; | 117 if (!expectedNext) return ['longer than expected', newLocation]; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 } | 312 } |
| 318 } | 313 } |
| 319 } | 314 } |
| 320 | 315 |
| 321 /** A matcher that matches any value. */ | 316 /** A matcher that matches any value. */ |
| 322 const Matcher anything = const _IsAnything(); | 317 const Matcher anything = const _IsAnything(); |
| 323 | 318 |
| 324 class _IsAnything extends Matcher { | 319 class _IsAnything extends Matcher { |
| 325 const _IsAnything(); | 320 const _IsAnything(); |
| 326 bool matches(item, Map matchState) => true; | 321 bool matches(item, Map matchState) => true; |
| 327 Description describe(Description description) => | 322 Description describe(Description description) => description.add('anything'); |
| 328 description.add('anything'); | |
| 329 } | 323 } |
| 330 | 324 |
| 331 /** | 325 /** |
| 332 * Returns a matcher that matches if an object is an instance | 326 * Returns a matcher that matches if an object is an instance |
| 333 * of [type] (or a subtype). | 327 * of [type] (or a subtype). |
| 334 * | 328 * |
| 335 * As types are not first class objects in Dart we can only | 329 * As types are not first class objects in Dart we can only |
| 336 * approximate this test by using a generic wrapper class. | 330 * approximate this test by using a generic wrapper class. |
| 337 * | 331 * |
| 338 * For example, to test whether 'bar' is an instance of type | 332 * For example, to test whether 'bar' is an instance of type |
| 339 * 'Foo', we would write: | 333 * 'Foo', we would write: |
| 340 * | 334 * |
| 341 * expect(bar, new isInstanceOf<Foo>()); | 335 * expect(bar, new isInstanceOf<Foo>()); |
| 342 * | 336 * |
| 343 * To get better error message, supply a name when creating the | 337 * To get better error message, supply a name when creating the |
| 344 * Type wrapper; e.g.: | 338 * Type wrapper; e.g.: |
| 345 * | 339 * |
| 346 * expect(bar, new isInstanceOf<Foo>('Foo')); | 340 * expect(bar, new isInstanceOf<Foo>('Foo')); |
| 347 * | 341 * |
| 348 * Note that this does not currently work in dart2js; it will | 342 * Note that this does not currently work in dart2js; it will |
| 349 * match any type, and isNot(new isInstanceof<T>()) will always | 343 * match any type, and isNot(new isInstanceof<T>()) will always |
| 350 * fail. This is because dart2js currently ignores template type | 344 * fail. This is because dart2js currently ignores template type |
| 351 * parameters. | 345 * parameters. |
| 352 */ | 346 */ |
| 353 class isInstanceOf<T> extends Matcher { | 347 class isInstanceOf<T> extends Matcher { |
| 354 final String _name; | 348 final String _name; |
| 355 const isInstanceOf([name = 'specified type']) : this._name = name; | 349 const isInstanceOf([name = 'specified type']): this._name = name; |
| 356 bool matches(obj, Map matchState) => obj is T; | 350 bool matches(obj, Map matchState) => obj is T; |
| 357 // The description here is lame :-( | 351 // The description here is lame :-( |
| 358 Description describe(Description description) => | 352 Description describe(Description description) => |
| 359 description.add('an instance of ${_name}'); | 353 description.add('an instance of ${_name}'); |
| 360 } | 354 } |
| 361 | 355 |
| 362 /** | 356 /** |
| 363 * This can be used to match two kinds of objects: | 357 * This can be used to match two kinds of objects: |
| 364 * | 358 * |
| 365 * * A [Function] that throws an exception when called. The function cannot | 359 * * A [Function] that throws an exception when called. The function cannot |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 * The function will be called once. Any exceptions will be silently swallowed. | 392 * The function will be called once. Any exceptions will be silently swallowed. |
| 399 * The value passed to expect() should be a reference to the function. | 393 * The value passed to expect() should be a reference to the function. |
| 400 * Note that the function cannot take arguments; to handle this | 394 * Note that the function cannot take arguments; to handle this |
| 401 * a wrapper will have to be created. | 395 * a wrapper will have to be created. |
| 402 */ | 396 */ |
| 403 const Matcher returnsNormally = const _ReturnsNormally(); | 397 const Matcher returnsNormally = const _ReturnsNormally(); |
| 404 | 398 |
| 405 class Throws extends Matcher { | 399 class Throws extends Matcher { |
| 406 final Matcher _matcher; | 400 final Matcher _matcher; |
| 407 | 401 |
| 408 const Throws([Matcher matcher]) : | 402 const Throws([Matcher matcher]): this._matcher = matcher; |
| 409 this._matcher = matcher; | |
| 410 | 403 |
| 411 bool matches(item, Map matchState) { | 404 bool matches(item, Map matchState) { |
| 412 if (item is! Function && item is! Future) return false; | 405 if (item is! Function && item is! Future) return false; |
| 413 if (item is Future) { | 406 if (item is Future) { |
| 414 var done = wrapAsync((fn) => fn()); | 407 var done = wrapAsync((fn) => fn()); |
| 415 | 408 |
| 416 // Queue up an asynchronous expectation that validates when the future | 409 // Queue up an asynchronous expectation that validates when the future |
| 417 // completes. | 410 // completes. |
| 418 item.then((value) { | 411 item.then((value) { |
| 419 done(() => fail("Expected future to fail, but succeeded with '$value'.") ); | 412 done(() => fail("Expected future to fail, but succeeded with '$value'.") ); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 * final Matcher throwsException = const _Throws(isException); | 509 * final Matcher throwsException = const _Throws(isException); |
| 517 * | 510 * |
| 518 * But currently using static functions in const expressions is not supported. | 511 * But currently using static functions in const expressions is not supported. |
| 519 * For now the only solution for all platforms seems to be separate classes | 512 * For now the only solution for all platforms seems to be separate classes |
| 520 * for each exception type. | 513 * for each exception type. |
| 521 */ | 514 */ |
| 522 | 515 |
| 523 abstract class TypeMatcher extends Matcher { | 516 abstract class TypeMatcher extends Matcher { |
| 524 final String _name; | 517 final String _name; |
| 525 const TypeMatcher(this._name); | 518 const TypeMatcher(this._name); |
| 526 Description describe(Description description) => | 519 Description describe(Description description) => description.add(_name); |
| 527 description.add(_name); | |
| 528 } | 520 } |
| 529 | 521 |
| 530 /** A matcher for FormatExceptions. */ | 522 /** A matcher for FormatExceptions. */ |
| 531 const isFormatException = const _FormatException(); | 523 const isFormatException = const _FormatException(); |
| 532 | 524 |
| 533 /** A matcher for functions that throw FormatException. */ | 525 /** A matcher for functions that throw FormatException. */ |
| 534 const Matcher throwsFormatException = | 526 const Matcher throwsFormatException = const Throws(isFormatException); |
| 535 const Throws(isFormatException); | |
| 536 | 527 |
| 537 class _FormatException extends TypeMatcher { | 528 class _FormatException extends TypeMatcher { |
| 538 const _FormatException() : super("FormatException"); | 529 const _FormatException(): super("FormatException"); |
| 539 bool matches(item, Map matchState) => item is FormatException; | 530 bool matches(item, Map matchState) => item is FormatException; |
| 540 } | 531 } |
| 541 | 532 |
| 542 /** A matcher for Exceptions. */ | 533 /** A matcher for Exceptions. */ |
| 543 const isException = const _Exception(); | 534 const isException = const _Exception(); |
| 544 | 535 |
| 545 /** A matcher for functions that throw Exception. */ | 536 /** A matcher for functions that throw Exception. */ |
| 546 const Matcher throwsException = const Throws(isException); | 537 const Matcher throwsException = const Throws(isException); |
| 547 | 538 |
| 548 class _Exception extends TypeMatcher { | 539 class _Exception extends TypeMatcher { |
| 549 const _Exception() : super("Exception"); | 540 const _Exception(): super("Exception"); |
| 550 bool matches(item, Map matchState) => item is Exception; | 541 bool matches(item, Map matchState) => item is Exception; |
| 551 } | 542 } |
| 552 | 543 |
| 553 /** A matcher for ArgumentErrors. */ | 544 /** A matcher for ArgumentErrors. */ |
| 554 const isArgumentError = const _ArgumentError(); | 545 const isArgumentError = const _ArgumentError(); |
| 555 | 546 |
| 556 /** A matcher for functions that throw ArgumentError. */ | 547 /** A matcher for functions that throw ArgumentError. */ |
| 557 const Matcher throwsArgumentError = | 548 const Matcher throwsArgumentError = const Throws(isArgumentError); |
| 558 const Throws(isArgumentError); | |
| 559 | 549 |
| 560 class _ArgumentError extends TypeMatcher { | 550 class _ArgumentError extends TypeMatcher { |
| 561 const _ArgumentError() : super("ArgumentError"); | 551 const _ArgumentError(): super("ArgumentError"); |
| 562 bool matches(item, Map matchState) => item is ArgumentError; | 552 bool matches(item, Map matchState) => item is ArgumentError; |
| 563 } | 553 } |
| 564 | 554 |
| 565 /** A matcher for RangeErrors. */ | 555 /** A matcher for RangeErrors. */ |
| 566 const isRangeError = const _RangeError(); | 556 const isRangeError = const _RangeError(); |
| 567 | 557 |
| 568 /** A matcher for functions that throw RangeError. */ | 558 /** A matcher for functions that throw RangeError. */ |
| 569 const Matcher throwsRangeError = | 559 const Matcher throwsRangeError = const Throws(isRangeError); |
| 570 const Throws(isRangeError); | |
| 571 | 560 |
| 572 class _RangeError extends TypeMatcher { | 561 class _RangeError extends TypeMatcher { |
| 573 const _RangeError() : super("RangeError"); | 562 const _RangeError(): super("RangeError"); |
| 574 bool matches(item, Map matchState) => item is RangeError; | 563 bool matches(item, Map matchState) => item is RangeError; |
| 575 } | 564 } |
| 576 | 565 |
| 577 /** A matcher for NoSuchMethodErrors. */ | 566 /** A matcher for NoSuchMethodErrors. */ |
| 578 const isNoSuchMethodError = const _NoSuchMethodError(); | 567 const isNoSuchMethodError = const _NoSuchMethodError(); |
| 579 | 568 |
| 580 /** A matcher for functions that throw NoSuchMethodError. */ | 569 /** A matcher for functions that throw NoSuchMethodError. */ |
| 581 const Matcher throwsNoSuchMethodError = | 570 const Matcher throwsNoSuchMethodError = const Throws(isNoSuchMethodError); |
| 582 const Throws(isNoSuchMethodError); | |
| 583 | 571 |
| 584 class _NoSuchMethodError extends TypeMatcher { | 572 class _NoSuchMethodError extends TypeMatcher { |
| 585 const _NoSuchMethodError() : super("NoSuchMethodError"); | 573 const _NoSuchMethodError(): super("NoSuchMethodError"); |
| 586 bool matches(item, Map matchState) => item is NoSuchMethodError; | 574 bool matches(item, Map matchState) => item is NoSuchMethodError; |
| 587 } | 575 } |
| 588 | 576 |
| 589 /** A matcher for UnimplementedErrors. */ | 577 /** A matcher for UnimplementedErrors. */ |
| 590 const isUnimplementedError = const _UnimplementedError(); | 578 const isUnimplementedError = const _UnimplementedError(); |
| 591 | 579 |
| 592 /** A matcher for functions that throw Exception. */ | 580 /** A matcher for functions that throw Exception. */ |
| 593 const Matcher throwsUnimplementedError = | 581 const Matcher throwsUnimplementedError = const Throws(isUnimplementedError); |
| 594 const Throws(isUnimplementedError); | |
| 595 | 582 |
| 596 class _UnimplementedError extends TypeMatcher { | 583 class _UnimplementedError extends TypeMatcher { |
| 597 const _UnimplementedError() : super("UnimplementedError"); | 584 const _UnimplementedError(): super("UnimplementedError"); |
| 598 bool matches(item, Map matchState) => item is UnimplementedError; | 585 bool matches(item, Map matchState) => item is UnimplementedError; |
| 599 } | 586 } |
| 600 | 587 |
| 601 /** A matcher for UnsupportedError. */ | 588 /** A matcher for UnsupportedError. */ |
| 602 const isUnsupportedError = const _UnsupportedError(); | 589 const isUnsupportedError = const _UnsupportedError(); |
| 603 | 590 |
| 604 /** A matcher for functions that throw UnsupportedError. */ | 591 /** A matcher for functions that throw UnsupportedError. */ |
| 605 const Matcher throwsUnsupportedError = const Throws(isUnsupportedError); | 592 const Matcher throwsUnsupportedError = const Throws(isUnsupportedError); |
| 606 | 593 |
| 607 class _UnsupportedError extends TypeMatcher { | 594 class _UnsupportedError extends TypeMatcher { |
| 608 const _UnsupportedError() : | 595 const _UnsupportedError(): super("UnsupportedError"); |
| 609 super("UnsupportedError"); | |
| 610 bool matches(item, Map matchState) => item is UnsupportedError; | 596 bool matches(item, Map matchState) => item is UnsupportedError; |
| 611 } | 597 } |
| 612 | 598 |
| 613 /** A matcher for StateErrors. */ | 599 /** A matcher for StateErrors. */ |
| 614 const isStateError = const _StateError(); | 600 const isStateError = const _StateError(); |
| 615 | 601 |
| 616 /** A matcher for functions that throw StateError. */ | 602 /** A matcher for functions that throw StateError. */ |
| 617 const Matcher throwsStateError = | 603 const Matcher throwsStateError = const Throws(isStateError); |
| 618 const Throws(isStateError); | |
| 619 | 604 |
| 620 class _StateError extends TypeMatcher { | 605 class _StateError extends TypeMatcher { |
| 621 const _StateError() : super("StateError"); | 606 const _StateError(): super("StateError"); |
| 622 bool matches(item, Map matchState) => item is StateError; | 607 bool matches(item, Map matchState) => item is StateError; |
| 623 } | 608 } |
| 624 | 609 |
| 625 /** A matcher for FallThroughError. */ | 610 /** A matcher for FallThroughError. */ |
| 626 const isFallThroughError = const _FallThroughError(); | 611 const isFallThroughError = const _FallThroughError(); |
| 627 | 612 |
| 628 /** A matcher for functions that throw FallThroughError. */ | 613 /** A matcher for functions that throw FallThroughError. */ |
| 629 const Matcher throwsFallThroughError = | 614 const Matcher throwsFallThroughError = const Throws(isFallThroughError); |
| 630 const Throws(isFallThroughError); | |
| 631 | 615 |
| 632 class _FallThroughError extends TypeMatcher { | 616 class _FallThroughError extends TypeMatcher { |
| 633 const _FallThroughError() : super("FallThroughError"); | 617 const _FallThroughError(): super("FallThroughError"); |
| 634 bool matches(item, Map matchState) => item is FallThroughError; | 618 bool matches(item, Map matchState) => item is FallThroughError; |
| 635 } | 619 } |
| 636 | 620 |
| 637 /** A matcher for NullThrownError. */ | 621 /** A matcher for NullThrownError. */ |
| 638 const isNullThrownError = const _NullThrownError(); | 622 const isNullThrownError = const _NullThrownError(); |
| 639 | 623 |
| 640 /** A matcher for functions that throw NullThrownError. */ | 624 /** A matcher for functions that throw NullThrownError. */ |
| 641 const Matcher throwsNullThrownError = | 625 const Matcher throwsNullThrownError = const Throws(isNullThrownError); |
| 642 const Throws(isNullThrownError); | |
| 643 | 626 |
| 644 class _NullThrownError extends TypeMatcher { | 627 class _NullThrownError extends TypeMatcher { |
| 645 const _NullThrownError() : super("NullThrownError"); | 628 const _NullThrownError(): super("NullThrownError"); |
| 646 bool matches(item, Map matchState) => item is NullThrownError; | 629 bool matches(item, Map matchState) => item is NullThrownError; |
| 647 } | 630 } |
| 648 | 631 |
| 649 /** A matcher for ConcurrentModificationError. */ | 632 /** A matcher for ConcurrentModificationError. */ |
| 650 const isConcurrentModificationError = const _ConcurrentModificationError(); | 633 const isConcurrentModificationError = const _ConcurrentModificationError(); |
| 651 | 634 |
| 652 /** A matcher for functions that throw ConcurrentModificationError. */ | 635 /** A matcher for functions that throw ConcurrentModificationError. */ |
| 653 const Matcher throwsConcurrentModificationError = | 636 const Matcher throwsConcurrentModificationError = |
| 654 const Throws(isConcurrentModificationError); | 637 const Throws(isConcurrentModificationError); |
| 655 | 638 |
| 656 class _ConcurrentModificationError extends TypeMatcher { | 639 class _ConcurrentModificationError extends TypeMatcher { |
| 657 const _ConcurrentModificationError() : super("ConcurrentModificationError"); | 640 const _ConcurrentModificationError(): super("ConcurrentModificationError"); |
| 658 bool matches(item, Map matchState) => item is ConcurrentModificationError; | 641 bool matches(item, Map matchState) => item is ConcurrentModificationError; |
| 659 } | 642 } |
| 660 | 643 |
| 661 /** A matcher for AbstractClassInstantiationError. */ | 644 /** A matcher for AbstractClassInstantiationError. */ |
| 662 const isAbstractClassInstantiationError = | 645 const isAbstractClassInstantiationError = |
| 663 const _AbstractClassInstantiationError(); | 646 const _AbstractClassInstantiationError(); |
| 664 | 647 |
| 665 /** A matcher for functions that throw AbstractClassInstantiationError. */ | 648 /** A matcher for functions that throw AbstractClassInstantiationError. */ |
| 666 const Matcher throwsAbstractClassInstantiationError = | 649 const Matcher throwsAbstractClassInstantiationError = |
| 667 const Throws(isAbstractClassInstantiationError); | 650 const Throws(isAbstractClassInstantiationError); |
| 668 | 651 |
| 669 class _AbstractClassInstantiationError extends TypeMatcher { | 652 class _AbstractClassInstantiationError extends TypeMatcher { |
| 670 const _AbstractClassInstantiationError() : | 653 const _AbstractClassInstantiationError() : |
| 671 super("AbstractClassInstantiationError"); | 654 super("AbstractClassInstantiationError"); |
| 672 bool matches(item, Map matchState) => item is AbstractClassInstantiationError; | 655 bool matches(item, Map matchState) => item is AbstractClassInstantiationError; |
| 673 } | 656 } |
| 674 | 657 |
| 675 /** A matcher for CyclicInitializationError. */ | 658 /** A matcher for CyclicInitializationError. */ |
| 676 const isCyclicInitializationError = const _CyclicInitializationError(); | 659 const isCyclicInitializationError = const _CyclicInitializationError(); |
| 677 | 660 |
| 678 /** A matcher for functions that throw CyclicInitializationError. */ | 661 /** A matcher for functions that throw CyclicInitializationError. */ |
| 679 const Matcher throwsCyclicInitializationError = | 662 const Matcher throwsCyclicInitializationError = |
| 680 const Throws(isCyclicInitializationError); | 663 const Throws(isCyclicInitializationError); |
| 681 | 664 |
| 682 class _CyclicInitializationError extends TypeMatcher { | 665 class _CyclicInitializationError extends TypeMatcher { |
| 683 const _CyclicInitializationError() : super("CyclicInitializationError"); | 666 const _CyclicInitializationError(): super("CyclicInitializationError"); |
| 684 bool matches(item, Map matchState) => item is CyclicInitializationError; | 667 bool matches(item, Map matchState) => item is CyclicInitializationError; |
| 685 } | 668 } |
| 686 | 669 |
| 687 /** A matcher for Map types. */ | 670 /** A matcher for Map types. */ |
| 688 const isMap = const _IsMap(); | 671 const isMap = const _IsMap(); |
| 689 | 672 |
| 690 class _IsMap extends TypeMatcher { | 673 class _IsMap extends TypeMatcher { |
| 691 const _IsMap() : super("Map"); | 674 const _IsMap(): super("Map"); |
| 692 bool matches(item, Map matchState) => item is Map; | 675 bool matches(item, Map matchState) => item is Map; |
| 693 } | 676 } |
| 694 | 677 |
| 695 /** A matcher for List types. */ | 678 /** A matcher for List types. */ |
| 696 const isList = const _IsList(); | 679 const isList = const _IsList(); |
| 697 | 680 |
| 698 class _IsList extends TypeMatcher { | 681 class _IsList extends TypeMatcher { |
| 699 const _IsList() : super("List"); | 682 const _IsList(): super("List"); |
| 700 bool matches(item, Map matchState) => item is List; | 683 bool matches(item, Map matchState) => item is List; |
| 701 } | 684 } |
| 702 | 685 |
| 703 /** | 686 /** |
| 704 * Returns a matcher that matches if an object has a length property | 687 * Returns a matcher that matches if an object has a length property |
| 705 * that matches [matcher]. | 688 * that matches [matcher]. |
| 706 */ | 689 */ |
| 707 Matcher hasLength(matcher) => | 690 Matcher hasLength(matcher) => new _HasLength(wrapMatcher(matcher)); |
| 708 new _HasLength(wrapMatcher(matcher)); | |
| 709 | 691 |
| 710 class _HasLength extends Matcher { | 692 class _HasLength extends Matcher { |
| 711 final Matcher _matcher; | 693 final Matcher _matcher; |
| 712 const _HasLength([Matcher matcher = null]) : this._matcher = matcher; | 694 const _HasLength([Matcher matcher = null]): this._matcher = matcher; |
|
Siggi Cherem (dart-lang)
2014/03/21 20:00:45
btw - I'm not sure I agree with this one, I filed:
kevmoo
2014/03/21 20:13:02
Good to have the bug. Being consistent is the most
| |
| 713 | 695 |
| 714 bool matches(item, Map matchState) { | 696 bool matches(item, Map matchState) { |
| 715 try { | 697 try { |
| 716 // This is harmless code that will throw if no length property | 698 // This is harmless code that will throw if no length property |
| 717 // but subtle enough that an optimizer shouldn't strip it out. | 699 // but subtle enough that an optimizer shouldn't strip it out. |
| 718 if (item.length * item.length >= 0) { | 700 if (item.length * item.length >= 0) { |
| 719 return _matcher.matches(item.length, matchState); | 701 return _matcher.matches(item.length, matchState); |
| 720 } | 702 } |
| 721 } catch (e) { | 703 } catch (e) { |
| 722 return false; | 704 return false; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 813 Description describe(Description description) => | 795 Description describe(Description description) => |
| 814 description.add('is in ').addDescriptionOf(_expected); | 796 description.add('is in ').addDescriptionOf(_expected); |
| 815 } | 797 } |
| 816 | 798 |
| 817 /** | 799 /** |
| 818 * Returns a matcher that uses an arbitrary function that returns | 800 * Returns a matcher that uses an arbitrary function that returns |
| 819 * true or false for the actual value. For example: | 801 * true or false for the actual value. For example: |
| 820 * | 802 * |
| 821 * expect(v, predicate((x) => ((x % 2) == 0), "is even")) | 803 * expect(v, predicate((x) => ((x % 2) == 0), "is even")) |
| 822 */ | 804 */ |
| 823 Matcher predicate(Function f, [description ='satisfies function']) => | 805 Matcher predicate(Function f, [description = 'satisfies function']) => |
| 824 new _Predicate(f, description); | 806 new _Predicate(f, description); |
| 825 | 807 |
| 826 class _Predicate extends Matcher { | 808 class _Predicate extends Matcher { |
| 827 | 809 |
| 828 final Function _matcher; | 810 final Function _matcher; |
| 829 final String _description; | 811 final String _description; |
| 830 | 812 |
| 831 const _Predicate(this._matcher, this._description); | 813 const _Predicate(this._matcher, this._description); |
| 832 | 814 |
| 833 bool matches(item, Map matchState) => _matcher(item); | 815 bool matches(item, Map matchState) => _matcher(item); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 884 addDescriptionOf(matchState['feature']); | 866 addDescriptionOf(matchState['feature']); |
| 885 var innerDescription = new StringDescription(); | 867 var innerDescription = new StringDescription(); |
| 886 _matcher.describeMismatch(matchState['feature'], innerDescription, | 868 _matcher.describeMismatch(matchState['feature'], innerDescription, |
| 887 matchState['state'], verbose); | 869 matchState['state'], verbose); |
| 888 if (innerDescription.length > 0) { | 870 if (innerDescription.length > 0) { |
| 889 mismatchDescription.add(' which ').add(innerDescription.toString()); | 871 mismatchDescription.add(' which ').add(innerDescription.toString()); |
| 890 } | 872 } |
| 891 return mismatchDescription; | 873 return mismatchDescription; |
| 892 } | 874 } |
| 893 } | 875 } |
| OLD | NEW |