Skip to content

Commit

Permalink
Produce a more legible failure message when multidimensional arrays a…
Browse files Browse the repository at this point in the history
…re of different lengths

Closes #1300
  • Loading branch information
tomwhoiscontrary authored and kcooney committed May 29, 2016
1 parent 892f798 commit b2d7fce
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 16 deletions.
40 changes: 31 additions & 9 deletions src/main/java/org/junit/internal/ComparisonCriteria.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ private void arrayEquals(String message, Object expecteds, Object actuals, boole
}

if (actualsLength != expectedsLength) {
Object expected = getArrayElementOrSentinel(expecteds, expectedsLength, prefixLength);
Object actual = getArrayElementOrSentinel(actuals, actualsLength, prefixLength);
Object expected = getToStringableArrayElement(expecteds, expectedsLength, prefixLength);
Object actual = getToStringableArrayElement(actuals, actualsLength, prefixLength);
try {
Assert.assertEquals(expected, actual);
} catch (AssertionError e) {
Expand All @@ -91,15 +91,37 @@ private void arrayEquals(String message, Object expecteds, Object actuals, boole
}
}

private static final Object END_OF_ARRAY_SENTINEL = new Object() {
@Override
public String toString() {
return "end of array";
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;
}
};
}

private Object getArrayElementOrSentinel(Object array, int length, int index) {
return index < length ? Array.get(array, index) : END_OF_ARRAY_SENTINEL;
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();
}
}

private boolean isArray(Object expected) {
Expand Down
36 changes: 29 additions & 7 deletions src/test/java/org/junit/tests/assertion/AssertionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,49 @@ public void multiDimensionalArraysAreNotEqualNoMessage() {

@Test
public void twoDimensionalArraysDifferentOuterLengthNotEqual() {
Object[] extraArray = {true};
assertArrayEqualsFailure(
"not equal",
new Object[][]{extraArray, {}},
new Object[][]{{true}, {}},
new Object[][]{{}},
"not equal: array lengths differed, expected.length=1 actual.length=0; arrays first differed at element [0][0]; expected:<true> but was:<end of array>");
assertArrayEqualsFailure(
"not equal",
new Object[][]{{}, extraArray},
new Object[][]{{}, {true}},
new Object[][]{{}},
"not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<" + extraArray.toString() + "> but was:<end of array>");
"not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<java.lang.Object[1]> but was:<end of array>");
assertArrayEqualsFailure(
"not equal",
new Object[][]{{}},
new Object[][]{extraArray, {}},
new Object[][]{{true}, {}},
"not equal: array lengths differed, expected.length=0 actual.length=1; arrays first differed at element [0][0]; expected:<end of array> but was:<true>");
assertArrayEqualsFailure(
"not equal",
new Object[][]{{}},
new Object[][]{{}, extraArray},
"not equal: array lengths differed, expected.length=1 actual.length=2; arrays first differed at element [1]; expected:<end of array> but was:<" + extraArray.toString() + ">");
new Object[][]{{}, {true}},
"not equal: array lengths differed, expected.length=1 actual.length=2; arrays first differed at element [1]; expected:<end of array> but was:<java.lang.Object[1]>");
}

@Test
public void primitiveArraysConvertedToStringCorrectly() {
assertArrayEqualsFailure(
"not equal",
new boolean[][]{{}, {true}},
new boolean[][]{{}},
"not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<boolean[1]> but was:<end of array>");
assertArrayEqualsFailure(
"not equal",
new int[][]{{}, {23}},
new int[][]{{}},
"not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<int[1]> but was:<end of array>");
}

@Test
public void twoDimensionalArraysConvertedToStringCorrectly() {
assertArrayEqualsFailure(
"not equal",
new Object[][][]{{}, {{true}}},
new Object[][][]{{}},
"not equal: array lengths differed, expected.length=2 actual.length=1; arrays first differed at element [1]; expected:<java.lang.Object[][1]> but was:<end of array>");
}

@Test
Expand Down

0 comments on commit b2d7fce

Please sign in to comment.