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