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 library matcher.expect; | 5 library matcher.expect; |
6 | 6 |
7 import 'core_matchers.dart'; | 7 import 'core_matchers.dart'; |
8 import 'description.dart'; | 8 import 'description.dart'; |
9 import 'interfaces.dart'; | 9 import 'interfaces.dart'; |
10 import 'util.dart'; | 10 import 'util.dart'; |
(...skipping 14 matching lines...) Expand all Loading... |
25 abstract class FailureHandler { | 25 abstract class FailureHandler { |
26 /// This handles failures given a textual decription | 26 /// This handles failures given a textual decription |
27 void fail(String reason); | 27 void fail(String reason); |
28 | 28 |
29 /// This handles failures given the actual [value], the [matcher] | 29 /// This handles failures given the actual [value], the [matcher] |
30 /// the [reason] (argument from [expect]), some additonal [matchState] | 30 /// the [reason] (argument from [expect]), some additonal [matchState] |
31 /// generated by the [matcher], and a verbose flag which controls in | 31 /// generated by the [matcher], and a verbose flag which controls in |
32 /// some cases how much [matchState] information is used. It will use | 32 /// some cases how much [matchState] information is used. It will use |
33 /// these to create a detailed error message (typically by calling | 33 /// these to create a detailed error message (typically by calling |
34 /// an [ErrorFormatter]) and then call [fail] with this message. | 34 /// an [ErrorFormatter]) and then call [fail] with this message. |
35 void failMatch(actual, Matcher matcher, String reason, | 35 void failMatch( |
36 Map matchState, bool verbose); | 36 actual, Matcher matcher, String reason, Map matchState, bool verbose); |
37 } | 37 } |
38 | 38 |
39 /// The ErrorFormatter type is used for functions that | 39 /// The ErrorFormatter type is used for functions that |
40 /// can be used to build up error reports upon [expect] failures. | 40 /// can be used to build up error reports upon [expect] failures. |
41 /// There is one built-in implementation ([defaultErrorFormatter]) | 41 /// There is one built-in implementation ([defaultErrorFormatter]) |
42 /// which is used by the default failure handler. If the failure handler | 42 /// which is used by the default failure handler. If the failure handler |
43 /// is replaced it may be desirable to replace the [stringDescription] | 43 /// is replaced it may be desirable to replace the [stringDescription] |
44 /// error formatter with another. | 44 /// error formatter with another. |
45 typedef String ErrorFormatter(actual, Matcher matcher, String reason, | 45 typedef String ErrorFormatter( |
46 Map matchState, bool verbose); | 46 actual, Matcher matcher, String reason, Map matchState, bool verbose); |
47 | 47 |
48 /// This Function is used by certain Matchers to catch certain exceptions. | 48 /// This Function is used by certain Matchers to catch certain exceptions. |
49 /// | 49 /// |
50 /// Some matchers, like those for Futures and exception testing, | 50 /// Some matchers, like those for Futures and exception testing, |
51 /// can fail in asynchronous sections, and throw exceptions. | 51 /// can fail in asynchronous sections, and throw exceptions. |
52 /// A user of this library will typically want to catch and handle | 52 /// A user of this library will typically want to catch and handle |
53 /// such exceptions. The [wrapAsync] property is a function that | 53 /// such exceptions. The [wrapAsync] property is a function that |
54 /// can wrap callbacks used by these Matchers so that they can be | 54 /// can wrap callbacks used by these Matchers so that they can be |
55 /// used safely. For example, the unittest library will set this | 55 /// used safely. For example, the unittest library will set this |
56 /// to be `expectAsync`. By default this is an identity function. | 56 /// to be `expectAsync`. By default this is an identity function. |
(...skipping 11 matching lines...) Expand all Loading... |
68 /// If the assertion fails, then the default behavior is to throw a | 68 /// If the assertion fails, then the default behavior is to throw a |
69 /// [TestFailure], but this behavior can be changed by calling | 69 /// [TestFailure], but this behavior can be changed by calling |
70 /// [configureExpectFailureHandler] and providing an alternative handler that | 70 /// [configureExpectFailureHandler] and providing an alternative handler that |
71 /// implements the [IFailureHandler] interface. It is also possible to | 71 /// implements the [IFailureHandler] interface. It is also possible to |
72 /// pass a [failureHandler] to [expect] as a final parameter for fine- | 72 /// pass a [failureHandler] to [expect] as a final parameter for fine- |
73 /// grained control. | 73 /// grained control. |
74 /// | 74 /// |
75 /// In some cases extra diagnostic info can be produced on failure (for | 75 /// In some cases extra diagnostic info can be produced on failure (for |
76 /// example, stack traces on mismatched exceptions). To enable these, | 76 /// example, stack traces on mismatched exceptions). To enable these, |
77 /// [verbose] should be specified as true; | 77 /// [verbose] should be specified as true; |
78 void expect(actual, matcher, {String reason, FailureHandler failureHandler, | 78 void expect(actual, matcher, |
79 bool verbose : false}) { | 79 {String reason, FailureHandler failureHandler, bool verbose: false}) { |
80 matcher = wrapMatcher(matcher); | 80 matcher = wrapMatcher(matcher); |
81 bool doesMatch; | 81 bool doesMatch; |
82 var matchState = {}; | 82 var matchState = {}; |
83 try { | 83 try { |
84 doesMatch = matcher.matches(actual, matchState); | 84 doesMatch = matcher.matches(actual, matchState); |
85 } catch (e, trace) { | 85 } catch (e, trace) { |
86 doesMatch = false; | 86 doesMatch = false; |
87 if (reason == null) { | 87 if (reason == null) { |
88 reason = '${(e is String) ? e : e.toString()} at $trace'; | 88 reason = '${(e is String) ? e : e.toString()} at $trace'; |
89 } | 89 } |
(...skipping 19 matching lines...) Expand all Loading... |
109 // The default failure handler that throws [TestFailure]s. | 109 // The default failure handler that throws [TestFailure]s. |
110 class DefaultFailureHandler implements FailureHandler { | 110 class DefaultFailureHandler implements FailureHandler { |
111 DefaultFailureHandler() { | 111 DefaultFailureHandler() { |
112 if (_assertErrorFormatter == null) { | 112 if (_assertErrorFormatter == null) { |
113 _assertErrorFormatter = _defaultErrorFormatter; | 113 _assertErrorFormatter = _defaultErrorFormatter; |
114 } | 114 } |
115 } | 115 } |
116 void fail(String reason) { | 116 void fail(String reason) { |
117 throw new TestFailure(reason); | 117 throw new TestFailure(reason); |
118 } | 118 } |
119 void failMatch(actual, Matcher matcher, String reason, | 119 void failMatch( |
120 Map matchState, bool verbose) { | 120 actual, Matcher matcher, String reason, Map matchState, bool verbose) { |
121 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose)); | 121 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose)); |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 /// Changes the default failure handler for [expect]. | 125 /// Changes the default failure handler for [expect]. |
126 /// | 126 /// |
127 /// [handler] is a reference to the new handler; if this is omitted | 127 /// [handler] is a reference to the new handler; if this is omitted |
128 /// or null then the failure handler is reset to the default, which | 128 /// or null then the failure handler is reset to the default, which |
129 /// throws [TestFailure]s on [expect] assertion failures. | 129 /// throws [TestFailure]s on [expect] assertion failures. |
130 void configureExpectFailureHandler([FailureHandler handler = null]) { | 130 void configureExpectFailureHandler([FailureHandler handler = null]) { |
131 if (handler == null) { | 131 if (handler == null) { |
132 handler = new DefaultFailureHandler(); | 132 handler = new DefaultFailureHandler(); |
133 } | 133 } |
134 _assertFailureHandler = handler; | 134 _assertFailureHandler = handler; |
135 } | 135 } |
136 | 136 |
137 FailureHandler getOrCreateExpectFailureHandler() { | 137 FailureHandler getOrCreateExpectFailureHandler() { |
138 if (_assertFailureHandler == null) { | 138 if (_assertFailureHandler == null) { |
139 configureExpectFailureHandler(); | 139 configureExpectFailureHandler(); |
140 } | 140 } |
141 return _assertFailureHandler; | 141 return _assertFailureHandler; |
142 } | 142 } |
143 | 143 |
144 // The error message formatter for failed asserts. | 144 // The error message formatter for failed asserts. |
145 ErrorFormatter _assertErrorFormatter = null; | 145 ErrorFormatter _assertErrorFormatter = null; |
146 | 146 |
147 // The default error formatter implementation. | 147 // The default error formatter implementation. |
148 String _defaultErrorFormatter(actual, Matcher matcher, String reason, | 148 String _defaultErrorFormatter( |
149 Map matchState, bool verbose) { | 149 actual, Matcher matcher, String reason, Map matchState, bool verbose) { |
150 var description = new StringDescription(); | 150 var description = new StringDescription(); |
151 description.add('Expected: ').addDescriptionOf(matcher).add('\n'); | 151 description.add('Expected: ').addDescriptionOf(matcher).add('\n'); |
152 description.add(' Actual: ').addDescriptionOf(actual).add('\n'); | 152 description.add(' Actual: ').addDescriptionOf(actual).add('\n'); |
153 | 153 |
154 var mismatchDescription = new StringDescription(); | 154 var mismatchDescription = new StringDescription(); |
155 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); | 155 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); |
156 | 156 |
157 if (mismatchDescription.length > 0) { | 157 if (mismatchDescription.length > 0) { |
158 description.add(' Which: ${mismatchDescription}\n'); | 158 description.add(' Which: ${mismatchDescription}\n'); |
159 } | 159 } |
160 if (reason != null) { | 160 if (reason != null) { |
161 description.add(reason).add('\n'); | 161 description.add(reason).add('\n'); |
162 } | 162 } |
163 return description.toString(); | 163 return description.toString(); |
164 } | 164 } |
165 | 165 |
166 /// Changes the failure message formatter for expect(). | 166 /// Changes the failure message formatter for expect(). |
167 /// | 167 /// |
168 /// [formatter] is a reference to the new formatter; if this is omitted or | 168 /// [formatter] is a reference to the new formatter; if this is omitted or |
169 /// null then the failure formatter is reset to the default. The new | 169 /// null then the failure formatter is reset to the default. The new |
170 /// formatter is returned; this allows custom expect handlers to easily | 170 /// formatter is returned; this allows custom expect handlers to easily |
171 /// get a reference to the default formatter. | 171 /// get a reference to the default formatter. |
172 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) { | 172 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) { |
173 if (formatter == null) { | 173 if (formatter == null) { |
174 formatter = _defaultErrorFormatter; | 174 formatter = _defaultErrorFormatter; |
175 } | 175 } |
176 return _assertErrorFormatter = formatter; | 176 return _assertErrorFormatter = formatter; |
177 } | 177 } |
OLD | NEW |