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