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