001package org.junit.internal; 002 003import java.lang.reflect.Array; 004import java.util.Arrays; 005 006import org.junit.Assert; 007 008/** 009 * Defines criteria for finding two items "equal enough". Concrete subclasses 010 * may demand exact equality, or, for example, equality within a given delta. 011 */ 012public abstract class ComparisonCriteria { 013 /** 014 * Asserts that two arrays are equal, according to the criteria defined by 015 * the concrete subclass. If they are not, an {@link AssertionError} is 016 * thrown with the given message. If <code>expecteds</code> and 017 * <code>actuals</code> are <code>null</code>, they are considered equal. 018 * 019 * @param message the identifying message for the {@link AssertionError} ( 020 * <code>null</code> okay) 021 * @param expecteds Object array or array of arrays (multi-dimensional array) with 022 * expected values. 023 * @param actuals Object array or array of arrays (multi-dimensional array) with 024 * actual values 025 */ 026 public void arrayEquals(String message, Object expecteds, Object actuals) 027 throws ArrayComparisonFailure { 028 if (expecteds == actuals 029 || Arrays.deepEquals(new Object[] {expecteds}, new Object[] {actuals})) { 030 // The reflection-based loop below is potentially very slow, especially for primitive 031 // arrays. The deepEquals check allows us to circumvent it in the usual case where 032 // the arrays are exactly equal. 033 return; 034 } 035 String header = message == null ? "" : message + ": "; 036 037 int expectedsLength = assertArraysAreSameLength(expecteds, 038 actuals, header); 039 040 for (int i = 0; i < expectedsLength; i++) { 041 Object expected = Array.get(expecteds, i); 042 Object actual = Array.get(actuals, i); 043 044 if (isArray(expected) && isArray(actual)) { 045 try { 046 arrayEquals(message, expected, actual); 047 } catch (ArrayComparisonFailure e) { 048 e.addDimension(i); 049 throw e; 050 } 051 } else { 052 try { 053 assertElementsEqual(expected, actual); 054 } catch (AssertionError e) { 055 throw new ArrayComparisonFailure(header, e, i); 056 } 057 } 058 } 059 } 060 061 private boolean isArray(Object expected) { 062 return expected != null && expected.getClass().isArray(); 063 } 064 065 private int assertArraysAreSameLength(Object expecteds, 066 Object actuals, String header) { 067 if (expecteds == null) { 068 Assert.fail(header + "expected array was null"); 069 } 070 if (actuals == null) { 071 Assert.fail(header + "actual array was null"); 072 } 073 int actualsLength = Array.getLength(actuals); 074 int expectedsLength = Array.getLength(expecteds); 075 if (actualsLength != expectedsLength) { 076 Assert.fail(header + "array lengths differed, expected.length=" 077 + expectedsLength + " actual.length=" + actualsLength); 078 } 079 return expectedsLength; 080 } 081 082 protected abstract void assertElementsEqual(Object expected, Object actual); 083}