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