diff --git a/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java b/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java index d2ae2f207..8741f2104 100644 --- a/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java +++ b/src/test/java/org/apache/commons/lang3/builder/HashCodeBuilderTest.java @@ -53,26 +53,6 @@ public class HashCodeBuilderTest extends AbstractLangTest { } } - @Test - public void testConstructorExZero() { - assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(0, 0)); - } - - @Test - public void testConstructorExEvenFirst() { - assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(2, 3)); - } - - @Test - public void testConstructorExEvenSecond() { - assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(3, 2)); - } - - @Test - public void testConstructorExEvenNegative() { - assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(-2, -2)); - } - static class TestObject { private int a; @@ -92,6 +72,10 @@ public class HashCodeBuilderTest extends AbstractLangTest { return a == rhs.a; } + public int getA() { + return a; + } + @Override public int hashCode() { return a; @@ -100,464 +84,6 @@ public class HashCodeBuilderTest extends AbstractLangTest { public void setA(final int a) { this.a = a; } - - public int getA() { - return a; - } - } - - static class TestSubObject extends TestObject { - private int b; - - @SuppressWarnings("unused") - private transient int t; - - TestSubObject() { - super(0); - } - - TestSubObject(final int a, final int b, final int t) { - super(a); - this.b = b; - this.t = t; - } - - @Override - public boolean equals(final Object o) { - if (o == this) { - return true; - } - if (!(o instanceof TestSubObject)) { - return false; - } - final TestSubObject rhs = (TestSubObject) o; - return super.equals(o) && b == rhs.b; - } - - @Override - public int hashCode() { - return b*17 + super.hashCode(); - } - - } - - @Test - public void testReflectionHashCode() { - assertEquals(17 * 37, HashCodeBuilder.reflectionHashCode(new TestObject(0))); - assertEquals(17 * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestObject(123456))); - } - - @Test - public void testReflectionHierarchyHashCode() { - assertEquals(17 * 37 * 37, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0))); - assertEquals(17 * 37 * 37 * 37, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0), true)); - assertEquals((17 * 37 + 7890) * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject(123456, 7890, - 0))); - assertEquals(((17 * 37 + 7890) * 37 + 0) * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject( - 123456, 7890, 0), true)); - } - - @Test - public void testReflectionHierarchyHashCodeEx1() { - assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(0, 0, new TestSubObject(0, 0, 0), true)); - } - - @Test - public void testReflectionHierarchyHashCodeEx2() { - assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(2, 2, new TestSubObject(0, 0, 0), true)); - } - - @Test - public void testReflectionHashCodeEx1() { - assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(0, 0, new TestObject(0), true)); - } - - @Test - public void testReflectionHashCodeEx2() { - assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(2, 2, new TestObject(0), true)); - } - - @Test - public void testReflectionHashCodeEx3() { - assertThrows(NullPointerException.class, () -> HashCodeBuilder.reflectionHashCode(13, 19, null, true)); - } - - @Test - public void testSuper() { - final Object obj = new Object(); - assertEquals(17 * 37 + 19 * 41 + obj.hashCode(), new HashCodeBuilder(17, 37).appendSuper( - new HashCodeBuilder(19, 41).append(obj).toHashCode()).toHashCode()); - } - - @Test - public void testObject() { - Object obj = null; - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj = new Object(); - assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testObjectBuild() { - Object obj = null; - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).build().intValue()); - obj = new Object(); - assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).build().intValue()); - } - - @Test - public void testLong() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0L).toHashCode()); - assertEquals(17 * 37 + (int) (123456789L ^ 123456789L >> 32), new HashCodeBuilder(17, 37).append( - 123456789L).toHashCode()); - } - - @Test - public void testInt() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0).toHashCode()); - assertEquals(17 * 37 + 123456, new HashCodeBuilder(17, 37).append(123456).toHashCode()); - } - - @Test - public void testShort() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((short) 0).toHashCode()); - assertEquals(17 * 37 + 12345, new HashCodeBuilder(17, 37).append((short) 12345).toHashCode()); - } - - @Test - public void testChar() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((char) 0).toHashCode()); - assertEquals(17 * 37 + 1234, new HashCodeBuilder(17, 37).append((char) 1234).toHashCode()); - } - - @Test - public void testByte() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((byte) 0).toHashCode()); - assertEquals(17 * 37 + 123, new HashCodeBuilder(17, 37).append((byte) 123).toHashCode()); - } - - @Test - public void testDouble() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0d).toHashCode()); - final double d = 1234567.89; - final long l = Double.doubleToLongBits(d); - assertEquals(17 * 37 + (int) (l ^ l >> 32), new HashCodeBuilder(17, 37).append(d).toHashCode()); - } - - @Test - public void testFloat() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0f).toHashCode()); - final float f = 1234.89f; - final int i = Float.floatToIntBits(f); - assertEquals(17 * 37 + i, new HashCodeBuilder(17, 37).append(f).toHashCode()); - } - - @Test - public void testBoolean() { - assertEquals(17 * 37 + 0, new HashCodeBuilder(17, 37).append(true).toHashCode()); - assertEquals(17 * 37 + 1, new HashCodeBuilder(17, 37).append(false).toHashCode()); - } - - @Test - public void testObjectArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((Object[]) null).toHashCode()); - final Object[] obj = new Object[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = new Object(); - assertEquals((17 * 37 + obj[0].hashCode()) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = new Object(); - assertEquals((17 * 37 + obj[0].hashCode()) * 37 + obj[1].hashCode(), new HashCodeBuilder(17, 37).append(obj) - .toHashCode()); - } - - @Test - public void testObjectArrayAsObject() { - final Object[] obj = new Object[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = new Object(); - assertEquals((17 * 37 + obj[0].hashCode()) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = new Object(); - assertEquals((17 * 37 + obj[0].hashCode()) * 37 + obj[1].hashCode(), new HashCodeBuilder(17, 37).append( - (Object) obj).toHashCode()); - } - - @Test - public void testLongArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((long[]) null).toHashCode()); - final long[] obj = new long[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = 5L; - final int h1 = (int) (5L ^ 5L >> 32); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = 6L; - final int h2 = (int) (6L ^ 6L >> 32); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testLongArrayAsObject() { - final long[] obj = new long[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = 5L; - final int h1 = (int) (5L ^ 5L >> 32); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = 6L; - final int h2 = (int) (6L ^ 6L >> 32); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testIntArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((int[]) null).toHashCode()); - final int[] obj = new int[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testIntArrayAsObject() { - final int[] obj = new int[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testShortArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((short[]) null).toHashCode()); - final short[] obj = new short[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = (short) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = (short) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testShortArrayAsObject() { - final short[] obj = new short[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = (short) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = (short) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testCharArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((char[]) null).toHashCode()); - final char[] obj = new char[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = (char) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = (char) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testCharArrayAsObject() { - final char[] obj = new char[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = (char) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = (char) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testByteArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((byte[]) null).toHashCode()); - final byte[] obj = new byte[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = (byte) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = (byte) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testByteArrayAsObject() { - final byte[] obj = new byte[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = (byte) 5; - assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = (byte) 6; - assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testDoubleArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((double[]) null).toHashCode()); - final double[] obj = new double[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = 5.4d; - final long l1 = Double.doubleToLongBits(5.4d); - final int h1 = (int) (l1 ^ l1 >> 32); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = 6.3d; - final long l2 = Double.doubleToLongBits(6.3d); - final int h2 = (int) (l2 ^ l2 >> 32); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testDoubleArrayAsObject() { - final double[] obj = new double[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = 5.4d; - final long l1 = Double.doubleToLongBits(5.4d); - final int h1 = (int) (l1 ^ l1 >> 32); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = 6.3d; - final long l2 = Double.doubleToLongBits(6.3d); - final int h2 = (int) (l2 ^ l2 >> 32); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testFloatArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((float[]) null).toHashCode()); - final float[] obj = new float[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = 5.4f; - final int h1 = Float.floatToIntBits(5.4f); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = 6.3f; - final int h2 = Float.floatToIntBits(6.3f); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testFloatArrayAsObject() { - final float[] obj = new float[2]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = 5.4f; - final int h1 = Float.floatToIntBits(5.4f); - assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = 6.3f; - final int h2 = Float.floatToIntBits(6.3f); - assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testBooleanArray() { - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((boolean[]) null).toHashCode()); - final boolean[] obj = new boolean[2]; - assertEquals((17 * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = true; - assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = false; - assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testBooleanArrayAsObject() { - final boolean[] obj = new boolean[2]; - assertEquals((17 * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[0] = true; - assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - obj[1] = false; - assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); - } - - @Test - public void testBooleanMultiArray() { - final boolean[][] obj = new boolean[2][]; - assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = new boolean[0]; - assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = new boolean[1]; - assertEquals((17 * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0] = new boolean[2]; - assertEquals(((17 * 37 + 1) * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[0][0] = true; - assertEquals(((17 * 37 + 0) * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - obj[1] = new boolean[1]; - assertEquals(((17 * 37 + 0) * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); - } - - @Test - public void testReflectionHashCodeExcludeFields() { - final TestObjectWithMultipleFields x = new TestObjectWithMultipleFields(1, 2, 3); - - assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x)); - - assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, (String[]) null)); - assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x)); - assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, "xxx")); - - assertEquals((17 * 37 + 1) * 37 + 3, HashCodeBuilder.reflectionHashCode(x, "two")); - assertEquals((17 * 37 + 1) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, "three")); - - assertEquals(17 * 37 + 1, HashCodeBuilder.reflectionHashCode(x, "two", "three")); - - assertEquals(17, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three")); - assertEquals(17, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three", "xxx")); - } - - static class TestObjectWithMultipleFields { - @SuppressWarnings("unused") - private int one = 0; - - @SuppressWarnings("unused") - private int two = 0; - - @SuppressWarnings("unused") - private int three = 0; - - TestObjectWithMultipleFields(final int one, final int two, final int three) { - this.one = one; - this.two = two; - this.three = three; - } - } - - /** - * Test Objects pointing to each other. - */ - @Test - public void testReflectionObjectCycle() { - final ReflectionTestCycleA a = new ReflectionTestCycleA(); - final ReflectionTestCycleB b = new ReflectionTestCycleB(); - a.b = b; - b.a = a; - - // Used to caused: - // java.lang.StackOverflowError - // at java.lang.ClassLoader.getCallerClassLoader(Native Method) - // at java.lang.Class.getDeclaredFields(Class.java:992) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:373) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:349) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:155) - // at - // org.apache.commons.lang.builder.HashCodeBuilderTest$ReflectionTestCycleB.hashCode(HashCodeBuilderTest.java:53) - // at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:422) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:383) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:349) - // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:155) - // at - // org.apache.commons.lang.builder.HashCodeBuilderTest$ReflectionTestCycleA.hashCode(HashCodeBuilderTest.java:42) - // at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:422) - - a.hashCode(); - assertNull(HashCodeBuilder.getRegistry()); - b.hashCode(); - assertNull(HashCodeBuilder.getRegistry()); - } - - /** - * Ensures LANG-520 remains true - */ - @Test - public void testToHashCodeEqualsHashCode() { - final HashCodeBuilder hcb = new HashCodeBuilder(17, 37).append(new Object()).append('a'); - assertEquals(hcb.toHashCode(), hcb.hashCode(), - "hashCode() is no longer returning the same value as toHashCode() - see LANG-520"); } static class TestObjectHashCodeExclude { @@ -599,6 +125,480 @@ public class HashCodeBuilderTest extends AbstractLangTest { } } + static class TestObjectWithMultipleFields { + @SuppressWarnings("unused") + private int one = 0; + + @SuppressWarnings("unused") + private int two = 0; + + @SuppressWarnings("unused") + private int three = 0; + + TestObjectWithMultipleFields(final int one, final int two, final int three) { + this.one = one; + this.two = two; + this.three = three; + } + } + + static class TestSubObject extends TestObject { + private int b; + + @SuppressWarnings("unused") + private transient int t; + + TestSubObject() { + super(0); + } + + TestSubObject(final int a, final int b, final int t) { + super(a); + this.b = b; + this.t = t; + } + + @Override + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof TestSubObject)) { + return false; + } + final TestSubObject rhs = (TestSubObject) o; + return super.equals(o) && b == rhs.b; + } + + @Override + public int hashCode() { + return b*17 + super.hashCode(); + } + + } + + @Test + public void testBoolean() { + assertEquals(17 * 37 + 0, new HashCodeBuilder(17, 37).append(true).toHashCode()); + assertEquals(17 * 37 + 1, new HashCodeBuilder(17, 37).append(false).toHashCode()); + } + + @Test + public void testBooleanArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((boolean[]) null).toHashCode()); + final boolean[] obj = new boolean[2]; + assertEquals((17 * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = true; + assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = false; + assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testBooleanArrayAsObject() { + final boolean[] obj = new boolean[2]; + assertEquals((17 * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = true; + assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = false; + assertEquals((17 * 37 + 0) * 37 + 1, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testBooleanMultiArray() { + final boolean[][] obj = new boolean[2][]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = new boolean[0]; + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = new boolean[1]; + assertEquals((17 * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = new boolean[2]; + assertEquals(((17 * 37 + 1) * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0][0] = true; + assertEquals(((17 * 37 + 0) * 37 + 1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = new boolean[1]; + assertEquals(((17 * 37 + 0) * 37 + 1) * 37 + 1, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testByte() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((byte) 0).toHashCode()); + assertEquals(17 * 37 + 123, new HashCodeBuilder(17, 37).append((byte) 123).toHashCode()); + } + + @Test + public void testByteArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((byte[]) null).toHashCode()); + final byte[] obj = new byte[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = (byte) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = (byte) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testByteArrayAsObject() { + final byte[] obj = new byte[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = (byte) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = (byte) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testChar() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((char) 0).toHashCode()); + assertEquals(17 * 37 + 1234, new HashCodeBuilder(17, 37).append((char) 1234).toHashCode()); + } + + @Test + public void testCharArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((char[]) null).toHashCode()); + final char[] obj = new char[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = (char) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = (char) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testCharArrayAsObject() { + final char[] obj = new char[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = (char) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = (char) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testConstructorExEvenFirst() { + assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(2, 3)); + } + + @Test + public void testConstructorExEvenNegative() { + assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(-2, -2)); + } + + @Test + public void testConstructorExEvenSecond() { + assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(3, 2)); + } + + @Test + public void testConstructorExZero() { + assertThrows(IllegalArgumentException.class, () -> new HashCodeBuilder(0, 0)); + } + + @Test + public void testDouble() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0d).toHashCode()); + final double d = 1234567.89; + final long l = Double.doubleToLongBits(d); + assertEquals(17 * 37 + (int) (l ^ l >> 32), new HashCodeBuilder(17, 37).append(d).toHashCode()); + } + + @Test + public void testDoubleArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((double[]) null).toHashCode()); + final double[] obj = new double[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = 5.4d; + final long l1 = Double.doubleToLongBits(5.4d); + final int h1 = (int) (l1 ^ l1 >> 32); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = 6.3d; + final long l2 = Double.doubleToLongBits(6.3d); + final int h2 = (int) (l2 ^ l2 >> 32); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testDoubleArrayAsObject() { + final double[] obj = new double[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = 5.4d; + final long l1 = Double.doubleToLongBits(5.4d); + final int h1 = (int) (l1 ^ l1 >> 32); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = 6.3d; + final long l2 = Double.doubleToLongBits(6.3d); + final int h2 = (int) (l2 ^ l2 >> 32); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testFloat() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0f).toHashCode()); + final float f = 1234.89f; + final int i = Float.floatToIntBits(f); + assertEquals(17 * 37 + i, new HashCodeBuilder(17, 37).append(f).toHashCode()); + } + + @Test + public void testFloatArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((float[]) null).toHashCode()); + final float[] obj = new float[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = 5.4f; + final int h1 = Float.floatToIntBits(5.4f); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = 6.3f; + final int h2 = Float.floatToIntBits(6.3f); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testFloatArrayAsObject() { + final float[] obj = new float[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = 5.4f; + final int h1 = Float.floatToIntBits(5.4f); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = 6.3f; + final int h2 = Float.floatToIntBits(6.3f); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testInt() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0).toHashCode()); + assertEquals(17 * 37 + 123456, new HashCodeBuilder(17, 37).append(123456).toHashCode()); + } + + @Test + public void testIntArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((int[]) null).toHashCode()); + final int[] obj = new int[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testIntArrayAsObject() { + final int[] obj = new int[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testLong() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(0L).toHashCode()); + assertEquals(17 * 37 + (int) (123456789L ^ 123456789L >> 32), new HashCodeBuilder(17, 37).append( + 123456789L).toHashCode()); + } + + @Test + public void testLongArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((long[]) null).toHashCode()); + final long[] obj = new long[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = 5L; + final int h1 = (int) (5L ^ 5L >> 32); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = 6L; + final int h2 = (int) (6L ^ 6L >> 32); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testLongArrayAsObject() { + final long[] obj = new long[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = 5L; + final int h1 = (int) (5L ^ 5L >> 32); + assertEquals((17 * 37 + h1) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = 6L; + final int h2 = (int) (6L ^ 6L >> 32); + assertEquals((17 * 37 + h1) * 37 + h2, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testObject() { + Object obj = null; + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj = new Object(); + assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testObjectArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((Object[]) null).toHashCode()); + final Object[] obj = new Object[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = new Object(); + assertEquals((17 * 37 + obj[0].hashCode()) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = new Object(); + assertEquals((17 * 37 + obj[0].hashCode()) * 37 + obj[1].hashCode(), new HashCodeBuilder(17, 37).append(obj) + .toHashCode()); + } + + @Test + public void testObjectArrayAsObject() { + final Object[] obj = new Object[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = new Object(); + assertEquals((17 * 37 + obj[0].hashCode()) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = new Object(); + assertEquals((17 * 37 + obj[0].hashCode()) * 37 + obj[1].hashCode(), new HashCodeBuilder(17, 37).append( + (Object) obj).toHashCode()); + } + + @Test + public void testObjectBuild() { + Object obj = null; + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append(obj).build().intValue()); + obj = new Object(); + assertEquals(17 * 37 + obj.hashCode(), new HashCodeBuilder(17, 37).append(obj).build().intValue()); + } + + @Test + public void testReflectionHashCode() { + assertEquals(17 * 37, HashCodeBuilder.reflectionHashCode(new TestObject(0))); + assertEquals(17 * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestObject(123456))); + } + + @Test + public void testReflectionHashCodeEx1() { + assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(0, 0, new TestObject(0), true)); + } + + @Test + public void testReflectionHashCodeEx2() { + assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(2, 2, new TestObject(0), true)); + } + + @Test + public void testReflectionHashCodeEx3() { + assertThrows(NullPointerException.class, () -> HashCodeBuilder.reflectionHashCode(13, 19, null, true)); + } + + @Test + public void testReflectionHashCodeExcludeFields() { + final TestObjectWithMultipleFields x = new TestObjectWithMultipleFields(1, 2, 3); + + assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x)); + + assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, (String[]) null)); + assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x)); + assertEquals(((17 * 37 + 1) * 37 + 3) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, "xxx")); + + assertEquals((17 * 37 + 1) * 37 + 3, HashCodeBuilder.reflectionHashCode(x, "two")); + assertEquals((17 * 37 + 1) * 37 + 2, HashCodeBuilder.reflectionHashCode(x, "three")); + + assertEquals(17 * 37 + 1, HashCodeBuilder.reflectionHashCode(x, "two", "three")); + + assertEquals(17, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three")); + assertEquals(17, HashCodeBuilder.reflectionHashCode(x, "one", "two", "three", "xxx")); + } + + @Test + public void testReflectionHierarchyHashCode() { + assertEquals(17 * 37 * 37, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0))); + assertEquals(17 * 37 * 37 * 37, HashCodeBuilder.reflectionHashCode(new TestSubObject(0, 0, 0), true)); + assertEquals((17 * 37 + 7890) * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject(123456, 7890, + 0))); + assertEquals(((17 * 37 + 7890) * 37 + 0) * 37 + 123456, HashCodeBuilder.reflectionHashCode(new TestSubObject( + 123456, 7890, 0), true)); + } + + @Test + public void testReflectionHierarchyHashCodeEx1() { + assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(0, 0, new TestSubObject(0, 0, 0), true)); + } + + @Test + public void testReflectionHierarchyHashCodeEx2() { + assertThrows(IllegalArgumentException.class, () -> HashCodeBuilder.reflectionHashCode(2, 2, new TestSubObject(0, 0, 0), true)); + } + + /** + * Test Objects pointing to each other. + */ + @Test + public void testReflectionObjectCycle() { + final ReflectionTestCycleA a = new ReflectionTestCycleA(); + final ReflectionTestCycleB b = new ReflectionTestCycleB(); + a.b = b; + b.a = a; + + // Used to caused: + // java.lang.StackOverflowError + // at java.lang.ClassLoader.getCallerClassLoader(Native Method) + // at java.lang.Class.getDeclaredFields(Class.java:992) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:373) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:349) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:155) + // at + // org.apache.commons.lang.builder.HashCodeBuilderTest$ReflectionTestCycleB.hashCode(HashCodeBuilderTest.java:53) + // at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:422) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionAppend(HashCodeBuilder.java:383) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:349) + // at org.apache.commons.lang.builder.HashCodeBuilder.reflectionHashCode(HashCodeBuilder.java:155) + // at + // org.apache.commons.lang.builder.HashCodeBuilderTest$ReflectionTestCycleA.hashCode(HashCodeBuilderTest.java:42) + // at org.apache.commons.lang.builder.HashCodeBuilder.append(HashCodeBuilder.java:422) + + a.hashCode(); + assertNull(HashCodeBuilder.getRegistry()); + b.hashCode(); + assertNull(HashCodeBuilder.getRegistry()); + } + + @Test + public void testShort() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((short) 0).toHashCode()); + assertEquals(17 * 37 + 12345, new HashCodeBuilder(17, 37).append((short) 12345).toHashCode()); + } + + @Test + public void testShortArray() { + assertEquals(17 * 37, new HashCodeBuilder(17, 37).append((short[]) null).toHashCode()); + final short[] obj = new short[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[0] = (short) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + obj[1] = (short) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append(obj).toHashCode()); + } + + @Test + public void testShortArrayAsObject() { + final short[] obj = new short[2]; + assertEquals(17 * 37 * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[0] = (short) 5; + assertEquals((17 * 37 + 5) * 37, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + obj[1] = (short) 6; + assertEquals((17 * 37 + 5) * 37 + 6, new HashCodeBuilder(17, 37).append((Object) obj).toHashCode()); + } + + @Test + public void testSuper() { + final Object obj = new Object(); + assertEquals(17 * 37 + 19 * 41 + obj.hashCode(), new HashCodeBuilder(17, 37).appendSuper( + new HashCodeBuilder(19, 41).append(obj).toHashCode()).toHashCode()); + } + + /** + * Ensures LANG-520 remains true + */ + @Test + public void testToHashCodeEqualsHashCode() { + final HashCodeBuilder hcb = new HashCodeBuilder(17, 37).append(new Object()).append('a'); + assertEquals(hcb.toHashCode(), hcb.hashCode(), + "hashCode() is no longer returning the same value as toHashCode() - see LANG-520"); + } + @Test public void testToHashCodeExclude() { final TestObjectHashCodeExclude one = new TestObjectHashCodeExclude(1, 2);