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 |