• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.test;
18 
19 import com.google.android.collect.Lists;
20 import junit.framework.Assert;
21 
22 import java.util.Arrays;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.ArrayList;
28 import java.util.regex.MatchResult;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 
32 /**
33  * Contains additional assertion methods not found in JUnit.
34  */
35 public final class MoreAsserts {
36 
MoreAsserts()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      */
assertAssignableFrom(Class<?> expected, Object actual)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      */
assertAssignableFrom(Class<?> expected, Class<?> actual)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      */
assertNotEqual( String message, Object unexpected, Object actual)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      */
assertNotEqual(Object unexpected, Object actual)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      */
assertEquals( String message, byte[] expected, byte[] actual)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      */
assertEquals(byte[] expected, byte[] actual)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      */
assertEquals( String message, int[] expected, int[] actual)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      */
assertEquals(int[] expected, int[] actual)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      */
assertEquals( String message, double[] expected, double[] actual)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      */
assertEquals(double[] expected, double[] actual)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.
161      * {@code null} will be considered equal to {@code null} (unlike SQL).
162      * On failure, message indicates first specific element mismatch.
163      */
assertEquals( String message, Object[] expected, Object[] actual)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      */
assertEquals(Object[] expected, Object[] actual)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. */
assertEquals( String message, Set<? extends Object> expected, Set<? extends Object> actual)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. */
assertEquals(Set<? extends Object> expected, Set<? extends Object> actual)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      */
assertMatchesRegex( String message, String expectedRegex, String actual)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      */
assertMatchesRegex( String expectedRegex, String actual)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      */
assertContainsRegex( String message, String expectedRegex, String actual)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      */
assertContainsRegex( String expectedRegex, String actual)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      */
assertNotMatchesRegex( String message, String expectedRegex, String actual)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      */
assertNotMatchesRegex( String expectedRegex, String actual)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      */
assertNotContainsRegex( String message, String expectedRegex, String actual)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      */
assertNotContainsRegex( String expectedRegex, String actual)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      */
assertContentsInOrder( String message, Iterable<?> actual, Object... expected)318     public static void assertContentsInOrder(
319             String message, Iterable<?> actual, Object... expected) {
320         ArrayList actualList = new ArrayList();
321         for (Object o : actual) {
322             actualList.add(o);
323         }
324         Assert.assertEquals(message, Arrays.asList(expected), actualList);
325     }
326 
327     /**
328      * Variant of assertContentsInOrder(String, Iterable<?>, Object...)
329      * using a generic message.
330      */
assertContentsInOrder( Iterable<?> actual, Object... expected)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      */
assertContentsInAnyOrder(String message, Iterable<?> actual, Object... expected)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      */
assertContentsInAnyOrder(Iterable<?> actual, Object... expected)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      */
assertEmpty(String message, Iterable<?> iterable)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      */
assertEmpty(Iterable<?> iterable)379     public static void assertEmpty(Iterable<?> iterable) {
380         assertEmpty(null, iterable);
381     }
382 
383     /**
384      * Asserts that {@code map} is empty.
385      */
assertEmpty(String message, Map<?,?> map)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      */
assertEmpty(Map<?,?> map)396     public  static void assertEmpty(Map<?,?> map) {
397         assertEmpty(null, map);
398     }
399 
400     /**
401      * Asserts that {@code iterable} is not empty.
402      */
assertNotEmpty(String message, Iterable<?> iterable)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      */
assertNotEmpty(Iterable<?> iterable)413     public static void assertNotEmpty(Iterable<?> iterable) {
414         assertNotEmpty(null, iterable);
415     }
416 
417     /**
418      * Asserts that {@code map} is not empty.
419      */
assertNotEmpty(String message, Map<?,?> map)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      */
assertNotEmpty(Map<?,?> map)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      */
checkEqualsAndHashCodeMethods( String message, Object lhs, Object rhs, boolean expectedResult)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      */
checkEqualsAndHashCodeMethods(Object lhs, Object rhs, boolean expectedResult)484     public static void checkEqualsAndHashCodeMethods(Object lhs, Object rhs,
485             boolean expectedResult) {
486         checkEqualsAndHashCodeMethods((String) null, lhs, rhs, expectedResult);
487     }
488 
getMatcher(String expectedRegex, String actual)489     private static Matcher getMatcher(String expectedRegex, String actual) {
490         Pattern pattern = Pattern.compile(expectedRegex);
491         return pattern.matcher(actual);
492     }
493 
failEqual(String message, Object unexpected)494     private static void failEqual(String message, Object unexpected) {
495         failWithMessage(message, "expected not to be:<" + unexpected + ">");
496     }
497 
failWrongLength( String message, int expected, int actual)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 
failWrongElement( String message, int index, Object expected, Object actual)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 
failNotMatches( String message, String expectedRegex, String actual)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 
failNotContains( String message, String expectedRegex, String actual)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 
failMatch( String message, String expectedRegex, String actual)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 
failContains( String message, String expectedRegex, String actual)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 
failNotEmpty( String message, String actual)536     private static void failNotEmpty(
537             String message, String actual) {
538         failWithMessage(message, "expected to be empty, but contained: <"
539                 + actual + ">");
540     }
541 
failEmpty(String message)542     private static void failEmpty(String message) {
543         failWithMessage(message, "expected not to be empty, but was");
544     }
545 
failWithMessage(String userMessage, String ourMessage)546     private static void failWithMessage(String userMessage, String ourMessage) {
547         Assert.fail((userMessage == null)
548                 ? ourMessage
549                 : userMessage + ' ' + ourMessage);
550     }
551 
equal(Object a, Object b)552     private static boolean equal(Object a, Object b) {
553         return a == b || (a != null && a.equals(b));
554     }
555 
556 }
557