aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/junit/internal/ComparisonCriteria.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/junit/internal/ComparisonCriteria.java')
-rw-r--r--src/main/java/org/junit/internal/ComparisonCriteria.java89
1 files changed, 69 insertions, 20 deletions
diff --git a/src/main/java/org/junit/internal/ComparisonCriteria.java b/src/main/java/org/junit/internal/ComparisonCriteria.java
index e6d49a4..ed1c674 100644
--- a/src/main/java/org/junit/internal/ComparisonCriteria.java
+++ b/src/main/java/org/junit/internal/ComparisonCriteria.java
@@ -25,6 +25,11 @@ public abstract class ComparisonCriteria {
*/
public void arrayEquals(String message, Object expecteds, Object actuals)
throws ArrayComparisonFailure {
+ arrayEquals(message, expecteds, actuals, true);
+ }
+
+ private void arrayEquals(String message, Object expecteds, Object actuals, boolean outer)
+ throws ArrayComparisonFailure {
if (expecteds == actuals
|| Arrays.deepEquals(new Object[] {expecteds}, new Object[] {actuals})) {
// The reflection-based loop below is potentially very slow, especially for primitive
@@ -34,19 +39,37 @@ public abstract class ComparisonCriteria {
}
String header = message == null ? "" : message + ": ";
- int expectedsLength = assertArraysAreSameLength(expecteds,
- actuals, header);
+ // Only include the user-provided message in the outer exception.
+ String exceptionMessage = outer ? header : "";
+
+ if (expecteds == null) {
+ Assert.fail(exceptionMessage + "expected array was null");
+ }
+ if (actuals == null) {
+ Assert.fail(exceptionMessage + "actual array was null");
+ }
+
+ int actualsLength = Array.getLength(actuals);
+ int expectedsLength = Array.getLength(expecteds);
+ if (actualsLength != expectedsLength) {
+ header += "array lengths differed, expected.length="
+ + expectedsLength + " actual.length=" + actualsLength + "; ";
+ }
+ int prefixLength = Math.min(actualsLength, expectedsLength);
- for (int i = 0; i < expectedsLength; i++) {
+ for (int i = 0; i < prefixLength; i++) {
Object expected = Array.get(expecteds, i);
Object actual = Array.get(actuals, i);
if (isArray(expected) && isArray(actual)) {
try {
- arrayEquals(message, expected, actual);
+ arrayEquals(message, expected, actual, false);
} catch (ArrayComparisonFailure e) {
e.addDimension(i);
throw e;
+ } catch (AssertionError e) {
+ // Array lengths differed.
+ throw new ArrayComparisonFailure(header, e, i);
}
} else {
try {
@@ -56,27 +79,53 @@ public abstract class ComparisonCriteria {
}
}
}
- }
- private boolean isArray(Object expected) {
- return expected != null && expected.getClass().isArray();
+ if (actualsLength != expectedsLength) {
+ Object expected = getToStringableArrayElement(expecteds, expectedsLength, prefixLength);
+ Object actual = getToStringableArrayElement(actuals, actualsLength, prefixLength);
+ try {
+ Assert.assertEquals(expected, actual);
+ } catch (AssertionError e) {
+ throw new ArrayComparisonFailure(header, e, prefixLength);
+ }
+ }
}
- private int assertArraysAreSameLength(Object expecteds,
- Object actuals, String header) {
- if (expecteds == null) {
- Assert.fail(header + "expected array was null");
- }
- if (actuals == null) {
- Assert.fail(header + "actual array was null");
+ private static final Object END_OF_ARRAY_SENTINEL = objectWithToString("end of array");
+
+ private Object getToStringableArrayElement(Object array, int length, int index) {
+ if (index < length) {
+ Object element = Array.get(array, index);
+ if (isArray(element)) {
+ return objectWithToString(componentTypeName(element.getClass()) + "[" + Array.getLength(element) + "]");
+ } else {
+ return element;
+ }
+ } else {
+ return END_OF_ARRAY_SENTINEL;
}
- int actualsLength = Array.getLength(actuals);
- int expectedsLength = Array.getLength(expecteds);
- if (actualsLength != expectedsLength) {
- Assert.fail(header + "array lengths differed, expected.length="
- + expectedsLength + " actual.length=" + actualsLength);
+ }
+
+ private static Object objectWithToString(final String string) {
+ return new Object() {
+ @Override
+ public String toString() {
+ return string;
+ }
+ };
+ }
+
+ private String componentTypeName(Class<?> arrayClass) {
+ Class<?> componentType = arrayClass.getComponentType();
+ if (componentType.isArray()) {
+ return componentTypeName(componentType) + "[]";
+ } else {
+ return componentType.getName();
}
- return expectedsLength;
+ }
+
+ private boolean isArray(Object expected) {
+ return expected != null && expected.getClass().isArray();
}
protected abstract void assertElementsEqual(Object expected, Object actual);