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