OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 import 'package:matcher/matcher.dart'; | 5 import 'package:matcher/matcher.dart'; |
6 | 6 |
7 import '../backend/closed_exception.dart'; | 7 import '../backend/closed_exception.dart'; |
8 import '../backend/invoker.dart'; | 8 import '../backend/invoker.dart'; |
9 | 9 |
10 /// An exception thrown when a test assertion fails. | 10 /// An exception thrown when a test assertion fails. |
(...skipping 14 matching lines...) Expand all Loading... |
25 /// | 25 /// |
26 /// This is the main assertion function. [reason] is optional and is typically | 26 /// This is the main assertion function. [reason] is optional and is typically |
27 /// not supplied, as a reason is generated from [matcher]; if [reason] | 27 /// not supplied, as a reason is generated from [matcher]; if [reason] |
28 /// is included it is appended to the reason generated by the matcher. | 28 /// is included it is appended to the reason generated by the matcher. |
29 /// | 29 /// |
30 /// [matcher] can be a value in which case it will be wrapped in an | 30 /// [matcher] can be a value in which case it will be wrapped in an |
31 /// [equals] matcher. | 31 /// [equals] matcher. |
32 /// | 32 /// |
33 /// If the assertion fails a [TestFailure] is thrown. | 33 /// If the assertion fails a [TestFailure] is thrown. |
34 /// | 34 /// |
| 35 /// If [skip] is a String or `true`, the assertion is skipped. The arguments are |
| 36 /// still evaluated, but [actual] is not verified to match [matcher]. If |
| 37 /// [actual] is a [Future], the test won't complete until the future emits a |
| 38 /// value. |
| 39 /// |
| 40 /// If [skip] is a string, it should explain why the assertion is skipped; this |
| 41 /// reason will be printed when running the test. |
| 42 /// |
35 /// In some cases extra diagnostic info can be produced on failure (for | 43 /// In some cases extra diagnostic info can be produced on failure (for |
36 /// example, stack traces on mismatched exceptions). To enable these, | 44 /// example, stack traces on mismatched exceptions). To enable these, |
37 /// [verbose] should be specified as `true`. | 45 /// [verbose] should be specified as `true`. |
38 void expect(actual, matcher, | 46 void expect(actual, matcher, |
39 {String reason, bool verbose: false, ErrorFormatter formatter}) { | 47 {String reason, skip, bool verbose: false, ErrorFormatter formatter}) { |
40 if (Invoker.current == null) { | 48 if (Invoker.current == null) { |
41 throw new StateError("expect() may only be called within a test."); | 49 throw new StateError("expect() may only be called within a test."); |
42 } | 50 } |
43 | 51 |
44 if (Invoker.current.closed) throw new ClosedException(); | 52 if (Invoker.current.closed) throw new ClosedException(); |
45 | 53 |
| 54 if (skip != null && skip is! bool && skip is! String) { |
| 55 throw new ArgumentError.value(skip, "skip", "must be a bool or a String"); |
| 56 } |
| 57 |
46 matcher = wrapMatcher(matcher); | 58 matcher = wrapMatcher(matcher); |
| 59 if (skip != null && skip != false) { |
| 60 String message; |
| 61 if (skip is String) { |
| 62 message = "Skip expect: $skip"; |
| 63 } else if (reason != null) { |
| 64 message = "Skip expect ($reason)."; |
| 65 } else { |
| 66 var description = new StringDescription().addDescriptionOf(matcher); |
| 67 message = "Skip expect ($description)."; |
| 68 } |
| 69 |
| 70 Invoker.current.skip(message); |
| 71 return; |
| 72 } |
| 73 |
47 var matchState = {}; | 74 var matchState = {}; |
48 try { | 75 try { |
49 if (matcher.matches(actual, matchState)) return; | 76 if (matcher.matches(actual, matchState)) return; |
50 } catch (e, trace) { | 77 } catch (e, trace) { |
51 if (reason == null) { | 78 if (reason == null) { |
52 reason = '${(e is String) ? e : e.toString()} at $trace'; | 79 reason = '${(e is String) ? e : e.toString()} at $trace'; |
53 } | 80 } |
54 } | 81 } |
55 if (formatter == null) formatter = _defaultFailFormatter; | 82 if (formatter == null) formatter = _defaultFailFormatter; |
56 fail(formatter(actual, matcher, reason, matchState, verbose)); | 83 fail(formatter(actual, matcher, reason, matchState, verbose)); |
(...skipping 12 matching lines...) Expand all Loading... |
69 | 96 |
70 var mismatchDescription = new StringDescription(); | 97 var mismatchDescription = new StringDescription(); |
71 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); | 98 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); |
72 | 99 |
73 if (mismatchDescription.length > 0) { | 100 if (mismatchDescription.length > 0) { |
74 description.add(' Which: ${mismatchDescription}\n'); | 101 description.add(' Which: ${mismatchDescription}\n'); |
75 } | 102 } |
76 if (reason != null) description.add(reason).add('\n'); | 103 if (reason != null) description.add(reason).add('\n'); |
77 return description.toString(); | 104 return description.toString(); |
78 } | 105 } |
OLD | NEW |