blob: 7cf4089d7cc339ca1aef96231b981a957af32b04 [file] [log] [blame]
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.camera2.cts.helpers;
import android.graphics.Rect;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureRequest.Builder;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.params.MeteringRectangle;
import android.util.Log;
import android.util.Size;
import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher;
import org.junit.rules.ErrorCollector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* A camera test ErrorCollector class to gather the test failures during a test,
* instead of failing the test immediately for each failure.
*/
public class CameraErrorCollector extends ErrorCollector {
private static final String TAG = "CameraErrorCollector";
private static final boolean LOG_ERRORS = Log.isLoggable(TAG, Log.ERROR);
private String mCameraMsg = "";
@Override
public void verify() throws Throwable {
// Do not remove if using JUnit 3 test runners. super.verify() is protected.
super.verify();
}
/**
* Adds an unconditional error to the table.
*
* <p>Execution continues, but test will fail at the end.</p>
*
* @param message A string containing the failure reason.
*/
public void addMessage(String message) {
addErrorSuper(new Throwable(mCameraMsg + message));
}
/**
* Adds a Throwable to the table. <p>Execution continues, but the test will fail at the end.</p>
*/
@Override
public void addError(Throwable error) {
addErrorSuper(new Throwable(mCameraMsg + error.getMessage(), error));
}
private void addErrorSuper(Throwable error) {
if (LOG_ERRORS) Log.e(TAG, error.getMessage());
super.addError(error);
}
/**
* Adds a failure to the table if {@code matcher} does not match {@code value}.
* Execution continues, but the test will fail at the end if the match fails.
* The camera id is included into the failure log.
*/
@Override
public <T> void checkThat(final T value, final Matcher<T> matcher) {
super.checkThat(mCameraMsg, value, matcher);
}
/**
* Adds a failure with the given {@code reason} to the table if
* {@code matcher} does not match {@code value}. Execution continues, but
* the test will fail at the end if the match fails. The camera id is
* included into the failure log.
*/
@Override
public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
super.checkThat(mCameraMsg + reason, value, matcher);
}
/**
* Set the camera id to this error collector object for logging purpose.
*
* @param id The camera id to be set.
*/
public void setCameraId(String id) {
if (id != null) {
mCameraMsg = "Test failed for camera " + id + ": ";
} else {
mCameraMsg = "";
}
}
/**
* Adds a failure to the table if {@code condition} is not {@code true}.
* <p>
* Execution continues, but the test will fail at the end if the condition
* failed.
* </p>
*
* @param msg Message to be logged when check fails.
* @param condition Log the failure if it is not true.
*/
public boolean expectTrue(String msg, boolean condition) {
if (!condition) {
addMessage(msg);
}
return condition;
}
/**
* Check if the two values are equal.
*
* @param msg Message to be logged when check fails.
* @param expected Expected value to be checked against.
* @param actual Actual value to be checked.
* @return {@code true} if the two values are equal, {@code false} otherwise.
*
* @throws IllegalArgumentException if {@code expected} was {@code null}
*/
public <T> boolean expectEquals(String msg, T expected, T actual) {
if (expected == null) {
throw new IllegalArgumentException("expected value shouldn't be null");
}
if (!Objects.equals(expected, actual)) {
addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
actual));
return false;
}
return true;
}
/**
* Check if the two values are not equal.
*
* @param msg Message to be logged when check fails.
* @param expected Expected value to be checked against.
* @param actual Actual value to be checked.
* @return {@code true} if the two values are not equal, {@code false} otherwise.
*/
public <T> boolean expectNotEquals(String msg, T expected, T actual) {
if (Objects.equals(expected, actual)) {
addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
actual));
return false;
}
return true;
}
/**
* Check if the two arrays of values are deeply equal.
*
* @param msg Message to be logged when check fails.
* @param expected Expected array of values to be checked against.
* @param actual Actual array of values to be checked.
* @return {@code true} if the two arrays of values are deeply equal, {@code false} otherwise.
*
* @throws IllegalArgumentException if {@code expected} was {@code null}
*/
public <T> boolean expectEquals(String msg, T[] expected, T[] actual) {
if (expected == null) {
throw new IllegalArgumentException("expected value shouldn't be null");
}
if (!Arrays.deepEquals(expected, actual)) {
addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
Arrays.deepToString(expected), Arrays.deepToString(actual)));
return false;
}
return true;
}
/**
* Check if the two arrays of values are not deeply equal.
*
* @param msg Message to be logged when check fails.
* @param expected Expected array of values to be checked against.
* @param actual Actual array of values to be checked.
* @return {@code true} if the two arrays of values are not deeply equal, {@code false}
* otherwise.
*
* @throws IllegalArgumentException if {@code expected} was {@code null}
*/
public <T> boolean expectNotEquals(String msg, T[] expected, T[] actual) {
if (expected == null) {
throw new IllegalArgumentException("expected value shouldn't be null");
}
if (Arrays.deepEquals(expected, actual)) {
addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
Arrays.deepToString(expected), Arrays.deepToString(actual)));
return false;
}
return true;
}
/**
* Check that the {@code actual} value is greater than the {@code expected} value.
*
* @param msg Message to be logged when check fails.
* @param expected The expected value to check that the actual value is larger than.
* @param actual Actual value to check.
* @return {@code true} if {@code actual} is greater than {@code expected}.
*/
public <T extends Comparable<? super T>> boolean expectGreater(String msg, T expected,
T actual) {
return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
msg, expected, actual), actual.compareTo(expected) > 0);
}
/**
* Check that the {@code actual} value is greater than or equal to the {@code expected} value.
*
* @param msg Message to be logged when check fails.
* @param expected The expected value to check that the actual value is larger than or equal to.
* @param actual Actual value to check.
* @return {@code true} if {@code actual} is greater than or equal to {@code expected}.
*/
public <T extends Comparable<? super T>> boolean expectGreaterOrEqual(String msg, T expected,
T actual) {
return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
msg, expected, actual), actual.compareTo(expected) >= 0);
}
/**
* Check that the {@code actual} value is less than the {@code expected} value.
*
* @param msg Message to be logged when check fails.
* @param expected The expected value to check that the actual value is less than.
* @param actual Actual value to check.
* @return {@code true} if {@code actual} is less than {@code expected}.
*/
public <T extends Comparable<? super T>> boolean expectLess(String msg, T expected,
T actual) {
return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
msg, expected, actual), actual.compareTo(expected) < 0);
}
/**
* Check that the {@code actual} value is less than or equal to the {@code expected} value.
*
* @param msg Message to be logged when check fails.
* @param expected The expected value to check that the actual value is less than or equal to.
* @param actual Actual value to check.
* @return {@code true} if {@code actual} is less than or equal to {@code expected}.
*/
public <T extends Comparable<? super T>> boolean expectLessOrEqual(String msg, T expected,
T actual) {
return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
msg, expected, actual), actual.compareTo(expected) <= 0);
}
/**
* Check if the two float values are equal with given error tolerance.
*
* @param msg Message to be logged when check fails.
* @param expected Expected value to be checked against.
* @param actual Actual value to be checked.
* @param tolerance The error margin for the equality check.
* @return {@code true} if the two values are equal, {@code false} otherwise.
*/
public <T> boolean expectEquals(String msg, float expected, float actual, float tolerance) {
if (expected == actual) {
return true;
}
if (!(Math.abs(expected - actual) <= tolerance)) {
addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
expected, actual, tolerance));
return false;
}
return true;
}
/**
* Check if the two double values are equal with given error tolerance.
*
* @param msg Message to be logged when check fails.
* @param expected Expected value to be checked against.
* @param actual Actual value to be checked.
* @param tolerance The error margin for the equality check
* @return {@code true} if the two values are equal, {@code false} otherwise.
*/
public <T> boolean expectEquals(String msg, double expected, double actual, double tolerance) {
if (expected == actual) {
return true;
}
if (!(Math.abs(expected - actual) <= tolerance)) {
addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
expected, actual, tolerance));
return false;
}
return true;
}
/**
* Check that all values in the list are greater than or equal to the min value.
*
* @param msg Message to be logged when check fails
* @param list The list of values to be checked
* @param min The smallest allowed value
*/
public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
List<T> list, T min) {
for (T value : list) {
expectTrue(msg + String.format(", array value " + value.toString() +
" is less than %s",
min.toString()), value.compareTo(min) >= 0);
}
}
/**
* Check that all values in the array are greater than or equal to the min value.
*
* @param msg Message to be logged when check fails
* @param array The array of values to be checked
* @param min The smallest allowed value
*/
public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
T[] array, T min) {
expectValuesGreaterOrEqual(msg, Arrays.asList(array), min);
}
/**
* Expect the list of values are in the range.
*
* @param msg Message to be logged
* @param list The list of values to be checked
* @param min The min value of the range
* @param max The max value of the range
*/
public <T extends Comparable<? super T>> void expectValuesInRange(String msg, List<T> list,
T min, T max) {
for (T value : list) {
expectTrue(msg + String.format(", array value " + value.toString() +
" is out of range [%s, %s]",
min.toString(), max.toString()),
value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
}
}
/**
* Expect the array of values are in the range.
*
* @param msg Message to be logged
* @param array The array of values to be checked
* @param min The min value of the range
* @param max The max value of the range
*/
public <T extends Comparable<? super T>> void expectValuesInRange(String msg, T[] array,
T min, T max) {
expectValuesInRange(msg, Arrays.asList(array), min, max);
}
/**
* Expect the array of values are in the range.
*
* @param msg Message to be logged
* @param array The array of values to be checked
* @param min The min value of the range
* @param max The max value of the range
*/
public void expectValuesInRange(String msg, int[] array, int min, int max) {
ArrayList<Integer> l = new ArrayList<>(array.length);
for (int i : array) {
l.add(i);
}
expectValuesInRange(msg, l, min, max);
}
/**
* Expect the value is in the range.
*
* @param msg Message to be logged
* @param value The value to be checked
* @param min The min value of the range
* @param max The max value of the range
*
* @return {@code true} if the value was in range, {@code false} otherwise
*/
public <T extends Comparable<? super T>> boolean expectInRange(String msg, T value,
T min, T max) {
return expectTrue(msg + String.format(", value " + value.toString()
+ " is out of range [%s, %s]",
min.toString(), max.toString()),
value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
}
/**
* Check that two metering region arrays are similar enough by ensuring that each of their width,
* height, and all corners are within {@code errorPercent} of each other.
*
* <p>Note that the length of the arrays must be the same, and each weight must be the same
* as well. We assume the order is also equivalent.</p>
*
* <p>At most 1 error per each dissimilar metering region is collected.</p>
*
* @param msg Message to be logged
* @param expected The reference 'expected' values to be used to check against
* @param actual The actual values that were received
* @param errorPercent Within how many percent the components should be
*
* @return {@code true} if all expects passed, {@code false} otherwise
*/
public boolean expectMeteringRegionsAreSimilar(String msg,
MeteringRectangle[] expected, MeteringRectangle[] actual,
float errorPercent) {
String expectedActualMsg = String.format("expected (%s), actual (%s)",
Arrays.deepToString(expected), Arrays.deepToString(actual));
String differentSizesMsg = String.format(
"%s: rect lists are different sizes; %s",
msg, expectedActualMsg);
String differentWeightsMsg = String.format(
"%s: rect weights are different; %s",
msg, expectedActualMsg);
if (!expectTrue(differentSizesMsg, actual != null)) {
return false;
}
if (!expectEquals(differentSizesMsg, expected.length, actual.length)) return false;
boolean succ = true;
for (int i = 0; i < expected.length; ++i) {
if (i < actual.length) {
// Avoid printing multiple errors for the same rectangle
if (!expectRectsAreSimilar(
msg, expected[i].getRect(), actual[i].getRect(), errorPercent)) {
succ = false;
continue;
}
if (!expectEquals(differentWeightsMsg,
expected[i].getMeteringWeight(), actual[i].getMeteringWeight())) {
succ = false;
continue;
}
}
}
return succ;
}
/**
* Check that two rectangles are similar enough by ensuring that their width, height,
* and all corners are within {@code errorPercent} of each other.
*
* <p>Only the first error is collected, to avoid spamming several error messages when
* the rectangle is hugely dissimilar.</p>
*
* @param msg Message to be logged
* @param expected The reference 'expected' value to be used to check against
* @param actual The actual value that was received
* @param errorPercent Within how many percent the components should be
*
* @return {@code true} if all expects passed, {@code false} otherwise
*/
public boolean expectRectsAreSimilar(String msg, Rect expected, Rect actual,
float errorPercent) {
String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " +
"actual (%s), error percent (%s), reason: ",
msg, expected, actual, errorPercent);
if (!expectSimilarValues(
formattedMsg, "too wide", "too narrow", actual.width(), expected.width(),
errorPercent)) return false;
if (!expectSimilarValues(
formattedMsg, "too tall", "too short", actual.height(), expected.height(),
errorPercent)) return false;
if (!expectSimilarValues(
formattedMsg, "left pt too right", "left pt too left", actual.left, expected.left,
errorPercent)) return false;
if (!expectSimilarValues(
formattedMsg, "right pt too right", "right pt too left",
actual.right, expected.right, errorPercent)) return false;
if (!expectSimilarValues(
formattedMsg, "top pt too low", "top pt too high", actual.top, expected.top,
errorPercent)) return false;
if (!expectSimilarValues(
formattedMsg, "bottom pt too low", "bottom pt too high", actual.top, expected.top,
errorPercent)) return false;
return true;
}
/**
* Check that the rectangle is centered within a certain tolerance of {@code errorPercent},
* with respect to the {@code bounds} bounding rectangle.
*
* @param msg Message to be logged
* @param expectedBounds The width/height of the bounding rectangle
* @param actual The actual value that was received
* @param errorPercent Within how many percent the centering should be
*/
public void expectRectCentered(String msg, Size expectedBounds, Rect actual,
float errorPercent) {
String formattedMsg = String.format("%s: rect should be centered; expected bounds (%s), " +
"actual (%s), error percent (%s), reason: ",
msg, expectedBounds, actual, errorPercent);
int centerBoundX = expectedBounds.getWidth() / 2;
int centerBoundY = expectedBounds.getHeight() / 2;
expectSimilarValues(
formattedMsg, "too low", "too high", actual.centerY(), centerBoundY,
errorPercent);
expectSimilarValues(
formattedMsg, "too right", "too left", actual.centerX(), centerBoundX,
errorPercent);
}
private boolean expectSimilarValues(
String formattedMsg, String tooSmall, String tooLarge, int actualValue,
int expectedValue, float errorPercent) {
boolean succ = true;
succ = expectTrue(formattedMsg + tooLarge,
actualValue <= (expectedValue * (1.0f + errorPercent))) && succ;
succ = expectTrue(formattedMsg + tooSmall,
actualValue >= (expectedValue * (1.0f - errorPercent))) && succ;
return succ;
}
public void expectNotNull(String msg, Object obj) {
checkThat(msg, obj, CoreMatchers.notNullValue());
}
public void expectNull(String msg, Object obj) {
if (obj != null) {
addMessage(msg);
}
}
/**
* Check if the values in the array are monotonically increasing (decreasing) and not all
* equal.
*
* @param array The array of values to be checked
* @param ascendingOrder The monotonicity ordering to be checked with
*/
public <T extends Comparable<? super T>> void checkArrayMonotonicityAndNotAllEqual(T[] array,
boolean ascendingOrder) {
String orderMsg = ascendingOrder ? ("increasing order") : ("decreasing order");
for (int i = 0; i < array.length - 1; i++) {
int compareResult = array[i + 1].compareTo(array[i]);
boolean condition = compareResult >= 0;
if (!ascendingOrder) {
condition = compareResult <= 0;
}
expectTrue(String.format("Adjacent values (%s and %s) %s monotonicity is broken",
array[i].toString(), array[i + 1].toString(), orderMsg), condition);
}
expectTrue("All values of this array are equal: " + array[0].toString(),
array[0].compareTo(array[array.length - 1]) != 0);
}
/**
* Check if the key value is not null and return the value.
*
* @param characteristics The {@link CameraCharacteristics} to get the key from.
* @param key The {@link CameraCharacteristics} key to be checked.
*
* @return The value of the key.
*/
public <T> T expectKeyValueNotNull(CameraCharacteristics characteristics,
CameraCharacteristics.Key<T> key) {
T value = characteristics.get(key);
if (value == null) {
addMessage("Key " + key.getName() + " shouldn't be null");
}
return value;
}
/**
* Check if the key value is not null and return the value.
*
* @param request The {@link CaptureRequest} to get the key from.
* @param key The {@link CaptureRequest} key to be checked.
*
* @return The value of the key.
*/
public <T> T expectKeyValueNotNull(CaptureRequest request,
CaptureRequest.Key<T> key) {
T value = request.get(key);
if (value == null) {
addMessage("Key " + key.getName() + " shouldn't be null");
}
return value;
}
/**
* Check if the key value is not null and return the value.
*
* @param request The {@link CaptureRequest#Builder} to get the key from.
* @param key The {@link CaptureRequest} key to be checked.
* @return The value of the key.
*/
public <T> T expectKeyValueNotNull(Builder request, CaptureRequest.Key<T> key) {
T value = request.get(key);
if (value == null) {
addMessage("Key " + key.getName() + " shouldn't be null");
}
return value;
}
/**
* Check if the key value is not null and return the value.
*
* @param result The {@link CaptureResult} to get the key from.
* @param key The {@link CaptureResult} key to be checked.
* @return The value of the key.
*/
public <T> T expectKeyValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
return expectKeyValueNotNull("", result, key);
}
/**
* Check if the key value is not null and return the value.
*
* @param msg The message to be logged.
* @param result The {@link CaptureResult} to get the key from.
* @param key The {@link CaptureResult} key to be checked.
* @return The value of the key.
*/
public <T> T expectKeyValueNotNull(String msg, CaptureResult result, CaptureResult.Key<T> key) {
T value = result.get(key);
if (value == null) {
addMessage(msg + " Key " + key.getName() + " shouldn't be null");
}
return value;
}
/**
* Check if the key is non-null and the value is not equal to target.
*
* @param request The The {@link CaptureRequest#Builder} to get the key from.
* @param key The {@link CaptureRequest} key to be checked.
* @param expected The expected value of the CaptureRequest key.
*/
public <T> void expectKeyValueNotEquals(
Builder request, CaptureRequest.Key<T> key, T expected) {
if (request == null || key == null || expected == null) {
throw new IllegalArgumentException("request, key and expected shouldn't be null");
}
T value;
if ((value = expectKeyValueNotNull(request, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
checkThat(reason, value, CoreMatchers.not(expected));
}
/**
* Check if the key is non-null and the value is not equal to target.
*
* @param result The {@link CaptureResult} to get the key from.
* @param key The {@link CaptureResult} key to be checked.
* @param expected The expected value of the CaptureResult key.
*/
public <T> void expectKeyValueNotEquals(
CaptureResult result, CaptureResult.Key<T> key, T expected) {
if (result == null || key == null || expected == null) {
throw new IllegalArgumentException("result, key and expected shouldn't be null");
}
T value;
if ((value = expectKeyValueNotNull(result, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
checkThat(reason, value, CoreMatchers.not(expected));
}
/**
* Check if the value is non-null and the value is equal to target.
*
* @param result The {@link CaptureResult} to lookup the value in.
* @param key The {@link CaptureResult} key to be checked.
* @param expected The expected value of the {@link CaptureResult} key.
*/
public <T> void expectKeyValueEquals(CaptureResult result, CaptureResult.Key<T> key,
T expected) {
if (result == null || key == null || expected == null) {
throw new IllegalArgumentException("request, key and expected shouldn't be null");
}
T value;
if ((value = expectKeyValueNotNull(result, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value.toString()
+ " doesn't match the expected value " + expected.toString();
checkThat(reason, value, CoreMatchers.equalTo(expected));
}
/**
* Check if the key is non-null and the value is equal to target.
*
* <p>Only check non-null if the target is null.</p>
*
* @param request The The {@link CaptureRequest#Builder} to get the key from.
* @param key The {@link CaptureRequest} key to be checked.
* @param expected The expected value of the CaptureRequest key.
*/
public <T> void expectKeyValueEquals(Builder request, CaptureRequest.Key<T> key, T expected) {
if (request == null || key == null || expected == null) {
throw new IllegalArgumentException("request, key and expected shouldn't be null");
}
T value;
if ((value = expectKeyValueNotNull(request, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value.toString()
+ " doesn't match the expected value " + expected.toString();
checkThat(reason, value, CoreMatchers.equalTo(expected));
}
/**
* Check if the key is non-null, and the key value is greater than the expected value.
*
* @param result {@link CaptureResult} to check.
* @param key The {@link CaptureResult} key to be checked.
* @param expected The expected to be compared to the value for the given key.
*/
public <T extends Comparable<? super T>> void expectKeyValueGreaterOrEqual(
CaptureResult result, CaptureResult.Key<T> key, T expected) {
T value;
if ((value = expectKeyValueNotNull(result, key)) == null) {
return;
}
expectGreaterOrEqual(key.getName(), expected, value);
}
/**
* Check if the key is non-null, and the key value is greater than the expected value.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param expected The expected to be compared to the value for the given key.
*/
public <T extends Comparable<? super T>> void expectKeyValueGreaterThan(
CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T expected) {
T value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
expectGreater(key.getName(), expected, value);
}
/**
* Check if the key is non-null, and the key value is in the expected range.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param min The min value of the range
* @param max The max value of the range
*/
public <T extends Comparable<? super T>> void expectKeyValueInRange(
CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T min, T max) {
T value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
expectInRange(key.getName(), value, min, max);
}
/**
* Check if the key is non-null, and the key value is one of the expected values.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param expected The expected values for the given key.
*/
public <T> void expectKeyValueIsIn(CameraCharacteristics characteristics,
CameraCharacteristics.Key<T> key, T... expected) {
T value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value
+ " isn't one of the expected values " + Arrays.deepToString(expected);
expectContains(reason, expected, value);
}
/**
* Check if the key is non-null, and the key value contains the expected element.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param expected The expected element to be contained in the value for the given key.
*/
public <T> void expectKeyValueContains(CameraCharacteristics characteristics,
CameraCharacteristics.Key<T[]> key, T expected) {
T[] value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value
+ " doesn't contain the expected value " + expected;
expectContains(reason, value, expected);
}
/**
* Check if the key is non-null, and the key value contains the expected element.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param expected The expected element to be contained in the value for the given key.
*/
public void expectKeyValueContains(CameraCharacteristics characteristics,
CameraCharacteristics.Key<int[]> key, int expected) {
int[] value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value
+ " doesn't contain the expected value " + expected;
expectContains(reason, value, expected);
}
/**
* Check if the key is non-null, and the key value contains the expected element.
*
* @param characteristics {@link CameraCharacteristics} to check.
* @param key The {@link CameraCharacteristics} key to be checked.
* @param expected The expected element to be contained in the value for the given key.
*/
public void expectKeyValueContains(CameraCharacteristics characteristics,
CameraCharacteristics.Key<boolean[]> key, boolean expected) {
boolean[] value;
if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
return;
}
String reason = "Key " + key.getName() + " value " + value
+ " doesn't contain the expected value " + expected;
expectContains(reason, value, expected);
}
/**
* Check if the {@code values} array contains the expected element.
*
* @param reason reason to print for failure.
* @param values array to check for membership in.
* @param expected the value to check.
*/
public <T> void expectContains(String reason, T[] values, T expected) {
if (values == null) {
throw new NullPointerException();
}
checkThat(reason, expected, InMatcher.in(values));
}
public <T> void expectContains(T[] values, T expected) {
String reason = "Expected value " + expected
+ " is not contained in the given values " + values;
expectContains(reason, values, expected);
}
/**
* Specialize {@link InMatcher} class for integer primitive array.
*/
private static class IntInMatcher extends InMatcher<Integer> {
public IntInMatcher(int[] values) {
Preconditions.checkNotNull("values", values);
mValues = new ArrayList<>(values.length);
for (int i : values) {
mValues.add(i);
}
}
}
/**
* Check if the {@code values} array contains the expected element.
*
* <p>Specialized for primitive int arrays</p>
*
* @param reason reason to print for failure.
* @param values array to check for membership in.
* @param expected the value to check.
*/
public void expectContains(String reason, int[] values, int expected) {
if (values == null) {
throw new NullPointerException();
}
checkThat(reason, expected, new IntInMatcher(values));
}
public void expectContains(int[] values, int expected) {
String reason = "Expected value " + expected
+ " is not contained in the given values " + values;
expectContains(reason, values, expected);
}
/**
* Specialize {@link BooleanInMatcher} class for boolean primitive array.
*/
private static class BooleanInMatcher extends InMatcher<Boolean> {
public BooleanInMatcher(boolean[] values) {
Preconditions.checkNotNull("values", values);
mValues = new ArrayList<>(values.length);
for (boolean i : values) {
mValues.add(i);
}
}
}
/**
* Check if the {@code values} array contains the expected element.
*
* <p>Specialized for primitive boolean arrays</p>
*
* @param reason reason to print for failure.
* @param values array to check for membership in.
* @param expected the value to check.
*/
public void expectContains(String reason, boolean[] values, boolean expected) {
if (values == null) {
throw new NullPointerException();
}
checkThat(reason, expected, new BooleanInMatcher(values));
}
/**
* Check if the {@code values} array contains the expected element.
*
* <p>Specialized for primitive boolean arrays</p>
*
* @param values array to check for membership in.
* @param expected the value to check.
*/
public void expectContains(boolean[] values, boolean expected) {
String reason = "Expected value " + expected
+ " is not contained in the given values " + values;
expectContains(reason, values, expected);
}
/**
* Check if the element inside of the list are unique.
*
* @param msg The message to be logged
* @param list The list of values to be checked
*/
public <T> void expectValuesUnique(String msg, List<T> list) {
Set<T> sizeSet = new HashSet<T>(list);
expectTrue(msg + " each element must be distinct", sizeSet.size() == list.size());
}
}