You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2020/04/08 12:14:44 UTC

[commons-numbers] 01/04: Test hashCode is equal when the fractions are equal.

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-numbers.git

commit d392058a78213e96f1218d26a10b9702cd9954e6
Author: aherbert <ah...@apache.org>
AuthorDate: Wed Apr 8 12:02:55 2020 +0100

    Test hashCode is equal when the fractions are equal.
    
    This test currently fails and is marked disabled.
---
 .../commons/numbers/fraction/BigFractionTest.java  | 51 +++++++++++++++++-----
 .../commons/numbers/fraction/FractionTest.java     | 50 ++++++++++++++++-----
 2 files changed, 78 insertions(+), 23 deletions(-)

diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
index 8bbcc14..a24a801 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/BigFractionTest.java
@@ -22,6 +22,7 @@ import java.math.RoundingMode;
 import org.apache.commons.numbers.core.TestUtils;
 
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 
@@ -591,28 +592,38 @@ public class BigFractionTest {
         Assertions.assertEquals(new BigDecimal("0.333"), BigFraction.of(1, 3).bigDecimalValue(3, RoundingMode.DOWN));
     }
 
+    @Disabled
     @Test
     public void testEqualsAndHashCode() {
         BigFraction zero = BigFraction.of(0, 1);
-        BigFraction nullFraction = null;
         Assertions.assertEquals(zero, zero);
-        Assertions.assertFalse(zero.equals(nullFraction));
+        Assertions.assertFalse(zero.equals(null));
+        Assertions.assertFalse(zero.equals(new Object()));
         Assertions.assertFalse(zero.equals(Double.valueOf(0)));
+
+        // Equal to same rational number
         BigFraction zero2 = BigFraction.of(0, 2);
-        Assertions.assertEquals(zero, zero2);
-        Assertions.assertEquals(zero.hashCode(), zero2.hashCode());
+        assertEqualAndHashCodeEqual(zero, zero2);
+
+        // Not equal to different rational number
         BigFraction one = BigFraction.of(1, 1);
         Assertions.assertNotEquals(zero, one);
         Assertions.assertNotEquals(one, zero);
-        Assertions.assertEquals(BigFraction.ONE, one);
-        BigFraction one2 = BigFraction.of(-1, -1);
-        Assertions.assertEquals(one2, one);
-        Assertions.assertEquals(one, one2);
 
-        BigFraction minusOne = BigFraction.of(-1, 1);
-        BigFraction minusOne2 = BigFraction.of(1, -1);
-        Assertions.assertEquals(minusOne2, minusOne);
-        Assertions.assertEquals(minusOne, minusOne2);
+        // Test using different representations of the same fraction
+        // (Denominators are primes)
+        for (int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}}) {
+            final int num = f[0];
+            final int den = f[1];
+            BigFraction f1 = BigFraction.of(-num, den);
+            BigFraction f2 = BigFraction.of(num, -den);
+            assertEqualAndHashCodeEqual(f1, f2);
+            assertEqualAndHashCodeEqual(f2, f1);
+            f1 = BigFraction.of(num, den);
+            f2 = BigFraction.of(-num, -den);
+            assertEqualAndHashCodeEqual(f1, f2);
+            assertEqualAndHashCodeEqual(f2, f1);
+        }
 
         // Same numerator or denominator as 1/1
         BigFraction half = BigFraction.of(1, 2);
@@ -621,6 +632,22 @@ public class BigFractionTest {
         Assertions.assertNotEquals(one, two);
     }
 
+    /**
+     * Assert the two fractions are equal. The contract of {@link Object#hashCode()} requires
+     * that the hash code must also be equal.
+     *
+     * <p>This method must not be called with the same instance for both arguments. It is
+     * intended to be used to test different objects that are equal have the same hash code.
+     *
+     * @param f1 Fraction 1.
+     * @param f2 Fraction 2.
+     */
+    private static void assertEqualAndHashCodeEqual(BigFraction f1, BigFraction f2) {
+        Assertions.assertNotSame(f1, f2, "Do not call this assertion with the same object");
+        Assertions.assertEquals(f1, f2);
+        Assertions.assertEquals(f1.hashCode(), f2.hashCode(), "Equal fractions have different hashCode");
+    }
+
     @Test
     public void testPow() {
         Assertions.assertEquals(BigFraction.of(8192, 1594323), BigFraction.of(2, 3).pow(13));
diff --git a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
index 5534d2e..cf6e747 100644
--- a/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
+++ b/commons-numbers-fraction/src/test/java/org/apache/commons/numbers/fraction/FractionTest.java
@@ -19,6 +19,7 @@ package org.apache.commons.numbers.fraction;
 import org.apache.commons.numbers.core.TestUtils;
 
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
 
@@ -422,27 +423,38 @@ public class FractionTest {
         );
     }
 
+    @Disabled
     @Test
     public void testEqualsAndHashCode() {
         Fraction zero = Fraction.of(0, 1);
-        Fraction nullFraction = null;
         Assertions.assertEquals(zero, zero);
-        Assertions.assertNotEquals(zero, nullFraction);
+        Assertions.assertNotEquals(zero, null);
+        Assertions.assertFalse(zero.equals(new Object()));
         Assertions.assertFalse(zero.equals(Double.valueOf(0)));
+
+        // Equal to same rational number
         Fraction zero2 = Fraction.of(0, 2);
-        Assertions.assertEquals(zero, zero2);
-        Assertions.assertEquals(zero.hashCode(), zero2.hashCode());
+        assertEqualAndHashCodeEqual(zero, zero2);
+
+        // Not equal to different rational number
         Fraction one = Fraction.of(1, 1);
         Assertions.assertNotEquals(zero, one);
         Assertions.assertNotEquals(one, zero);
-        Fraction one2 = Fraction.of(-1, -1);
-        Assertions.assertEquals(one2, one);
-        Assertions.assertEquals(one, one2);
 
-        Fraction minusOne = Fraction.of(-1, 1);
-        Fraction minusOne2 = Fraction.of(1, -1);
-        Assertions.assertEquals(minusOne2, minusOne);
-        Assertions.assertEquals(minusOne, minusOne2);
+        // Test using different representations of the same fraction
+        // (Denominators are primes)
+        for (int[] f : new int[][] {{1, 1}, {2, 3}, {6826, 15373}, {1373, 103813}}) {
+            final int num = f[0];
+            final int den = f[1];
+            Fraction f1 = Fraction.of(-num, den);
+            Fraction f2 = Fraction.of(num, -den);
+            assertEqualAndHashCodeEqual(f1, f2);
+            assertEqualAndHashCodeEqual(f2, f1);
+            f1 = Fraction.of(num, den);
+            f2 = Fraction.of(-num, -den);
+            assertEqualAndHashCodeEqual(f1, f2);
+            assertEqualAndHashCodeEqual(f2, f1);
+        }
 
         // Same numerator or denominator as 1/1
         Fraction half = Fraction.of(1, 2);
@@ -462,6 +474,22 @@ public class FractionTest {
         Assertions.assertNotEquals(almostZero, almostZero2);
     }
 
+    /**
+     * Assert the two fractions are equal. The contract of {@link Object#hashCode()} requires
+     * that the hash code must also be equal.
+     *
+     * <p>This method must not be called with the same instance for both arguments. It is
+     * intended to be used to test different objects that are equal have the same hash code.
+     *
+     * @param f1 Fraction 1.
+     * @param f2 Fraction 2.
+     */
+    private static void assertEqualAndHashCodeEqual(Fraction f1, Fraction f2) {
+        Assertions.assertNotSame(f1, f2, "Do not call this assertion with the same object");
+        Assertions.assertEquals(f1, f2);
+        Assertions.assertEquals(f1.hashCode(), f2.hashCode(), "Equal fractions have different hashCode");
+    }
+
     @Test
     public void testAdditiveNeutral() {
         Assertions.assertEquals(Fraction.ZERO, Fraction.ONE.zero());