Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: pkg/unittest/lib/src/expect.dart

Issue 16408019: Improved error messages from unittest. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 part of matcher;
6 6
7 /** The objects thrown by the default failure handler. */ 7 /** The objects thrown by the default failure handler. */
8 class TestFailure { 8 class TestFailure {
9 String _message; 9 String _message;
10 10
11 get message => _message; 11 get message => _message;
12 set message(String value) => _message = value; 12 set message(String value) => _message = value;
13 13
14 TestFailure(String message) : _message = message; 14 TestFailure(String message) : _message = message;
15 15
16 String toString() => _message; 16 String toString() => _message;
17 } 17 }
18 18
19 /** 19 /**
20 * Useful utility for nesting match states.
21 */
22
23 void addStateInfo(Map matchState, Map values) {
24 var innerState = new Map.from(matchState);
25 matchState.clear();
26 matchState['state'] = innerState;
27 for (var key in values.keys) {
Siggi Cherem (dart-lang) 2013/06/14 01:20:56 I believe now you can do matchState.addAll(values)
28 matchState[key] = values[key];
29 }
30 }
31
32 /**
20 * Some matchers, like those for Futures and exception testing, 33 * Some matchers, like those for Futures and exception testing,
21 * can fail in asynchronous sections, and throw exceptions. 34 * can fail in asynchronous sections, and throw exceptions.
22 * A user of this library will typically want to catch and handle 35 * A user of this library will typically want to catch and handle
23 * such exceptions. The [wrapAsync] property is a function that 36 * such exceptions. The [wrapAsync] property is a function that
24 * can wrap callbacks used by these Matchers so that they can be 37 * can wrap callbacks used by these Matchers so that they can be
25 * used safely. For example, the unittest library will set this 38 * used safely. For example, the unittest library will set this
26 * to be expectAsync1. By default this is an identity function. 39 * to be expectAsync1. By default this is an identity function.
27 */ 40 */
28 Function wrapAsync = (f, [id]) => f; 41 Function wrapAsync = (f, [id]) => f;
29 42
(...skipping 14 matching lines...) Expand all
44 * grained control. 57 * grained control.
45 * 58 *
46 * In some cases extra diagnostic info can be produced on failure (for 59 * In some cases extra diagnostic info can be produced on failure (for
47 * example, stack traces on mismatched exceptions). To enable these, 60 * example, stack traces on mismatched exceptions). To enable these,
48 * [verbose] should be specified as true; 61 * [verbose] should be specified as true;
49 */ 62 */
50 void expect(actual, matcher, {String reason, FailureHandler failureHandler, 63 void expect(actual, matcher, {String reason, FailureHandler failureHandler,
51 bool verbose : false}) { 64 bool verbose : false}) {
52 matcher = wrapMatcher(matcher); 65 matcher = wrapMatcher(matcher);
53 bool doesMatch; 66 bool doesMatch;
54 var matchState = new MatchState(); 67 var matchState = {};
55 try { 68 try {
56 doesMatch = matcher.matches(actual, matchState); 69 doesMatch = matcher.matches(actual, matchState);
57 } catch (e, trace) { 70 } catch (e, trace) {
58 doesMatch = false; 71 doesMatch = false;
59 if (reason == null) { 72 if (reason == null) {
60 reason = '${(e is String) ? e : e.toString()} at $trace'; 73 reason = '${(e is String) ? e : e.toString()} at $trace';
61 } 74 }
62 } 75 }
63 if (!doesMatch) { 76 if (!doesMatch) {
64 if (failureHandler == null) { 77 if (failureHandler == null) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 class DefaultFailureHandler implements FailureHandler { 111 class DefaultFailureHandler implements FailureHandler {
99 DefaultFailureHandler() { 112 DefaultFailureHandler() {
100 if (_assertErrorFormatter == null) { 113 if (_assertErrorFormatter == null) {
101 _assertErrorFormatter = _defaultErrorFormatter; 114 _assertErrorFormatter = _defaultErrorFormatter;
102 } 115 }
103 } 116 }
104 void fail(String reason) { 117 void fail(String reason) {
105 throw new TestFailure(reason); 118 throw new TestFailure(reason);
106 } 119 }
107 void failMatch(actual, Matcher matcher, String reason, 120 void failMatch(actual, Matcher matcher, String reason,
108 MatchState matchState, bool verbose) { 121 Map matchState, bool verbose) {
109 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose)); 122 fail(_assertErrorFormatter(actual, matcher, reason, matchState, verbose));
110 } 123 }
111 } 124 }
112 125
113 /** 126 /**
114 * Changes or resets to the default the failure handler for expect() 127 * Changes or resets to the default the failure handler for expect()
115 * [handler] is a reference to the new handler; if this is omitted 128 * [handler] is a reference to the new handler; if this is omitted
116 * or null then the failure handler is reset to the default, which 129 * or null then the failure handler is reset to the default, which
117 * throws [TestFailure]s on [expect] assertion failures. 130 * throws [TestFailure]s on [expect] assertion failures.
118 */ 131 */
119 void configureExpectFailureHandler([FailureHandler handler = null]) { 132 void configureExpectFailureHandler([FailureHandler handler = null]) {
120 if (handler == null) { 133 if (handler == null) {
121 handler = new DefaultFailureHandler(); 134 handler = new DefaultFailureHandler();
122 } 135 }
123 _assertFailureHandler = handler; 136 _assertFailureHandler = handler;
124 } 137 }
125 138
126 FailureHandler getOrCreateExpectFailureHandler() { 139 FailureHandler getOrCreateExpectFailureHandler() {
127 if (_assertFailureHandler == null) { 140 if (_assertFailureHandler == null) {
128 configureExpectFailureHandler(); 141 configureExpectFailureHandler();
129 } 142 }
130 return _assertFailureHandler; 143 return _assertFailureHandler;
131 } 144 }
132 145
133 // The error message formatter for failed asserts. 146 // The error message formatter for failed asserts.
134 ErrorFormatter _assertErrorFormatter = null; 147 ErrorFormatter _assertErrorFormatter = null;
135 148
136 // The default error formatter implementation. 149 // The default error formatter implementation.
137 String _defaultErrorFormatter(actual, Matcher matcher, String reason, 150 String _defaultErrorFormatter(actual, Matcher matcher, String reason,
138 MatchState matchState, bool verbose) { 151 Map matchState, bool verbose) {
139 var description = new StringDescription(); 152 var description = new StringDescription();
140 description.add('Expected: ').addDescriptionOf(matcher).add('\n'); 153 description.add('Expected: ').addDescriptionOf(matcher).add('\n');
154 description.add(' Actual: ').addDescriptionOf(actual);
141 155
142 var mismatchDescription = new StringDescription(); 156 var mismatchDescription = new StringDescription();
143 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose); 157 matcher.describeMismatch(actual, mismatchDescription, matchState, verbose);
144 description.add(' But: ')
145 .add(mismatchDescription.toString()).add('.\n');
146 158
147 description.add('Actual: ').addDescriptionOf(actual); 159 if (mismatchDescription.length > 0) {
160 description.add(' Which: ${mismatchDescription}\n');
161 }
148 if (reason != null) { 162 if (reason != null) {
149 description.add(reason).add('\n'); 163 description.add(reason).add('\n');
150 } 164 }
151 return description.toString(); 165 return description.toString();
152 } 166 }
153 167
154 /** 168 /**
155 * Changes or resets to default the failure message formatter for expect(). 169 * Changes or resets to default the failure message formatter for expect().
156 * [formatter] is a reference to the new formatter; if this is omitted or 170 * [formatter] is a reference to the new formatter; if this is omitted or
157 * null then the failure formatter is reset to the default. The new 171 * null then the failure formatter is reset to the default. The new
158 * formatter is returned; this allows custom expect handlers to easily 172 * formatter is returned; this allows custom expect handlers to easily
159 * get a reference to the default formatter. 173 * get a reference to the default formatter.
160 */ 174 */
161 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) { 175 ErrorFormatter configureExpectFormatter([ErrorFormatter formatter = null]) {
162 if (formatter == null) { 176 if (formatter == null) {
163 formatter = _defaultErrorFormatter; 177 formatter = _defaultErrorFormatter;
164 } 178 }
165 return _assertErrorFormatter = formatter; 179 return _assertErrorFormatter = formatter;
166 } 180 }
167 181
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698