1/*
2 * Copyright (C) 2011 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 com.android.providers.contacts;
18
19import android.content.Context;
20import android.graphics.BitmapFactory;
21
22import com.google.android.collect.Sets;
23
24import junit.framework.Assert;
25
26import java.io.ByteArrayOutputStream;
27import java.io.IOException;
28import java.io.InputStream;
29import java.util.Arrays;
30import java.util.Set;
31
32/**
33 * Contains additional assertion methods not found in Junit or MoreAsserts.
34 */
35public final class EvenMoreAsserts {
36    // Non instantiable.
37    private EvenMoreAsserts() { }
38
39    public static <T extends Exception> void assertThrows(Class<T> exception, Runnable r) {
40        assertThrows(null, exception, r);
41    }
42
43    public static <T extends Exception> void assertThrows(String message, Class<T> exception,
44            Runnable r) {
45        try {
46            r.run();
47           // Cannot invoke Assert.fail() here because it will be caught by the try/catch below
48           // and, if we are expecting an AssertionError or AssertionFailedError (depending on
49           // the platform), we might incorrectly identify that as a success.
50        } catch (Exception caught) {
51            if (!exception.isInstance(caught)) {
52                Assert.fail(appendUserMessage("Exception " + exception + " expected but " +
53                        caught +" thrown.", message));
54            }
55            return;
56        }
57        Assert.fail(appendUserMessage(
58                "Exception " + exception + " expected but no exception was thrown.",
59                message));
60    }
61
62    private static String appendUserMessage(String errorMsg, String userMsg) {
63        return userMsg == null ? errorMsg : errorMsg + userMsg;
64    }
65
66    public static void assertImageRawData(Context context, byte[] expected,
67            InputStream actualStream)
68            throws IOException {
69        ByteArrayOutputStream baos = new ByteArrayOutputStream();
70
71        final byte[] buffer = new byte[4096];
72        int count;
73        while ((count = actualStream.read(buffer)) != -1) {
74            baos.write(buffer, 0, count);
75        }
76        actualStream.close();
77
78        assertImageRawData(context, expected, baos.toByteArray());
79    }
80
81    public static void assertImageRawData(Context context, byte[] expected, byte[] actual) {
82        String failReason = null;
83        if (expected.length != actual.length) {
84            failReason = "Different data lengths:" +
85                    " expected=" + expected.length + " actual=" + actual.length;
86        } else if (!Arrays.equals(expected, actual)) {
87            failReason = "Different data:";
88        }
89        if (failReason == null) {
90            return;
91        }
92        String expectedFile = TestUtils.dumpToCacheDir(context, "expected", ".jpg", expected);
93        String actualFile = TestUtils.dumpToCacheDir(context, "actual", ".jpg", actual);
94
95        // Length or hashCode is different.  We'll fail, but put the dimensions in the message.
96        Assert.fail(failReason + ", expected dimentions=" + getImageDimensions(expected) +
97                " actual dimentions=" + getImageDimensions(actual) +
98                " Data written to " + expectedFile + " and " + actualFile);
99    }
100
101    private static final String getImageDimensions(byte[] imageData) {
102        BitmapFactory.Options o = new BitmapFactory.Options();
103        o.inJustDecodeBounds = true;
104        BitmapFactory.decodeByteArray(imageData, 0, imageData.length, o);
105
106        return "[" + o.outWidth + " x " + o.outHeight + "]";
107    }
108
109    public static void assertUnique(Object... values) {
110        Set<Object> set = Sets.newHashSet();
111        for (Object o : values) {
112            Assert.assertFalse("Duplicate found: " + o, set.contains(o));
113            set.add(o);
114        }
115    }
116}
117