blob: 2e746440403c50ab5b5465725d210a229d16a321 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.test;
18
19import com.google.android.collect.Lists;
20import junit.framework.Assert;
21
22import java.util.Arrays;
23import java.util.HashMap;
24import java.util.HashSet;
25import java.util.Map;
26import java.util.Set;
27import java.util.regex.MatchResult;
28import java.util.regex.Matcher;
29import java.util.regex.Pattern;
30
31/**
32 * Contains additional assertion methods not found in JUnit.
33 */
34public final class MoreAsserts {
35
36 private MoreAsserts() { }
37
38 /**
39 * Asserts that the class {@code expected} is assignable from the object
40 * {@code actual}. This verifies {@code expected} is a parent class or a
41 * interface that {@code actual} implements.
42 */
43 public static void assertAssignableFrom(Class<?> expected, Object actual) {
44 assertAssignableFrom(expected, actual.getClass());
45 }
46
47 /**
48 * Asserts that class {@code expected} is assignable from the class
49 * {@code actual}. This verifies {@code expected} is a parent class or a
50 * interface that {@code actual} implements.
51 */
52 public static void assertAssignableFrom(Class<?> expected, Class<?> actual) {
53 Assert.assertTrue(
54 "Expected " + expected.getCanonicalName() +
55 " to be assignable from actual class " + actual.getCanonicalName(),
56 expected.isAssignableFrom(actual));
57 }
58
59 /**
60 * Asserts that {@code actual} is not equal {@code unexpected}, according
61 * to both {@code ==} and {@link Object#equals}.
62 */
63 public static void assertNotEqual(
64 String message, Object unexpected, Object actual) {
65 if (equal(unexpected, actual)) {
66 failEqual(message, unexpected);
67 }
68 }
69
70 /**
71 * Variant of {@link #assertNotEqual(String,Object,Object)} using a
72 * generic message.
73 */
74 public static void assertNotEqual(Object unexpected, Object actual) {
75 assertNotEqual(null, unexpected, actual);
76 }
77
78 /**
79 * Asserts that array {@code actual} is the same size and every element equals
80 * those in array {@code expected}. On failure, message indicates specific
81 * element mismatch.
82 */
83 public static void assertEquals(
84 String message, byte[] expected, byte[] actual) {
85 if (expected.length != actual.length) {
86 failWrongLength(message, expected.length, actual.length);
87 }
88 for (int i = 0; i < expected.length; i++) {
89 if (expected[i] != actual[i]) {
90 failWrongElement(message, i, expected[i], actual[i]);
91 }
92 }
93 }
94
95 /**
96 * Asserts that array {@code actual} is the same size and every element equals
97 * those in array {@code expected}. On failure, message indicates specific
98 * element mismatch.
99 */
100 public static void assertEquals(byte[] expected, byte[] actual) {
101 assertEquals(null, expected, actual);
102 }
103
104 /**
105 * Asserts that array {@code actual} is the same size and every element equals
106 * those in array {@code expected}. On failure, message indicates first
107 * specific element mismatch.
108 */
109 public static void assertEquals(
110 String message, int[] expected, int[] actual) {
111 if (expected.length != actual.length) {
112 failWrongLength(message, expected.length, actual.length);
113 }
114 for (int i = 0; i < expected.length; i++) {
115 if (expected[i] != actual[i]) {
116 failWrongElement(message, i, expected[i], actual[i]);
117 }
118 }
119 }
120
121 /**
122 * Asserts that array {@code actual} is the same size and every element equals
123 * those in array {@code expected}. On failure, message indicates first
124 * specific element mismatch.
125 */
126 public static void assertEquals(int[] expected, int[] actual) {
127 assertEquals(null, expected, actual);
128 }
129
130 /**
131 * Asserts that array {@code actual} is the same size and every element equals
132 * those in array {@code expected}. On failure, message indicates first
133 * specific element mismatch.
134 */
135 public static void assertEquals(
136 String message, double[] expected, double[] actual) {
137 if (expected.length != actual.length) {
138 failWrongLength(message, expected.length, actual.length);
139 }
140 for (int i = 0; i < expected.length; i++) {
141 if (expected[i] != actual[i]) {
142 failWrongElement(message, i, expected[i], actual[i]);
143 }
144 }
145 }
146
147 /**
148 * Asserts that array {@code actual} is the same size and every element equals
149 * those in array {@code expected}. On failure, message indicates first
150 * specific element mismatch.
151 */
152 public static void assertEquals(double[] expected, double[] actual) {
153 assertEquals(null, expected, actual);
154 }
155
156 /**
157 * Asserts that array {@code actual} is the same size and every element
158 * is the same as those in array {@code expected}. Note that this uses
159 * {@code equals()} instead of {@code ==} to compare the objects.
160 * {@code null} will be considered equal to {code null} (unlike SQL).
161 * On failure, message indicates first specific element mismatch.
162 */
163 public static void assertEquals(
164 String message, Object[] expected, Object[] actual) {
165 if (expected.length != actual.length) {
166 failWrongLength(message, expected.length, actual.length);
167 }
168 for (int i = 0; i < expected.length; i++) {
169 Object exp = expected[i];
170 Object act = actual[i];
171 // The following borrowed from java.util.equals(Object[], Object[]).
172 if (!((exp==null) ? act==null : exp.equals(act))) {
173 failWrongElement(message, i, exp, act);
174 }
175 }
176 }
177
178 /**
179 * Asserts that array {@code actual} is the same size and every element
180 * is the same as those in array {@code expected}. Note that this uses
181 * {@code ==} instead of {@code equals()} to compare the objects.
182 * On failure, message indicates first specific element mismatch.
183 */
184 public static void assertEquals(Object[] expected, Object[] actual) {
185 assertEquals(null, expected, actual);
186 }
187
188 /** Asserts that two sets contain the same elements. */
189 public static void assertEquals(
190 String message, Set<? extends Object> expected, Set<? extends Object> actual) {
191 Set<Object> onlyInExpected = new HashSet<Object>(expected);
192 onlyInExpected.removeAll(actual);
193 Set<Object> onlyInActual = new HashSet<Object>(actual);
194 onlyInActual.removeAll(expected);
195 if (onlyInExpected.size() != 0 || onlyInActual.size() != 0) {
196 Set<Object> intersection = new HashSet<Object>(expected);
197 intersection.retainAll(actual);
198 failWithMessage(
199 message,
200 "Sets do not match.\nOnly in expected: " + onlyInExpected
201 + "\nOnly in actual: " + onlyInActual
202 + "\nIntersection: " + intersection);
203 }
204 }
205
206 /** Asserts that two sets contain the same elements. */
207 public static void assertEquals(Set<? extends Object> expected, Set<? extends Object> actual) {
208 assertEquals(null, expected, actual);
209 }
210
211 /**
212 * Asserts that {@code expectedRegex} exactly matches {@code actual} and
213 * fails with {@code message} if it does not. The MatchResult is returned
214 * in case the test needs access to any captured groups. Note that you can
215 * also use this for a literal string, by wrapping your expected string in
216 * {@link Pattern#quote}.
217 */
218 public static MatchResult assertMatchesRegex(
219 String message, String expectedRegex, String actual) {
220 if (actual == null) {
221 failNotMatches(message, expectedRegex, actual);
222 }
223 Matcher matcher = getMatcher(expectedRegex, actual);
224 if (!matcher.matches()) {
225 failNotMatches(message, expectedRegex, actual);
226 }
227 return matcher;
228 }
229
230 /**
231 * Variant of {@link #assertMatchesRegex(String,String,String)} using a
232 * generic message.
233 */
234 public static MatchResult assertMatchesRegex(
235 String expectedRegex, String actual) {
236 return assertMatchesRegex(null, expectedRegex, actual);
237 }
238
239 /**
240 * Asserts that {@code expectedRegex} matches any substring of {@code actual}
241 * and fails with {@code message} if it does not. The Matcher is returned in
242 * case the test needs access to any captured groups. Note that you can also
243 * use this for a literal string, by wrapping your expected string in
244 * {@link Pattern#quote}.
245 */
246 public static MatchResult assertContainsRegex(
247 String message, String expectedRegex, String actual) {
248 if (actual == null) {
249 failNotContains(message, expectedRegex, actual);
250 }
251 Matcher matcher = getMatcher(expectedRegex, actual);
252 if (!matcher.find()) {
253 failNotContains(message, expectedRegex, actual);
254 }
255 return matcher;
256 }
257
258 /**
259 * Variant of {@link #assertContainsRegex(String,String,String)} using a
260 * generic message.
261 */
262 public static MatchResult assertContainsRegex(
263 String expectedRegex, String actual) {
264 return assertContainsRegex(null, expectedRegex, actual);
265 }
266
267 /**
268 * Asserts that {@code expectedRegex} does not exactly match {@code actual},
269 * and fails with {@code message} if it does. Note that you can also use
270 * this for a literal string, by wrapping your expected string in
271 * {@link Pattern#quote}.
272 */
273 public static void assertNotMatchesRegex(
274 String message, String expectedRegex, String actual) {
275 Matcher matcher = getMatcher(expectedRegex, actual);
276 if (matcher.matches()) {
277 failMatch(message, expectedRegex, actual);
278 }
279 }
280
281 /**
282 * Variant of {@link #assertNotMatchesRegex(String,String,String)} using a
283 * generic message.
284 */
285 public static void assertNotMatchesRegex(
286 String expectedRegex, String actual) {
287 assertNotMatchesRegex(null, expectedRegex, actual);
288 }
289
290 /**
291 * Asserts that {@code expectedRegex} does not match any substring of
292 * {@code actual}, and fails with {@code message} if it does. Note that you
293 * can also use this for a literal string, by wrapping your expected string
294 * in {@link Pattern#quote}.
295 */
296 public static void assertNotContainsRegex(
297 String message, String expectedRegex, String actual) {
298 Matcher matcher = getMatcher(expectedRegex, actual);
299 if (matcher.find()) {
300 failContains(message, expectedRegex, actual);
301 }
302 }
303
304 /**
305 * Variant of {@link #assertNotContainsRegex(String,String,String)} using a
306 * generic message.
307 */
308 public static void assertNotContainsRegex(
309 String expectedRegex, String actual) {
310 assertNotContainsRegex(null, expectedRegex, actual);
311 }
312
313 /**
314 * Asserts that {@code actual} contains precisely the elements
315 * {@code expected}, and in the same order.
316 */
317 public static void assertContentsInOrder(
318 String message, Iterable<?> actual, Object... expected) {
319 Assert.assertEquals(message,
320 Arrays.asList(expected), Lists.newArrayList(actual));
321 }
322
323 /**
324 * Variant of assertContentsInOrder(String, Iterable<?>, Object...)
325 * using a generic message.
326 */
327 public static void assertContentsInOrder(
328 Iterable<?> actual, Object... expected) {
329 assertContentsInOrder((String) null, actual, expected);
330 }
331
332 /**
333 * Asserts that {@code actual} contains precisely the elements
334 * {@code expected}, but in any order.
335 */
336 public static void assertContentsInAnyOrder(String message, Iterable<?> actual,
337 Object... expected) {
338 HashMap<Object, Object> expectedMap = new HashMap<Object, Object>(expected.length);
339 for (Object expectedObj : expected) {
340 expectedMap.put(expectedObj, expectedObj);
341 }
342
343 for (Object actualObj : actual) {
344 if (expectedMap.remove(actualObj) == null) {
345 failWithMessage(message, "Extra object in actual: (" + actualObj.toString() + ")");
346 }
347 }
348
349 if (expectedMap.size() > 0) {
350 failWithMessage(message, "Extra objects in expected.");
351 }
352 }
353
354 /**
355 * Variant of assertContentsInAnyOrder(String, Iterable<?>, Object...)
356 * using a generic message.
357 */
358 public static void assertContentsInAnyOrder(Iterable<?> actual, Object... expected) {
359 assertContentsInAnyOrder((String)null, actual, expected);
360 }
361
362 /**
363 * Asserts that {@code iterable} is empty.
364 */
365 public static void assertEmpty(String message, Iterable<?> iterable) {
366 if (iterable.iterator().hasNext()) {
367 failNotEmpty(message, iterable.toString());
368 }
369 }
370
371 /**
372 * Variant of {@link #assertEmpty(String, Iterable)} using a
373 * generic message.
374 */
375 public static void assertEmpty(Iterable<?> iterable) {
376 assertEmpty(null, iterable);
377 }
378
379 /**
380 * Asserts that {@code map} is empty.
381 */
382 public static void assertEmpty(String message, Map<?,?> map) {
383 if (!map.isEmpty()) {
384 failNotEmpty(message, map.toString());
385 }
386 }
387
388 /**
389 * Variant of {@link #assertEmpty(String, Map)} using a generic
390 * message.
391 */
392 public static void assertEmpty(Map<?,?> map) {
393 assertEmpty(null, map);
394 }
395
396 /**
397 * Asserts that {@code iterable} is not empty.
398 */
399 public static void assertNotEmpty(String message, Iterable<?> iterable) {
400 if (!iterable.iterator().hasNext()) {
401 failEmpty(message);
402 }
403 }
404
405 /**
406 * Variant of assertNotEmpty(String, Iterable<?>)
407 * using a generic message.
408 */
409 public static void assertNotEmpty(Iterable<?> iterable) {
410 assertNotEmpty(null, iterable);
411 }
412
413 /**
414 * Asserts that {@code map} is not empty.
415 */
416 public static void assertNotEmpty(String message, Map<?,?> map) {
417 if (map.isEmpty()) {
418 failEmpty(message);
419 }
420 }
421
422 /**
423 * Variant of {@link #assertNotEmpty(String, Map)} using a generic
424 * message.
425 */
426 public static void assertNotEmpty(Map<?,?> map) {
427 assertNotEmpty(null, map);
428 }
429
430 /**
431 * Utility for testing equals() and hashCode() results at once.
432 * Tests that lhs.equals(rhs) matches expectedResult, as well as
433 * rhs.equals(lhs). Also tests that hashCode() return values are
434 * equal if expectedResult is true. (hashCode() is not tested if
435 * expectedResult is false, as unequal objects can have equal hashCodes.)
436 *
437 * @param lhs An Object for which equals() and hashCode() are to be tested.
438 * @param rhs As lhs.
439 * @param expectedResult True if the objects should compare equal,
440 * false if not.
441 */
442 public static void checkEqualsAndHashCodeMethods(
443 String message, Object lhs, Object rhs, boolean expectedResult) {
444
445 if ((lhs == null) && (rhs == null)) {
446 Assert.assertTrue(
447 "Your check is dubious...why would you expect null != null?",
448 expectedResult);
449 return;
450 }
451
452 if ((lhs == null) || (rhs == null)) {
453 Assert.assertFalse(
454 "Your check is dubious...why would you expect an object "
455 + "to be equal to null?", expectedResult);
456 }
457
458 if (lhs != null) {
459 Assert.assertEquals(message, expectedResult, lhs.equals(rhs));
460 }
461 if (rhs != null) {
462 Assert.assertEquals(message, expectedResult, rhs.equals(lhs));
463 }
464
465 if (expectedResult) {
466 String hashMessage =
467 "hashCode() values for equal objects should be the same";
468 if (message != null) {
469 hashMessage += ": " + message;
470 }
471 Assert.assertTrue(hashMessage, lhs.hashCode() == rhs.hashCode());
472 }
473 }
474
475 /**
476 * Variant of
477 * checkEqualsAndHashCodeMethods(String,Object,Object,boolean...)}
478 * using a generic message.
479 */
480 public static void checkEqualsAndHashCodeMethods(Object lhs, Object rhs,
481 boolean expectedResult) {
482 checkEqualsAndHashCodeMethods((String) null, lhs, rhs, expectedResult);
483 }
484
485 private static Matcher getMatcher(String expectedRegex, String actual) {
486 Pattern pattern = Pattern.compile(expectedRegex);
487 return pattern.matcher(actual);
488 }
489
490 private static void failEqual(String message, Object unexpected) {
491 failWithMessage(message, "expected not to be:<" + unexpected + ">");
492 }
493
494 private static void failWrongLength(
495 String message, int expected, int actual) {
496 failWithMessage(message, "expected array length:<" + expected
497 + "> but was:<" + actual + '>');
498 }
499
500 private static void failWrongElement(
501 String message, int index, Object expected, Object actual) {
502 failWithMessage(message, "expected array element[" + index + "]:<"
503 + expected + "> but was:<" + actual + '>');
504 }
505
506 private static void failNotMatches(
507 String message, String expectedRegex, String actual) {
508 String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
509 failWithMessage(message, "expected to match regex:<" + expectedRegex
510 + "> but was:" + actualDesc);
511 }
512
513 private static void failNotContains(
514 String message, String expectedRegex, String actual) {
515 String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
516 failWithMessage(message, "expected to contain regex:<" + expectedRegex
517 + "> but was:" + actualDesc);
518 }
519
520 private static void failMatch(
521 String message, String expectedRegex, String actual) {
522 failWithMessage(message, "expected not to match regex:<" + expectedRegex
523 + "> but was:<" + actual + '>');
524 }
525
526 private static void failContains(
527 String message, String expectedRegex, String actual) {
528 failWithMessage(message, "expected not to contain regex:<" + expectedRegex
529 + "> but was:<" + actual + '>');
530 }
531
532 private static void failNotEmpty(
533 String message, String actual) {
534 failWithMessage(message, "expected to be empty, but contained: <"
535 + actual + ">");
536 }
537
538 private static void failEmpty(String message) {
539 failWithMessage(message, "expected not to be empty, but was");
540 }
541
542 private static void failWithMessage(String userMessage, String ourMessage) {
543 Assert.fail((userMessage == null)
544 ? ourMessage
545 : userMessage + ' ' + ourMessage);
546 }
547
548 private static boolean equal(Object a, Object b) {
549 return a == b || (a != null && a.equals(b));
550 }
551
552}