1/*
2 * Copyright 2016 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.mediaframeworktest.helpers;
18
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.Collection;
22import java.util.List;
23
24import static junit.framework.Assert.assertEquals;
25import static junit.framework.Assert.assertTrue;
26import static junit.framework.Assert.fail;
27
28/**
29 * Helper set of methods to add extra useful assert functionality missing in junit.
30 */
31/**
32 * (non-Javadoc)
33 * @see android.hardware.camera2.cts.helpers.AssertHelpers
34 */
35public class AssertHelpers {
36
37    private static final int MAX_FORMAT_STRING = 50;
38
39    /**
40     * Assert that at least one of the elements in data is non-zero.
41     *
42     * <p>An empty or a null array always fails.</p>
43     */
44    public static void assertArrayNotAllZeroes(String message, byte[] data) {
45        int size = data.length;
46
47        int i = 0;
48        for (i = 0; i < size; ++i) {
49            if (data[i] != 0) {
50                break;
51            }
52        }
53
54        assertTrue(message, i < size);
55    }
56
57    /**
58     * Assert that every element in left is less than or equals to the corresponding element in
59     * right.
60     *
61     * <p>Array sizes must match.</p>
62     *
63     * @param message Message to use in case the assertion fails
64     * @param left Left array
65     * @param right Right array
66     */
67    public static void assertArrayNotGreater(String message, float[] left, float[] right) {
68        assertEquals("Array lengths did not match", left.length, right.length);
69
70        String leftString = Arrays.toString(left);
71        String rightString = Arrays.toString(right);
72
73        for (int i = 0; i < left.length; ++i) {
74            String msg = String.format(
75                    "%s: (%s should be less than or equals than %s; item index %d; left = %s; " +
76                    "right = %s)",
77                    message, left[i], right[i], i, leftString, rightString);
78
79            assertTrue(msg, left[i] <= right[i]);
80        }
81    }
82
83    /**
84     * Assert that every element in the value array is greater than the lower bound (exclusive).
85     *
86     * @param value an array of items
87     * @param lowerBound the exclusive lower bound
88     */
89    public static void assertArrayWithinLowerBound(String message, float[] value, float lowerBound)
90    {
91        for (int i = 0; i < value.length; ++i) {
92            assertTrue(
93                    String.format("%s: (%s should be greater than than %s; item index %d in %s)",
94                            message, value[i], lowerBound, i, Arrays.toString(value)),
95                    value[i] > lowerBound);
96        }
97    }
98
99    /**
100     * Assert that every element in the value array is less than the upper bound (exclusive).
101     *
102     * @param value an array of items
103     * @param upperBound the exclusive upper bound
104     */
105    public static void assertArrayWithinUpperBound(String message, float[] value, float upperBound)
106    {
107        for (int i = 0; i < value.length; ++i) {
108            assertTrue(
109                    String.format("%s: (%s should be less than than %s; item index %d in %s)",
110                            message, value[i], upperBound, i, Arrays.toString(value)),
111                    value[i] < upperBound);
112        }
113    }
114
115    /**
116     * Assert that {@code low <= value <= high}
117     */
118    public static void assertInRange(float value, float low, float high) {
119        assertTrue(
120                String.format("Value %s must be greater or equal to %s, but was lower", value, low),
121                value >= low);
122        assertTrue(
123                String.format("Value %s must be less than or equal to %s, but was higher",
124                        value, high),
125                value <= high);
126
127        // TODO: generic by using comparators
128    }
129
130    /**
131     * Assert that the given array contains the given value.
132     *
133     * @param message message to print on failure.
134     * @param actual array to test.
135     * @param checkVals value to check for array membership.
136     */
137    public static <T> void assertArrayContains(String message, T[] actual, T checkVals) {
138        assertCollectionContainsAnyOf(message, buildList(actual), Arrays.asList(checkVals));
139    }
140
141
142    /**
143     * Assert that the given array contains the given value.
144     *
145     * @param message message to print on failure.
146     * @param actual array to test.
147     * @param checkVals value to check for array membership.
148     */
149    public static void assertArrayContains(String message, int[] actual, int checkVals) {
150        assertCollectionContainsAnyOf(message, buildList(actual), Arrays.asList(checkVals));
151    }
152
153    /**
154     * Assert that the given array contains at least one of the given values.
155     *
156     * @param message message to print on failure.
157     * @param actual array to test
158     * @param checkVals values to check for array membership.
159     * @return the value contained, or null.
160     */
161    public static <T> T assertArrayContainsAnyOf(String message, T[] actual, T[] checkVals) {
162        return assertCollectionContainsAnyOf(message, buildList(actual), buildList(checkVals));
163    }
164
165    /**
166     * Assert that the given array contains at least one of the given values.
167     *
168     * @param message message to print on failure.
169     * @param actual array to test
170     * @param checkVals values to check for array membership.
171     * @return the value contained.
172     */
173    public static int assertArrayContainsAnyOf(String message, int[] actual, int[] checkVals) {
174        return assertCollectionContainsAnyOf(message, buildList(actual), buildList(checkVals));
175    }
176
177    /**
178     * Assert that the given {@link Collection} contains at least one of the given values.
179     *
180     * @param message message to print on failure.
181     * @param actual {@link Collection} to test.
182     * @param checkVals a {@link Collection} of values to check for membership.
183     * @return the value contained, or null.
184     */
185    public static <T> T assertCollectionContainsAnyOf(String message, Collection<T> actual,
186                                                      Collection<T> checkVals) {
187        boolean contains = false;
188        T selected = null;
189        for (T check : checkVals) {
190            contains = actual.contains(check);
191            if (contains) {
192                selected = check;
193                break;
194            }
195        }
196
197        if (!contains) {
198            fail(String.format("%s : No elements from %s in %s", message,
199                    formatCollection(actual, MAX_FORMAT_STRING),
200                    formatCollection(checkVals, MAX_FORMAT_STRING)));
201        }
202        return selected;
203    }
204
205    private static <T> List<T> buildList(T[] array) {
206        return new ArrayList<T>(Arrays.asList(array));
207    }
208
209    private static List<Integer> buildList(int[] array) {
210        List<Integer> list = new ArrayList<Integer>(array.length);
211        for (Integer val : array) {
212            list.add(val);
213        }
214        return list;
215    }
216
217    private static <T> String formatCollection(Collection<T> collection, int maxLen) {
218        StringBuilder builder = new StringBuilder();
219        builder.append("[");
220
221        boolean first = true;
222        for (T elem : collection) {
223            String val = ((first) ? ", " : "") + ((elem != null) ? elem.toString() : "null");
224            first = false;
225            if ((builder.length() + val.length()) > maxLen - "...]".length()) {
226                builder.append("...");
227                break;
228            } else {
229                builder.append(val);
230            }
231        }
232        builder.append("]");
233        return builder.toString();
234    }
235
236
237    // Suppress default constructor for noninstantiability
238    private AssertHelpers() { throw new AssertionError(); }
239}
240