/* * Copyright (c) 2007 Mockito contributors * This program is made available under the terms of the MIT License. */ //Class comes from Apache Commons Lang, added some tiny changes package org.mockito.internal.matchers.apachecommons; import org.junit.Test; import org.mockitoutil.TestBase; import java.math.BigDecimal; import java.util.Arrays; import static junit.framework.TestCase.*; /** * @author <a href="mailto:sdowney@panix.com">Steve Downey</a> * @author <a href="mailto:scolebourne@joda.org">Stephen Colebourne</a> * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a> * @author Maarten Coene * @version $Id: EqualsBuilderTest.java 611543 2008-01-13 07:00:22Z bayard $ */ public class EqualsBuilderTest extends TestBase { @Test public void testname() throws Exception { } static class TestObject { private int a; public TestObject() { } public TestObject(int a) { this.a = a; } public boolean equals(Object o) { if (o == null) { return false; } if (o == this) { return true; } if (o.getClass() != getClass()) { return false; } TestObject rhs = (TestObject) o; return (a == rhs.a); } public int hashCode() { return super.hashCode(); } public void setA(int a) { this.a = a; } public int getA() { return a; } } static class TestSubObject extends TestObject { private int b; public TestSubObject() { super(0); } public TestSubObject(int a, int b) { super(a); this.b = b; } public boolean equals(Object o) { if (o == null) { return false; } if (o == this) { return true; } if (o.getClass() != getClass()) { return false; } TestSubObject rhs = (TestSubObject) o; return super.equals(o) && (b == rhs.b); } public int hashCode() { return 1; } public void setB(int b) { this.b = b; } public int getB() { return b; } } static class TestEmptySubObject extends TestObject { public TestEmptySubObject(int a) { super(a); } } @SuppressWarnings("unused") static class TestTSubObject extends TestObject { private transient int t; public TestTSubObject(int a, int t) { super(a); this.t = t; } } @SuppressWarnings("unused") static class TestTTSubObject extends TestTSubObject { private transient int tt; public TestTTSubObject(int a, int t, int tt) { super(a, t); this.tt = tt; } } @SuppressWarnings("unused") static class TestTTLeafObject extends TestTTSubObject { private int leafValue; public TestTTLeafObject(int a, int t, int tt, int leafValue) { super(a, t, tt); this.leafValue = leafValue; } } static class TestTSubObject2 extends TestObject { private transient int t; public TestTSubObject2(int a, int t) { super(a); } public int getT() { return t; } public void setT(int t) { this.t = t; } } @Test public void testReflectionEquals() { TestObject o1 = new TestObject(4); TestObject o2 = new TestObject(5); assertTrue(EqualsBuilder.reflectionEquals(o1, o1)); assertTrue(!EqualsBuilder.reflectionEquals(o1, o2)); o2.setA(4); assertTrue(EqualsBuilder.reflectionEquals(o1, o2)); assertTrue(!EqualsBuilder.reflectionEquals(o1, this)); assertTrue(!EqualsBuilder.reflectionEquals(o1, null)); assertTrue(!EqualsBuilder.reflectionEquals(null, o2)); assertTrue(EqualsBuilder.reflectionEquals((Object) null, (Object) null)); } @Test public void testReflectionHierarchyEquals() { testReflectionHierarchyEquals(false); testReflectionHierarchyEquals(true); // Transients assertTrue(EqualsBuilder.reflectionEquals(new TestTTLeafObject(1, 2, 3, 4), new TestTTLeafObject(1, 2, 3, 4), true)); assertTrue(EqualsBuilder.reflectionEquals(new TestTTLeafObject(1, 2, 3, 4), new TestTTLeafObject(1, 2, 3, 4), false)); assertTrue(!EqualsBuilder.reflectionEquals(new TestTTLeafObject(1, 0, 0, 4), new TestTTLeafObject(1, 2, 3, 4), true)); assertTrue(!EqualsBuilder.reflectionEquals(new TestTTLeafObject(1, 2, 3, 4), new TestTTLeafObject(1, 2, 3, 0), true)); assertTrue(!EqualsBuilder.reflectionEquals(new TestTTLeafObject(0, 2, 3, 4), new TestTTLeafObject(1, 2, 3, 4), true)); } private void testReflectionHierarchyEquals(boolean testTransients) { TestObject to1 = new TestObject(4); TestObject to1Bis = new TestObject(4); TestObject to1Ter = new TestObject(4); TestObject to2 = new TestObject(5); TestEmptySubObject teso = new TestEmptySubObject(4); TestTSubObject ttso = new TestTSubObject(4, 1); TestTTSubObject tttso = new TestTTSubObject(4, 1, 2); TestTTLeafObject ttlo = new TestTTLeafObject(4, 1, 2, 3); TestSubObject tso1 = new TestSubObject(1, 4); TestSubObject tso1bis = new TestSubObject(1, 4); TestSubObject tso1ter = new TestSubObject(1, 4); TestSubObject tso2 = new TestSubObject(2, 5); testReflectionEqualsEquivalenceRelationship(to1, to1Bis, to1Ter, to2, new TestObject(), testTransients); testReflectionEqualsEquivalenceRelationship(tso1, tso1bis, tso1ter, tso2, new TestSubObject(), testTransients); // More sanity checks: // same values assertTrue(EqualsBuilder.reflectionEquals(ttlo, ttlo, testTransients)); assertTrue(EqualsBuilder.reflectionEquals(new TestSubObject(1, 10), new TestSubObject(1, 10), testTransients)); // same super values, diff sub values assertTrue(!EqualsBuilder.reflectionEquals(new TestSubObject(1, 10), new TestSubObject(1, 11), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestSubObject(1, 11), new TestSubObject(1, 10), testTransients)); // diff super values, same sub values assertTrue(!EqualsBuilder.reflectionEquals(new TestSubObject(0, 10), new TestSubObject(1, 10), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestSubObject(1, 10), new TestSubObject(0, 10), testTransients)); // mix super and sub types: equals assertTrue(EqualsBuilder.reflectionEquals(to1, teso, testTransients)); assertTrue(EqualsBuilder.reflectionEquals(teso, to1, testTransients)); assertTrue(EqualsBuilder.reflectionEquals(to1, ttso, false)); // Force testTransients = false for this assert assertTrue(EqualsBuilder.reflectionEquals(ttso, to1, false)); // Force testTransients = false for this assert assertTrue(EqualsBuilder.reflectionEquals(to1, tttso, false)); // Force testTransients = false for this assert assertTrue(EqualsBuilder.reflectionEquals(tttso, to1, false)); // Force testTransients = false for this assert assertTrue(EqualsBuilder.reflectionEquals(ttso, tttso, false)); // Force testTransients = false for this assert assertTrue(EqualsBuilder.reflectionEquals(tttso, ttso, false)); // Force testTransients = false for this assert // mix super and sub types: NOT equals assertTrue(!EqualsBuilder.reflectionEquals(new TestObject(0), new TestEmptySubObject(1), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestEmptySubObject(1), new TestObject(0), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestObject(0), new TestTSubObject(1, 1), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestTSubObject(1, 1), new TestObject(0), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestObject(1), new TestSubObject(0, 10), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(new TestSubObject(0, 10), new TestObject(1), testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(to1, ttlo)); assertTrue(!EqualsBuilder.reflectionEquals(tso1, this)); } /** * Equivalence relationship tests inspired by "Effective Java": * <ul> * <li>reflection</li> * <li>symmetry</li> * <li>transitive</li> * <li>consistency</li> * <li>non-null reference</li> * </ul> * @param to a TestObject * @param toBis a TestObject, equal to to and toTer * @param toTer Left hand side, equal to to and toBis * @param to2 a different TestObject * @param oToChange a TestObject that will be changed */ private void testReflectionEqualsEquivalenceRelationship( TestObject to, TestObject toBis, TestObject toTer, TestObject to2, TestObject oToChange, boolean testTransients) { // reflection test assertTrue(EqualsBuilder.reflectionEquals(to, to, testTransients)); assertTrue(EqualsBuilder.reflectionEquals(to2, to2, testTransients)); // symmetry test assertTrue(EqualsBuilder.reflectionEquals(to, toBis, testTransients) && EqualsBuilder.reflectionEquals(toBis, to, testTransients)); // transitive test assertTrue( EqualsBuilder.reflectionEquals(to, toBis, testTransients) && EqualsBuilder.reflectionEquals(toBis, toTer, testTransients) && EqualsBuilder.reflectionEquals(to, toTer, testTransients)); // consistency test oToChange.setA(to.getA()); if (oToChange instanceof TestSubObject) { ((TestSubObject) oToChange).setB(((TestSubObject) to).getB()); } assertTrue(EqualsBuilder.reflectionEquals(oToChange, to, testTransients)); assertTrue(EqualsBuilder.reflectionEquals(oToChange, to, testTransients)); oToChange.setA(to.getA() + 1); if (oToChange instanceof TestSubObject) { ((TestSubObject) oToChange).setB(((TestSubObject) to).getB() + 1); } assertTrue(!EqualsBuilder.reflectionEquals(oToChange, to, testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(oToChange, to, testTransients)); // non-null reference test assertTrue(!EqualsBuilder.reflectionEquals(to, null, testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(to2, null, testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(null, to, testTransients)); assertTrue(!EqualsBuilder.reflectionEquals(null, to2, testTransients)); assertTrue(EqualsBuilder.reflectionEquals((Object) null, (Object) null, testTransients)); } @Test public void testSuper() { TestObject o1 = new TestObject(4); TestObject o2 = new TestObject(5); assertEquals(true, new EqualsBuilder().appendSuper(true).append(o1, o1).isEquals()); assertEquals(false, new EqualsBuilder().appendSuper(false).append(o1, o1).isEquals()); assertEquals(false, new EqualsBuilder().appendSuper(true).append(o1, o2).isEquals()); assertEquals(false, new EqualsBuilder().appendSuper(false).append(o1, o2).isEquals()); } @Test public void testObject() { TestObject o1 = new TestObject(4); TestObject o2 = new TestObject(5); assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); o2.setA(4); assertTrue(new EqualsBuilder().append(o1, o2).isEquals()); assertTrue(!new EqualsBuilder().append(o1, this).isEquals()); assertTrue(!new EqualsBuilder().append(o1, null).isEquals()); assertTrue(!new EqualsBuilder().append(null, o2).isEquals()); assertTrue(new EqualsBuilder().append((Object) null, (Object) null).isEquals()); } @Test public void testLong() { long o1 = 1L; long o2 = 2L; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testInt() { int o1 = 1; int o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testShort() { short o1 = 1; short o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testChar() { char o1 = 1; char o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testByte() { byte o1 = 1; byte o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testDouble() { double o1 = 1; double o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); assertTrue(!new EqualsBuilder().append(o1, Double.NaN).isEquals()); assertTrue(new EqualsBuilder().append(Double.NaN, Double.NaN).isEquals()); assertTrue(new EqualsBuilder().append(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY).isEquals()); } @Test public void testFloat() { float o1 = 1; float o2 = 2; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); assertTrue(!new EqualsBuilder().append(o1, Float.NaN).isEquals()); assertTrue(new EqualsBuilder().append(Float.NaN, Float.NaN).isEquals()); assertTrue(new EqualsBuilder().append(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY).isEquals()); } // https://issues.apache.org/jira/browse/LANG-393 @Test public void testBigDecimal() { BigDecimal o1 = new BigDecimal("2.0"); BigDecimal o2 = new BigDecimal("2.00"); assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testAccessors() { EqualsBuilder equalsBuilder = new EqualsBuilder(); assertTrue(equalsBuilder.isEquals()); equalsBuilder.setEquals(true); assertTrue(equalsBuilder.isEquals()); equalsBuilder.setEquals(false); assertFalse(equalsBuilder.isEquals()); } @Test public void testBoolean() { boolean o1 = true; boolean o2 = false; assertTrue(new EqualsBuilder().append(o1, o1).isEquals()); assertTrue(!new EqualsBuilder().append(o1, o2).isEquals()); } @Test public void testObjectArray() { TestObject[] obj1 = new TestObject[3]; obj1[0] = new TestObject(4); obj1[1] = new TestObject(5); obj1[2] = null; TestObject[] obj2 = new TestObject[3]; obj2[0] = new TestObject(4); obj2[1] = new TestObject(5); obj2[2] = null; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj2, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1].setA(6); assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1].setA(5); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[2] = obj1[1]; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[2] = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testLongArray() { long[] obj1 = new long[2]; obj1[0] = 5L; obj1[1] = 6L; long[] obj2 = new long[2]; obj2[0] = 5L; obj2[1] = 6L; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testIntArray() { int[] obj1 = new int[2]; obj1[0] = 5; obj1[1] = 6; int[] obj2 = new int[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testShortArray() { short[] obj1 = new short[2]; obj1[0] = 5; obj1[1] = 6; short[] obj2 = new short[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testCharArray() { char[] obj1 = new char[2]; obj1[0] = 5; obj1[1] = 6; char[] obj2 = new char[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testByteArray() { byte[] obj1 = new byte[2]; obj1[0] = 5; obj1[1] = 6; byte[] obj2 = new byte[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testDoubleArray() { double[] obj1 = new double[2]; obj1[0] = 5; obj1[1] = 6; double[] obj2 = new double[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testFloatArray() { float[] obj1 = new float[2]; obj1[0] = 5; obj1[1] = 6; float[] obj2 = new float[2]; obj2[0] = 5; obj2[1] = 6; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testBooleanArray() { boolean[] obj1 = new boolean[2]; obj1[0] = true; obj1[1] = false; boolean[] obj2 = new boolean[2]; obj2[0] = true; obj2[1] = false; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); obj1[1] = true; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj2 = null; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); obj1 = null; assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testMultiLongArray() { long[][] array1 = new long[2][2]; long[][] array2 = new long[2][2]; for (int i = 0; i < array1.length; ++i) { for (int j = 0; j < array1[0].length; j++) { array1[i][j] = (i + 1) * (j + 1); array2[i][j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiIntArray() { int[][] array1 = new int[2][2]; int[][] array2 = new int[2][2]; for (int i = 0; i < array1.length; ++i) { for (int j = 0; j < array1[0].length; j++) { array1[i][j] = (i + 1) * (j + 1); array2[i][j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiShortArray() { short[][] array1 = new short[2][2]; short[][] array2 = new short[2][2]; for (short i = 0; i < array1.length; ++i) { for (short j = 0; j < array1[0].length; j++) { array1[i][j] = i; array2[i][j] = i; } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiCharArray() { char[][] array1 = new char[2][2]; char[][] array2 = new char[2][2]; for (char i = 0; i < array1.length; ++i) { for (char j = 0; j < array1[0].length; j++) { array1[i][j] = i; array2[i][j] = i; } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiByteArray() { byte[][] array1 = new byte[2][2]; byte[][] array2 = new byte[2][2]; for (byte i = 0; i < array1.length; ++i) { for (byte j = 0; j < array1[0].length; j++) { array1[i][j] = i; array2[i][j] = i; } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiFloatArray() { float[][] array1 = new float[2][2]; float[][] array2 = new float[2][2]; for (int i = 0; i < array1.length; ++i) { for (int j = 0; j < array1[0].length; j++) { array1[i][j] = (i + 1) * (j + 1); array2[i][j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiDoubleArray() { double[][] array1 = new double[2][2]; double[][] array2 = new double[2][2]; for (int i = 0; i < array1.length; ++i) { for (int j = 0; j < array1[0].length; j++) { array1[i][j] = (i + 1) * (j + 1); array2[i][j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMultiBooleanArray() { boolean[][] array1 = new boolean[2][2]; boolean[][] array2 = new boolean[2][2]; for (int i = 0; i < array1.length; ++i) { for (int j = 0; j < array1[0].length; j++) { array1[i][j] = (i == 1) || (j == 1); array2[i][j] = (i == 1) || (j == 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = false; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); // compare 1 dim to 2. boolean[] array3 = new boolean[]{true, true}; assertFalse(new EqualsBuilder().append(array1, array3).isEquals()); assertFalse(new EqualsBuilder().append(array3, array1).isEquals()); assertFalse(new EqualsBuilder().append(array2, array3).isEquals()); assertFalse(new EqualsBuilder().append(array3, array2).isEquals()); } @Test public void testRaggedArray() { long[][] array1 = new long[2][]; long[][] array2 = new long[2][]; for (int i = 0; i < array1.length; ++i) { array1[i] = new long[2]; array2[i] = new long[2]; for (int j = 0; j < array1[i].length; ++j) { array1[i][j] = (i + 1) * (j + 1); array2[i][j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); array1[1][1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testMixedArray() { Object[] array1 = new Object[2]; Object[] array2 = new Object[2]; for (int i = 0; i < array1.length; ++i) { array1[i] = new long[2]; array2[i] = new long[2]; for (int j = 0; j < 2; ++j) { ((long[]) array1[i])[j] = (i + 1) * (j + 1); ((long[]) array2[i])[j] = (i + 1) * (j + 1); } } assertTrue(new EqualsBuilder().append(array1, array1).isEquals()); assertTrue(new EqualsBuilder().append(array1, array2).isEquals()); ((long[]) array1[1])[1] = 0; assertTrue(!new EqualsBuilder().append(array1, array2).isEquals()); } @Test public void testObjectArrayHiddenByObject() { TestObject[] array1 = new TestObject[2]; array1[0] = new TestObject(4); array1[1] = new TestObject(5); TestObject[] array2 = new TestObject[2]; array2[0] = new TestObject(4); array2[1] = new TestObject(5); Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1].setA(6); assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testLongArrayHiddenByObject() { long[] array1 = new long[2]; array1[0] = 5L; array1[1] = 6L; long[] array2 = new long[2]; array2[0] = 5L; array2[1] = 6L; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testIntArrayHiddenByObject() { int[] array1 = new int[2]; array1[0] = 5; array1[1] = 6; int[] array2 = new int[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testShortArrayHiddenByObject() { short[] array1 = new short[2]; array1[0] = 5; array1[1] = 6; short[] array2 = new short[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testCharArrayHiddenByObject() { char[] array1 = new char[2]; array1[0] = 5; array1[1] = 6; char[] array2 = new char[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testByteArrayHiddenByObject() { byte[] array1 = new byte[2]; array1[0] = 5; array1[1] = 6; byte[] array2 = new byte[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testDoubleArrayHiddenByObject() { double[] array1 = new double[2]; array1[0] = 5; array1[1] = 6; double[] array2 = new double[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testFloatArrayHiddenByObject() { float[] array1 = new float[2]; array1[0] = 5; array1[1] = 6; float[] array2 = new float[2]; array2[0] = 5; array2[1] = 6; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = 7; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } @Test public void testBooleanArrayHiddenByObject() { boolean[] array1 = new boolean[2]; array1[0] = true; array1[1] = false; boolean[] array2 = new boolean[2]; array2[0] = true; array2[1] = false; Object obj1 = array1; Object obj2 = array2; assertTrue(new EqualsBuilder().append(obj1, obj1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array1).isEquals()); assertTrue(new EqualsBuilder().append(obj1, obj2).isEquals()); assertTrue(new EqualsBuilder().append(obj1, array2).isEquals()); array1[1] = true; assertTrue(!new EqualsBuilder().append(obj1, obj2).isEquals()); } public static class TestACanEqualB { private int a; public TestACanEqualB(int a) { this.a = a; } public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof TestACanEqualB) { return this.a == ((TestACanEqualB) o).getA(); } if (o instanceof TestBCanEqualA) { return this.a == ((TestBCanEqualA) o).getB(); } return false; } public int hashCode() { return 1; } public int getA() { return this.a; } } public static class TestBCanEqualA { private int b; public TestBCanEqualA(int b) { this.b = b; } public boolean equals(Object o) { if (o == this) { return true; } if (o instanceof TestACanEqualB) { return this.b == ((TestACanEqualB) o).getA(); } if (o instanceof TestBCanEqualA) { return this.b == ((TestBCanEqualA) o).getB(); } return false; } public int hashCode() { return 1; } public int getB() { return this.b; } } /** * Tests two instances of classes that can be equal and that are not "related". The two classes are not subclasses * of each other and do not share a parent aside from Object. * See http://issues.apache.org/bugzilla/show_bug.cgi?id=33069 */ @Test public void testUnrelatedClasses() { Object[] x = new Object[]{new TestACanEqualB(1)}; Object[] y = new Object[]{new TestBCanEqualA(1)}; // sanity checks: assertTrue(Arrays.equals(x, x)); assertTrue(Arrays.equals(y, y)); assertTrue(Arrays.equals(x, y)); assertTrue(Arrays.equals(y, x)); // real tests: assertTrue(x[0].equals(x[0])); assertTrue(y[0].equals(y[0])); assertTrue(x[0].equals(y[0])); assertTrue(y[0].equals(x[0])); assertTrue(new EqualsBuilder().append(x, x).isEquals()); assertTrue(new EqualsBuilder().append(y, y).isEquals()); assertTrue(new EqualsBuilder().append(x, y).isEquals()); assertTrue(new EqualsBuilder().append(y, x).isEquals()); } /** * Test from http://issues.apache.org/bugzilla/show_bug.cgi?id=33067 */ @Test public void testNpeForNullElement() { Object[] x1 = new Object[] { new Integer(1), null, new Integer(3) }; Object[] x2 = new Object[] { new Integer(1), new Integer(2), new Integer(3) }; // causes an NPE in 2.0 according to: // http://issues.apache.org/bugzilla/show_bug.cgi?id=33067 new EqualsBuilder().append(x1, x2); } @Test public void testReflectionEqualsExcludeFields() throws Exception { TestObjectWithMultipleFields x1 = new TestObjectWithMultipleFields(1, 2, 3); TestObjectWithMultipleFields x2 = new TestObjectWithMultipleFields(1, 3, 4); // not equal when including all fields assertTrue(!EqualsBuilder.reflectionEquals(x1, x2)); // doesn't barf on null, empty array, or non-existent field, but still tests as not equal assertTrue(!EqualsBuilder.reflectionEquals(x1, x2, (String[]) null)); assertTrue(!EqualsBuilder.reflectionEquals(x1, x2, new String[] {})); assertTrue(!EqualsBuilder.reflectionEquals(x1, x2, new String[] {"xxx"})); // not equal if only one of the differing fields excluded assertTrue(!EqualsBuilder.reflectionEquals(x1, x2, new String[] {"two"})); assertTrue(!EqualsBuilder.reflectionEquals(x1, x2, new String[] {"three"})); // equal if both differing fields excluded assertTrue(EqualsBuilder.reflectionEquals(x1, x2, new String[] {"two", "three"})); // still equal as long as both differing fields are among excluded assertTrue(EqualsBuilder.reflectionEquals(x1, x2, new String[] {"one", "two", "three"})); assertTrue(EqualsBuilder.reflectionEquals(x1, x2, new String[] {"one", "two", "three", "xxx"})); } @SuppressWarnings("unused") static class TestObjectWithMultipleFields { private TestObject one; private TestObject two; private TestObject three; public TestObjectWithMultipleFields(int one, int two, int three) { this.one = new TestObject(one); this.two = new TestObject(two); this.three = new TestObject(three); } } }