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