1b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpackage org.junit.internal;
2b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
3b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport java.lang.reflect.Array;
4b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
5b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotimport org.junit.Assert;
6b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
7b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot/**
8b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * Defines criteria for finding two items "equal enough". Concrete subclasses
9b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot * may demand exact equality, or, for example, equality within a given delta.
10b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot */
11b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabotpublic abstract class ComparisonCriteria {
12b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	/**
13b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * Asserts that two arrays are equal, according to the criteria defined by
14b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * the concrete subclass. If they are not, an {@link AssertionError} is
15b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * thrown with the given message. If <code>expecteds</code> and
16b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * <code>actuals</code> are <code>null</code>, they are considered equal.
17b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *
18b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * @param message
19b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            the identifying message for the {@link AssertionError} (
20b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            <code>null</code> okay)
21b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * @param expecteds
22b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            Object array or array of arrays (multi-dimensional array) with
23b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            expected values.
24b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 * @param actuals
25b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            Object array or array of arrays (multi-dimensional array) with
26b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 *            actual values
27b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	 */
28b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	public void arrayEquals(String message, Object expecteds, Object actuals)
29b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			throws ArrayComparisonFailure {
30b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		if (expecteds == actuals)
31b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			return;
32b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		String header= message == null ? "" : message + ": ";
33b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
34b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		int expectedsLength= assertArraysAreSameLength(expecteds,
35b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				actuals, header);
36b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
37b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		for (int i= 0; i < expectedsLength; i++) {
38b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Object expected= Array.get(expecteds, i);
39b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Object actual= Array.get(actuals, i);
40b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
41b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			if (isArray(expected) && isArray(actual)) {
42b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				try {
43b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					arrayEquals(message, expected, actual);
44b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				} catch (ArrayComparisonFailure e) {
45b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					e.addDimension(i);
46b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					throw e;
47b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				}
48b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			} else
49b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				try {
50b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					assertElementsEqual(expected, actual);
51b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				} catch (AssertionError e) {
52b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					throw new ArrayComparisonFailure(header, e, i);
53b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot				}
54b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		}
55b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	}
56b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
57b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private boolean isArray(Object expected) {
58b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		return expected != null && expected.getClass().isArray();
59b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	}
60b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
61b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	private int assertArraysAreSameLength(Object expecteds,
62b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Object actuals, String header) {
63b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		if (expecteds == null)
64b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Assert.fail(header + "expected array was null");
65b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		if (actuals == null)
66b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Assert.fail(header + "actual array was null");
67b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		int actualsLength= Array.getLength(actuals);
68b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		int expectedsLength= Array.getLength(expecteds);
69b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		if (actualsLength != expectedsLength)
70b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot			Assert.fail(header + "array lengths differed, expected.length="
71b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot					+ expectedsLength + " actual.length=" + actualsLength);
72b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot		return expectedsLength;
73b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	}
74b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot
75b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot	protected abstract void assertElementsEqual(Object expected, Object actual);
76b3823db9f1192d8c81345740b3e65bd6738ba55bBrett Chabot}
77