| 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 matcher; | 5 library matcher.expect; |
| 6 | 6 |
| 7 /** The objects thrown by the default failure handler. */ | 7 import 'core_matchers.dart'; |
| 8 import 'description.dart'; |
| 9 import 'interfaces.dart'; |
| 10 |
| 11 /// The objects thrown by the default failure handler. |
| 8 class TestFailure extends Error { | 12 class TestFailure extends Error { |
| 9 final String message; | 13 final String message; |
| 10 | 14 |
| 11 TestFailure(this.message); | 15 TestFailure(this.message); |
| 12 | 16 |
| 13 String toString() => message; | 17 String toString() => message; |
| 14 } | 18 } |
| 15 | 19 |
| 16 /** | 20 /// Useful utility for nesting match states. |
| 17 * Useful utility for nesting match states. | |
| 18 */ | |
| 19 | 21 |
| 20 void addStateInfo(Map matchState, Map values) { | 22 void addStateInfo(Map matchState, Map values) { |
| 21 var innerState = new Map.from(matchState); | 23 var innerState = new Map.from(matchState); |
| 22 matchState.clear(); | 24 matchState.clear(); |
| 23 matchState['state'] = innerState; | 25 matchState['state'] = innerState; |
| 24 matchState.addAll(values); | 26 matchState.addAll(values); |
| 25 } | 27 } |
| 26 | 28 |
| 27 /** | 29 /// Some matchers, like those for Futures and exception testing, |
| 28 * Some matchers, like those for Futures and exception testing, | 30 /// can fail in asynchronous sections, and throw exceptions. |
| 29 * can fail in asynchronous sections, and throw exceptions. | 31 /// A user of this library will typically want to catch and handle |
| 30 * A user of this library will typically want to catch and handle | 32 /// such exceptions. The [wrapAsync] property is a function that |
| 31 * such exceptions. The [wrapAsync] property is a function that | 33 /// can wrap callbacks used by these Matchers so that they can be |
| 32 * can wrap callbacks used by these Matchers so that they can be | 34 /// used safely. For example, the unittest library will set this |
| 33 * used safely. For example, the unittest library will set this | 35 /// to be `expectAsync`. By default this is an identity function. |
| 34 * to be `expectAsync`. By default this is an identity function. | |
| 35 */ | |
| 36 Function wrapAsync = (Function f, [id]) => f; | 36 Function wrapAsync = (Function f, [id]) => f; |
| 37 | 37 |
| 38 /** | 38 /// This is the main assertion function. It asserts that [actual] |
| 39 * This is the main assertion function. It asserts that [actual] | 39 /// matches the [matcher]. [reason] is optional and is typically not |
| 40 * matches the [matcher]. [reason] is optional and is typically not | 40 /// supplied, as a reason is generated from the matcher; if [reason] |
| 41 * supplied, as a reason is generated from the matcher; if [reason] | 41 /// is included it is appended to the reason generated by the matcher. |
| 42 * is included it is appended to the reason generated by the matcher. | 42 /// |
| 43 * | 43 /// [matcher] can be a value in which case it will be wrapped in an |
| 44 * [matcher] can be a value in which case it will be wrapped in an | 44 /// [equals] matcher. |
| 45 * [equals] matcher. | 45 /// |
| 46 * | 46 /// If the assertion fails, then the default behavior is to throw a |
| 47 * If the assertion fails, then the default behavior is to throw a | 47 /// [TestFailure], but this behavior can be changed by calling |
| 48 * [TestFailure], but this behavior can be changed by calling | 48 /// [configureExpectFailureHandler] and providing an alternative handler that |
| 49 * [configureExpectFailureHandler] and providing an alternative handler that | 49 /// implements the [IFailureHandler] interface. It is also possible to |
| 50 * implements the [IFailureHandler] interface. It is also possible to | 50 /// pass a [failureHandler] to [expect] as a final parameter for fine- |
| 51 * pass a [failureHandler] to [expect] as a final parameter for fine- | 51 /// grained control. |
| 52 * grained control. | 52 /// |
| 53 * | 53 /// In some cases extra diagnostic info can be produced on failure (for |
| 54 * In some cases extra diagnostic info can be produced on failure (for | 54 /// example, stack traces on mismatched exceptions). To enable these, |
| 55 * example, stack traces on mismatched exceptions). To enable these, | 55 /// [verbose] should be specified as true; |
| 56 * [verbose] should be specified as true; | |
| 57 */ | |
| 58 void expect(actual, matcher, {String reason, FailureHandler failureHandler, | 56 void expect(actual, matcher, {String reason, FailureHandler failureHandler, |
| 59 bool verbose : false}) { | 57 bool verbose : false}) { |
| 60 matcher = wrapMatcher(matcher); | 58 matcher = wrapMatcher(matcher); |
| 61 bool doesMatch; | 59 bool doesMatch; |
| 62 var matchState = {}; | 60 var matchState = {}; |
| 63 try { | 61 try { |
| 64 doesMatch = matcher.matches(actual, matchState); | 62 doesMatch = matcher.matches(actual, matchState); |
| 65 } catch (e, trace) { | 63 } catch (e, trace) { |
| 66 doesMatch = false; | 64 doesMatch = false; |
| 67 if (reason == null) { | 65 if (reason == null) { |
| 68 reason = '${(e is String) ? e : e.toString()} at $trace'; | 66 reason = '${(e is String) ? e : e.toString()} at $trace'; |
| 69 } | 67 } |
| 70 } | 68 } |
| 71 if (!doesMatch) { | 69 if (!doesMatch) { |
| 72 if (failureHandler == null) { | 70 if (failureHandler == null) { |
| 73 failureHandler = getOrCreateExpectFailureHandler(); | 71 failureHandler = getOrCreateExpectFailureHandler(); |
| 74 } | 72 } |
| 75 failureHandler.failMatch(actual, matcher, reason, matchState, verbose); | 73 failureHandler.failMatch(actual, matcher, reason, matchState, verbose); |
| 76 } | 74 } |
| 77 } | 75 } |
| 78 | 76 |
| 79 void fail(String message, {FailureHandler failureHandler}) { | 77 void fail(String message, {FailureHandler failureHandler}) { |
| 80 if (failureHandler == null) { | 78 if (failureHandler == null) { |
| 81 failureHandler = getOrCreateExpectFailureHandler(); | 79 failureHandler = getOrCreateExpectFailureHandler(); |
| 82 } | 80 } |
| 83 failureHandler.fail(message); | 81 failureHandler.fail(message); |
| 84 } | 82 } |
| 85 | 83 |
| 86 /** | 84 /// Takes an argument and returns an equivalent matcher. |
| 87 * Takes an argument and returns an equivalent matcher. | 85 /// If the argument is already a matcher this does nothing, |
| 88 * If the argument is already a matcher this does nothing, | 86 /// else if the argument is a function, it generates a predicate |
| 89 * else if the argument is a function, it generates a predicate | 87 /// function matcher, else it generates an equals matcher. |
| 90 * function matcher, else it generates an equals matcher. | |
| 91 */ | |
| 92 Matcher wrapMatcher(x) { | 88 Matcher wrapMatcher(x) { |
| 93 if (x is Matcher) { | 89 if (x is Matcher) { |
| 94 return x; | 90 return x; |
| 95 } else if (x is Function) { | 91 } else if (x is Function) { |
| 96 return predicate(x); | 92 return predicate(x); |
| 97 } else { | 93 } else { |
| 98 return equals(x); | 94 return equals(x); |
| 99 } | 95 } |
| 100 } | 96 } |
| 101 | 97 |
| 102 // The handler for failed asserts. | 98 // The handler for failed asserts. |
| 103 FailureHandler _assertFailureHandler = null; | 99 FailureHandler _assertFailureHandler = null; |
| 104 | 100 |
| 105 // The default failure handler that throws [TestFailure]s. | 101 // The default failure handler that throws [TestFailure]s. |
| 106 class DefaultFailureHandler implements FailureHandler { | 102 class DefaultFailureHandler implements FailureHandler { |
| 107 DefaultFailureHandler() { | 103 DefaultFailureHandler() { |
| 108 if (_assertErrorFormatter == null) { | 104 if (_assertErrorFormatter == null) { |
| 109 _assertErrorFormatter = _defaultErrorFormatter; | 105 _assertErrorFormatter = _defaultErrorFormatter; |
| 110 } | 106 } |
| 111 } | 107 } |
| 112 void fail(String reason) { | 108 void fail(String reason) { |
| 113 throw new TestFailure(reason); | 109 throw new TestFailure(reason); |
| 114 } | 110 } |
| 115 void failMatch(actual, Matcher matcher, String reason, | 111 void failMatch(actual, Matcher matcher, String reason, |
| 116 Map matchState, bool verbose) { | 112 Map matchState, bool verbose) { |
| 117 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose)); | 113 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose)); |
| 118 } | 114 } |
| 119 } | 115 } |
| 120 | 116 |
| 121 /** | 117 /// Changes or resets to the default the failure handler for expect() |
| 122 * Changes or resets to the default the failure handler for expect() | 118 /// [handler] is a reference to the new handler; if this is omitted |
| 123 * [handler] is a reference to the new handler; if this is omitted | 119 /// or null then the failure handler is reset to the default, which |
| 124 * or null then the failure handler is reset to the default, which | 120 /// throws [TestFailure]s on [expect] assertion failures. |
| 125 * throws [TestFailure]s on [expect] assertion failures. | |
| 126 */ | |
| 127 void configureExpectFailureHandler([FailureHandler handler = null]) { | 121 void configureExpectFailureHandler([FailureHandler handler = null]) { |
| 128 if (handler == null) { | 122 if (handler == null) { |
| 129 handler = new DefaultFailureHandler(); | 123 handler = new DefaultFailureHandler(); |
| 130 } | 124 } |
| 131 _assertFailureHandler = handler; | 125 _assertFailureHandler = handler; |
| 132 } | 126 } |
| 133 | 127 |
| 134 FailureHandler getOrCreateExpectFailureHandler() { | 128 FailureHandler getOrCreateExpectFailureHandler() { |
| 135 if (_assertFailureHandler == null) { | 129 if (_assertFailureHandler == null) { |
| 136 configureExpectFailureHandler(); | 130 configureExpectFailureHandler(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 153 | 147 |
| 154 if (mismatchDescription.length > 0) { | 148 if (mismatchDescription.length > 0) { |
| 155 description.add(' Which: ${mismatchDescription}\n'); | 149 description.add(' Which: ${mismatchDescription}\n'); |
| 156 } | 150 } |
| 157 if (reason != null) { | 151 if (reason != null) { |
| 158 description.add(reason).add('\n'); | 152 description.add(reason).add('\n'); |
| 159 } | 153 } |
| 160 return description.toString(); | 154 return description.toString(); |
| 161 } | 155 } |
| 162 | 156 |
| 163 /** | 157 /// Changes or resets to default the failure message formatter for expect(). |
| 164 * Changes or resets to default the failure message formatter for expect(). | 158 /// [formatter] is a reference to the new formatter; if this is omitted or |
| 165 * [formatter] is a reference to the new formatter; if this is omitted or | 159 /// null then the failure formatter is reset to the default. The new |
| 166 * null then the failure formatter is reset to the default. The new | 160 /// formatter is returned; this allows custom expect handlers to easily |
| 167 * formatter is returned; this allows custom expect handlers to easily | 161 /// get a reference to the default formatter. |
| 168 * get a reference to the default formatter. | |
| 169 */ | |
| 170 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) { | 162 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) { |
| 171 if (formatter == null) { | 163 if (formatter == null) { |
| 172 formatter = _defaultErrorFormatter; | 164 formatter = _defaultErrorFormatter; |
| 173 } | 165 } |
| 174 return _assertErrorFormatter = formatter; | 166 return _assertErrorFormatter = formatter; |
| 175 } | 167 } |
| 176 | |
| OLD | NEW |