import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.HashSet;
import org.junit.jupiter.api.Test;

// Una prueba por cada propiedad del contrato de equals y hashCode.
class FractionTest {
    private final Fraction a = new Fraction(1, 2);
    private final Fraction b = new Fraction(2, 4);
    private final Fraction c = new Fraction(-3, -6);

    @Test
    void reflexive() {
        assertTrue(a.equals(a));
    }

    @Test
    void symmetric() {
        assertTrue(a.equals(b));
        assertTrue(b.equals(a));
    }

    @Test
    void transitive() {
        assertTrue(a.equals(b));
        assertTrue(b.equals(c));
        assertTrue(a.equals(c));
    }

    @Test
    void consistent() {
        for (int i = 0; i < 3; i++) {
            assertTrue(a.equals(b));
        }
    }

    @Test
    void notEqualToNull() {
        assertFalse(a.equals(null));
    }

    @Test
    void notEqualToOtherType() {
        assertFalse(a.equals("1/2"));
    }

    @Test
    void differentValuesAreNotEqual() {
        assertNotEquals(new Fraction(1, 3), a);
    }

    @Test
    void equalObjectsHaveEqualHashCodes() {
        assertEquals(a.hashCode(), b.hashCode());
        assertEquals(a.hashCode(), c.hashCode());
    }

    @Test
    void hashSetFindsAnEqualFraction() {
        HashSet<Fraction> set = new HashSet<>();
        set.add(a);
        assertTrue(set.contains(new Fraction(5, 10)));
    }

    @Test
    void toStringShowsReducedForm() {
        assertEquals("1/2", b.toString());
        assertEquals("-2", new Fraction(4, -2).toString());
    }
}
