Home | History | Annotate | Download | only in test
      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 junit.framework.Assert;
     20 
     21 import java.util.Arrays;
     22 import java.util.HashMap;
     23 import java.util.HashSet;
     24 import java.util.Map;
     25 import java.util.Set;
     26 import java.util.ArrayList;
     27 import java.util.regex.MatchResult;
     28 import java.util.regex.Matcher;
     29 import java.util.regex.Pattern;
     30 
     31 /**
     32  * Contains additional assertion methods not found in JUnit.
     33  */
     34 public 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      * @hide 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, long[] expected, long[] 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      * @hide 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(long[] expected, long[] actual) {
    153         assertEquals(null, expected, actual);
    154     }
    155 
    156 
    157     /**
    158      * Asserts that array {@code actual} is the same size and every element equals
    159      * those in array {@code expected}. On failure, message indicates first
    160      * specific element mismatch.
    161      */
    162     public static void assertEquals(
    163             String message, double[] expected, double[] actual) {
    164         if (expected.length != actual.length) {
    165             failWrongLength(message, expected.length, actual.length);
    166         }
    167         for (int i = 0; i < expected.length; i++) {
    168             if (expected[i] != actual[i]) {
    169                 failWrongElement(message, i, expected[i], actual[i]);
    170             }
    171         }
    172     }
    173 
    174     /**
    175      * Asserts that array {@code actual} is the same size and every element equals
    176      * those in array {@code expected}. On failure, message indicates first
    177      * specific element mismatch.
    178      */
    179     public static void assertEquals(double[] expected, double[] actual) {
    180         assertEquals(null, expected, actual);
    181     }
    182 
    183     /**
    184      * Asserts that array {@code actual} is the same size and every element
    185      * is the same as those in array {@code expected}. Note that this uses
    186      * {@code equals()} instead of {@code ==} to compare the objects.
    187      * {@code null} will be considered equal to {@code null} (unlike SQL).
    188      * On failure, message indicates first specific element mismatch.
    189      */
    190     public static void assertEquals(
    191             String message, Object[] expected, Object[] actual) {
    192         if (expected.length != actual.length) {
    193             failWrongLength(message, expected.length, actual.length);
    194         }
    195         for (int i = 0; i < expected.length; i++) {
    196             Object exp = expected[i];
    197             Object act = actual[i];
    198             // The following borrowed from java.util.equals(Object[], Object[]).
    199             if (!((exp==null) ? act==null : exp.equals(act))) {
    200                 failWrongElement(message, i, exp, act);
    201             }
    202         }
    203     }
    204 
    205     /**
    206      * Asserts that array {@code actual} is the same size and every element
    207      * is the same as those in array {@code expected}. Note that this uses
    208      * {@code ==} instead of {@code equals()} to compare the objects.
    209      * On failure, message indicates first specific element mismatch.
    210      */
    211     public static void assertEquals(Object[] expected, Object[] actual) {
    212         assertEquals(null, expected, actual);
    213     }
    214 
    215     /** Asserts that two sets contain the same elements. */
    216     public static void assertEquals(
    217             String message, Set<? extends Object> expected, Set<? extends Object> actual) {
    218         Set<Object> onlyInExpected = new HashSet<Object>(expected);
    219         onlyInExpected.removeAll(actual);
    220         Set<Object> onlyInActual = new HashSet<Object>(actual);
    221         onlyInActual.removeAll(expected);
    222         if (onlyInExpected.size() != 0 || onlyInActual.size() != 0) {
    223             Set<Object> intersection = new HashSet<Object>(expected);
    224             intersection.retainAll(actual);
    225             failWithMessage(
    226                     message,
    227                     "Sets do not match.\nOnly in expected: " + onlyInExpected
    228                     + "\nOnly in actual: " + onlyInActual
    229                     + "\nIntersection: " + intersection);
    230         }
    231     }
    232 
    233     /** Asserts that two sets contain the same elements. */
    234     public static void assertEquals(Set<? extends Object> expected, Set<? extends Object> actual) {
    235         assertEquals(null, expected, actual);
    236     }
    237 
    238     /**
    239      * Asserts that {@code expectedRegex} exactly matches {@code actual} and
    240      * fails with {@code message} if it does not.  The MatchResult is returned
    241      * in case the test needs access to any captured groups.  Note that you can
    242      * also use this for a literal string, by wrapping your expected string in
    243      * {@link Pattern#quote}.
    244      */
    245     public static MatchResult assertMatchesRegex(
    246             String message, String expectedRegex, String actual) {
    247         if (actual == null) {
    248             failNotMatches(message, expectedRegex, actual);
    249         }
    250         Matcher matcher = getMatcher(expectedRegex, actual);
    251         if (!matcher.matches()) {
    252             failNotMatches(message, expectedRegex, actual);
    253         }
    254         return matcher;
    255     }
    256 
    257     /**
    258      * Variant of {@link #assertMatchesRegex(String,String,String)} using a
    259      * generic message.
    260      */
    261     public static MatchResult assertMatchesRegex(
    262             String expectedRegex, String actual) {
    263         return assertMatchesRegex(null, expectedRegex, actual);
    264     }
    265 
    266     /**
    267      * Asserts that {@code expectedRegex} matches any substring of {@code actual}
    268      * and fails with {@code message} if it does not.  The Matcher is returned in
    269      * case the test needs access to any captured groups.  Note that you can also
    270      * use this for a literal string, by wrapping your expected string in
    271      * {@link Pattern#quote}.
    272      */
    273     public static MatchResult assertContainsRegex(
    274             String message, String expectedRegex, String actual) {
    275         if (actual == null) {
    276             failNotContains(message, expectedRegex, actual);
    277         }
    278         Matcher matcher = getMatcher(expectedRegex, actual);
    279         if (!matcher.find()) {
    280             failNotContains(message, expectedRegex, actual);
    281         }
    282         return matcher;
    283     }
    284 
    285     /**
    286      * Variant of {@link #assertContainsRegex(String,String,String)} using a
    287      * generic message.
    288      */
    289     public static MatchResult assertContainsRegex(
    290             String expectedRegex, String actual) {
    291         return assertContainsRegex(null, expectedRegex, actual);
    292     }
    293 
    294     /**
    295      * Asserts that {@code expectedRegex} does not exactly match {@code actual},
    296      * and fails with {@code message} if it does. Note that you can also use
    297      * this for a literal string, by wrapping your expected string in
    298      * {@link Pattern#quote}.
    299      */
    300     public static void assertNotMatchesRegex(
    301             String message, String expectedRegex, String actual) {
    302         Matcher matcher = getMatcher(expectedRegex, actual);
    303         if (matcher.matches()) {
    304             failMatch(message, expectedRegex, actual);
    305         }
    306     }
    307 
    308     /**
    309      * Variant of {@link #assertNotMatchesRegex(String,String,String)} using a
    310      * generic message.
    311      */
    312     public static void assertNotMatchesRegex(
    313             String expectedRegex, String actual) {
    314         assertNotMatchesRegex(null, expectedRegex, actual);
    315     }
    316 
    317     /**
    318      * Asserts that {@code expectedRegex} does not match any substring of
    319      * {@code actual}, and fails with {@code message} if it does.  Note that you
    320      * can also use this for a literal string, by wrapping your expected string
    321      * in {@link Pattern#quote}.
    322      */
    323     public static void assertNotContainsRegex(
    324             String message, String expectedRegex, String actual) {
    325         Matcher matcher = getMatcher(expectedRegex, actual);
    326         if (matcher.find()) {
    327             failContains(message, expectedRegex, actual);
    328         }
    329     }
    330 
    331     /**
    332      * Variant of {@link #assertNotContainsRegex(String,String,String)} using a
    333      * generic message.
    334      */
    335     public static void assertNotContainsRegex(
    336             String expectedRegex, String actual) {
    337         assertNotContainsRegex(null, expectedRegex, actual);
    338     }
    339 
    340     /**
    341      * Asserts that {@code actual} contains precisely the elements
    342      * {@code expected}, and in the same order.
    343      */
    344     public static void assertContentsInOrder(
    345             String message, Iterable<?> actual, Object... expected) {
    346         ArrayList actualList = new ArrayList();
    347         for (Object o : actual) {
    348             actualList.add(o);
    349         }
    350         Assert.assertEquals(message, Arrays.asList(expected), actualList);
    351     }
    352 
    353     /**
    354      * Variant of assertContentsInOrder(String, Iterable<?>, Object...)
    355      * using a generic message.
    356      */
    357     public static void assertContentsInOrder(
    358             Iterable<?> actual, Object... expected) {
    359         assertContentsInOrder((String) null, actual, expected);
    360     }
    361 
    362     /**
    363      * Asserts that {@code actual} contains precisely the elements
    364      * {@code expected}, but in any order.
    365      */
    366     public static void assertContentsInAnyOrder(String message, Iterable<?> actual,
    367             Object... expected) {
    368         HashMap<Object, Object> expectedMap = new HashMap<Object, Object>(expected.length);
    369         for (Object expectedObj : expected) {
    370             expectedMap.put(expectedObj, expectedObj);
    371         }
    372 
    373         for (Object actualObj : actual) {
    374             if (expectedMap.remove(actualObj) == null) {
    375                 failWithMessage(message, "Extra object in actual: (" + actualObj.toString() + ")");
    376             }
    377         }
    378 
    379         if (expectedMap.size() > 0) {
    380             failWithMessage(message, "Extra objects in expected.");
    381         }
    382     }
    383 
    384     /**
    385      * Variant of assertContentsInAnyOrder(String, Iterable<?>, Object...)
    386      * using a generic message.
    387      */
    388     public static void assertContentsInAnyOrder(Iterable<?> actual, Object... expected) {
    389         assertContentsInAnyOrder((String)null, actual, expected);
    390     }
    391 
    392     /**
    393      * Asserts that {@code iterable} is empty.
    394      */
    395     public static void assertEmpty(String message, Iterable<?> iterable) {
    396         if (iterable.iterator().hasNext()) {
    397             failNotEmpty(message, iterable.toString());
    398         }
    399     }
    400 
    401     /**
    402      * Variant of {@link #assertEmpty(String, Iterable)} using a
    403      * generic message.
    404      */
    405     public static void assertEmpty(Iterable<?> iterable) {
    406         assertEmpty(null, iterable);
    407     }
    408 
    409     /**
    410      * Asserts that {@code map} is empty.
    411      */
    412     public static void assertEmpty(String message, Map<?,?> map) {
    413         if (!map.isEmpty()) {
    414             failNotEmpty(message, map.toString());
    415         }
    416     }
    417 
    418     /**
    419      * Variant of {@link #assertEmpty(String, Map)} using a generic
    420      * message.
    421      */
    422     public  static void assertEmpty(Map<?,?> map) {
    423         assertEmpty(null, map);
    424     }
    425 
    426     /**
    427      * Asserts that {@code iterable} is not empty.
    428      */
    429     public static void assertNotEmpty(String message, Iterable<?> iterable) {
    430         if (!iterable.iterator().hasNext()) {
    431             failEmpty(message);
    432         }
    433     }
    434 
    435     /**
    436      * Variant of assertNotEmpty(String, Iterable<?>)
    437      * using a generic message.
    438      */
    439     public static void assertNotEmpty(Iterable<?> iterable) {
    440         assertNotEmpty(null, iterable);
    441     }
    442 
    443     /**
    444      * Asserts that {@code map} is not empty.
    445      */
    446     public static void assertNotEmpty(String message, Map<?,?> map) {
    447         if (map.isEmpty()) {
    448             failEmpty(message);
    449         }
    450     }
    451 
    452     /**
    453      * Variant of {@link #assertNotEmpty(String, Map)} using a generic
    454      * message.
    455      */
    456     public static void assertNotEmpty(Map<?,?> map) {
    457         assertNotEmpty(null, map);
    458     }
    459 
    460     /**
    461      * Utility for testing equals() and hashCode() results at once.
    462      * Tests that lhs.equals(rhs) matches expectedResult, as well as
    463      * rhs.equals(lhs).  Also tests that hashCode() return values are
    464      * equal if expectedResult is true.  (hashCode() is not tested if
    465      * expectedResult is false, as unequal objects can have equal hashCodes.)
    466      *
    467      * @param lhs An Object for which equals() and hashCode() are to be tested.
    468      * @param rhs As lhs.
    469      * @param expectedResult True if the objects should compare equal,
    470      *   false if not.
    471      */
    472     public static void checkEqualsAndHashCodeMethods(
    473             String message, Object lhs, Object rhs, boolean expectedResult) {
    474 
    475         if ((lhs == null) && (rhs == null)) {
    476             Assert.assertTrue(
    477                     "Your check is dubious...why would you expect null != null?",
    478                     expectedResult);
    479             return;
    480         }
    481 
    482         if ((lhs == null) || (rhs == null)) {
    483             Assert.assertFalse(
    484                     "Your check is dubious...why would you expect an object "
    485                             + "to be equal to null?", expectedResult);
    486         }
    487 
    488         if (lhs != null) {
    489             Assert.assertEquals(message, expectedResult, lhs.equals(rhs));
    490         }
    491         if (rhs != null) {
    492             Assert.assertEquals(message, expectedResult, rhs.equals(lhs));
    493         }
    494 
    495         if (expectedResult) {
    496             String hashMessage =
    497                     "hashCode() values for equal objects should be the same";
    498             if (message != null) {
    499                 hashMessage += ": " + message;
    500             }
    501             Assert.assertTrue(hashMessage, lhs.hashCode() == rhs.hashCode());
    502         }
    503     }
    504 
    505     /**
    506      * Variant of
    507      * checkEqualsAndHashCodeMethods(String,Object,Object,boolean...)}
    508      * using a generic message.
    509      */
    510     public static void checkEqualsAndHashCodeMethods(Object lhs, Object rhs,
    511             boolean expectedResult) {
    512         checkEqualsAndHashCodeMethods((String) null, lhs, rhs, expectedResult);
    513     }
    514 
    515     private static Matcher getMatcher(String expectedRegex, String actual) {
    516         Pattern pattern = Pattern.compile(expectedRegex);
    517         return pattern.matcher(actual);
    518     }
    519 
    520     private static void failEqual(String message, Object unexpected) {
    521         failWithMessage(message, "expected not to be:<" + unexpected + ">");
    522     }
    523 
    524     private static void failWrongLength(
    525             String message, int expected, int actual) {
    526         failWithMessage(message, "expected array length:<" + expected
    527                 + "> but was:<" + actual + '>');
    528     }
    529 
    530     private static void failWrongElement(
    531             String message, int index, Object expected, Object actual) {
    532         failWithMessage(message, "expected array element[" + index + "]:<"
    533                 + expected + "> but was:<" + actual + '>');
    534     }
    535 
    536     private static void failNotMatches(
    537             String message, String expectedRegex, String actual) {
    538         String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
    539         failWithMessage(message, "expected to match regex:<" + expectedRegex
    540                 + "> but was:" + actualDesc);
    541     }
    542 
    543     private static void failNotContains(
    544             String message, String expectedRegex, String actual) {
    545         String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
    546         failWithMessage(message, "expected to contain regex:<" + expectedRegex
    547                 + "> but was:" + actualDesc);
    548     }
    549 
    550     private static void failMatch(
    551             String message, String expectedRegex, String actual) {
    552         failWithMessage(message, "expected not to match regex:<" + expectedRegex
    553                 + "> but was:<" + actual + '>');
    554     }
    555 
    556     private static void failContains(
    557             String message, String expectedRegex, String actual) {
    558         failWithMessage(message, "expected not to contain regex:<" + expectedRegex
    559                 + "> but was:<" + actual + '>');
    560     }
    561 
    562     private static void failNotEmpty(
    563             String message, String actual) {
    564         failWithMessage(message, "expected to be empty, but contained: <"
    565                 + actual + ">");
    566     }
    567 
    568     private static void failEmpty(String message) {
    569         failWithMessage(message, "expected not to be empty, but was");
    570     }
    571 
    572     private static void failWithMessage(String userMessage, String ourMessage) {
    573         Assert.fail((userMessage == null)
    574                 ? ourMessage
    575                 : userMessage + ' ' + ourMessage);
    576     }
    577 
    578     private static boolean equal(Object a, Object b) {
    579         return a == b || (a != null && a.equals(b));
    580     }
    581 
    582 }
    583