/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.numbers.fraction;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.function.BiFunction;
import java.util.function.UnaryOperator;

/**
 * Test cases for the {@link Fraction} class.
 *
 * <p>This class is ported from commons lang to demonstrate interoperability of
 * the Fraction class in numbers.</p>
 */
class CommonsLangPortedFractionTest {

    private static final int SKIP = 500;  //53

    //--------------------------------------------------------------------------
    @Test
    void testConstants() {
        assertEquals(0, Fraction.ZERO.getNumerator());
        assertEquals(1, Fraction.ZERO.getDenominator());

        assertEquals(1, Fraction.ONE.getNumerator());
        assertEquals(1, Fraction.ONE.getDenominator());

        /*
         *  All these constants need not be supported.
         *  Users can create whatever constants they require.
         *  The special constants ZERO and ONE are for the additive and multiplicative identity.
         *
         *  assertEquals(1, Fraction.ONE_HALF.getNumerator());
         *  assertEquals(2, Fraction.ONE_HALF.getDenominator());
         *
         *  assertEquals(1, Fraction.ONE_THIRD.getNumerator());
         *  assertEquals(3, Fraction.ONE_THIRD.getDenominator());
         *
         *  assertEquals(2, Fraction.TWO_THIRDS.getNumerator());
         *  assertEquals(3, Fraction.TWO_THIRDS.getDenominator());
         *
         *  assertEquals(1, Fraction.ONE_QUARTER.getNumerator());
         *  assertEquals(4, Fraction.ONE_QUARTER.getDenominator());
         *
         *  assertEquals(1, Fraction.TWO_QUARTERS.getNumerator());
         *  assertEquals(2, Fraction.TWO_QUARTERS.getDenominator());
         *
         *  assertEquals(3, Fraction.THREE_QUARTERS.getNumerator());
         *  assertEquals(4, Fraction.THREE_QUARTERS.getDenominator());
         *
         *  assertEquals(1, Fraction.ONE_FIFTH.getNumerator());
         *  assertEquals(5, Fraction.ONE_FIFTH.getDenominator());
         *
         *  assertEquals(2, Fraction.TWO_FIFTHS.getNumerator());
         *  assertEquals(5, Fraction.TWO_FIFTHS.getDenominator());
         *
         *  assertEquals(3, Fraction.THREE_FIFTHS.getNumerator());
         *  assertEquals(5, Fraction.THREE_FIFTHS.getDenominator());
         *
         *  assertEquals(4, Fraction.FOUR_FIFTHS.getNumerator());
         *  assertEquals(5, Fraction.FOUR_FIFTHS.getDenominator());
         */
    }

    @Test
    void testFactory_int_int() {
        Fraction f = null;

        // zero
        f = Fraction.of(0, 1);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(0, 2);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // normal
        f = Fraction.of(1, 1);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(2, 1);
        assertEquals(2, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(23, 345);
        assertEquals(1, f.getNumerator());
        assertEquals(15, f.getDenominator());

        // improper
        f = Fraction.of(22, 7);
        assertEquals(22, f.getNumerator());
        assertEquals(7, f.getDenominator());

        // negatives
        f = Fraction.of(-6, 10);
        assertEquals(-3, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f = Fraction.of(6, -10);
        assertEquals(3, f.getNumerator());
        assertEquals(-5, f.getDenominator());

        f = Fraction.of(-6, -10);
        assertEquals(-3, f.getNumerator());
        assertEquals(-5, f.getDenominator());

        // zero denominator
        assertThrows(ArithmeticException.class, () -> Fraction.of(1, 0));
        assertThrows(ArithmeticException.class, () -> Fraction.of(2, 0));
        assertThrows(ArithmeticException.class, () -> Fraction.of(-3, 0));

        // lang cannot represent the unsimplified fraction with MIN_VALUE as the denominator
        // assertThrows(ArithmeticException.class, () -> Fraction.getFraction(4, Integer.MIN_VALUE));
        // assertThrows(ArithmeticException.class, () -> Fraction.getFraction(1, Integer.MIN_VALUE));
        // numbers will always simplify the fraction
        f = Fraction.of(4, Integer.MIN_VALUE);
        assertEquals(-1, f.signum());
        assertEquals(1, f.getNumerator());
        assertEquals(Integer.MIN_VALUE / 4, f.getDenominator());
        // numbers can use MIN_VALUE as the denominator
        f = Fraction.of(1, Integer.MIN_VALUE);
        assertEquals(-1, f.signum());
        assertEquals(1, f.getNumerator());
        assertEquals(Integer.MIN_VALUE, f.getDenominator());
    }

/*
 *  Removed as not supported in numbers.
 *
 *  @Test
 *  void testFactory_int_int_int() {
 *      Fraction f = null;
 *
 *      // zero
 *      f = Fraction.of(0, 0, 2);
 *      assertEquals(0, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      f = Fraction.of(2, 0, 2);
 *      assertEquals(2, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      f = Fraction.of(0, 1, 2);
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      // normal
 *      f = Fraction.of(1, 1, 2);
 *      assertEquals(3, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      // negatives
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(1, -6, -10));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(1, -6, -10));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(1, -6, -10));
 *
 *      // negative whole
 *      f = Fraction.of(-1, 6, 10);
 *      assertEquals(-8, f.getNumerator());
 *      assertEquals(5, f.getDenominator());
 *
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-1, -6, 10));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-1, 6, -10));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-1, -6, -10));
 *
 *      // zero denominator
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(0, 1, 0));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(1, 2, 0));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-1, -3, 0));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(Integer.MAX_VALUE, 1, 2));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-Integer.MAX_VALUE, 1, 2));
 *
 *      // very large
 *      f = Fraction.of(-1, 0, Integer.MAX_VALUE);
 *      assertEquals(-1, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      // negative denominators not allowed in this constructor.
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(0, 4, Integer.MIN_VALUE));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(1, 1, Integer.MAX_VALUE));
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(-1, 2, Integer.MAX_VALUE));
 *  }
 */

    @Test
    void testReducedFactory_int_int() {
        Fraction f = null;

        // zero
        f = Fraction.of(0, 1);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // normal
        f = Fraction.of(1, 1);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(2, 1);
        assertEquals(2, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // improper
        f = Fraction.of(22, 7);
        assertEquals(22, f.getNumerator());
        assertEquals(7, f.getDenominator());

        // negatives
        f = Fraction.of(-6, 10);
        assertEquals(-3, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f = Fraction.of(6, -10);
        assertEquals(3, f.getNumerator());
        assertEquals(-5, f.getDenominator());

        f = Fraction.of(-6, -10);
        assertEquals(-3, f.getNumerator());
        assertEquals(-5, f.getDenominator());

        // zero denominator
        assertThrows(ArithmeticException.class, () -> Fraction.of(1, 0));
        assertThrows(ArithmeticException.class, () -> Fraction.of(2, 0));
        assertThrows(ArithmeticException.class, () -> Fraction.of(-3, 0));

        // reduced
        f = Fraction.of(0, 2);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(2, 2);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(2, 4);
        assertEquals(1, f.getNumerator());
        assertEquals(2, f.getDenominator());

        f = Fraction.of(15, 10);
        assertEquals(3, f.getNumerator());
        assertEquals(2, f.getDenominator());

        f = Fraction.of(121, 22);
        assertEquals(11, f.getNumerator());
        assertEquals(2, f.getDenominator());

        // Extreme values
        // OK, can reduce before negating
        f = Fraction.of(-2, Integer.MIN_VALUE);
        assertEquals(-1, f.getNumerator());
        assertEquals(Integer.MIN_VALUE / 2, f.getDenominator());

        // lang requires the sign to be in the numerator so this would throw.
        // assertThrows(ArithmeticException.class, () -> Fraction.getReducedFraction(-7, Integer.MIN_VALUE));
        // numbers allows the sign to be in the denominator so this does not throw.
        f = Fraction.of(-7, Integer.MIN_VALUE);
        assertEquals(1, f.signum());
        assertEquals(-7, f.getNumerator());
        assertEquals(Integer.MIN_VALUE, f.getDenominator());

        // LANG-662
        f = Fraction.of(Integer.MIN_VALUE, 2);
        assertEquals(Integer.MIN_VALUE / 2, f.getNumerator());
        assertEquals(1, f.getDenominator());
    }

    @Test
    void testFactory_double() {
        assertThrows(IllegalArgumentException.class, () -> Fraction.from(Double.NaN));
        assertThrows(IllegalArgumentException.class, () -> Fraction.from(Double.POSITIVE_INFINITY));
        assertThrows(IllegalArgumentException.class, () -> Fraction.from(Double.NEGATIVE_INFINITY));
        Fraction.from((double) Integer.MAX_VALUE + 1);

        // zero
        Fraction f = Fraction.from(0.0d);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // one
        f = Fraction.from(1.0d);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // one half
        f = Fraction.from(0.5d);
        assertEquals(1, f.getNumerator());
        assertEquals(2, f.getDenominator());

        // negative
        f = Fraction.from(-0.875d);
        assertEquals(-7, f.getNumerator());
        assertEquals(8, f.getDenominator());

        // over 1
        f = Fraction.from(1.25d);
        assertEquals(5, f.getNumerator());
        assertEquals(4, f.getDenominator());

        // two thirds
        f = Fraction.from(0.66666d);
        assertEquals(2, f.getNumerator());
        assertEquals(3, f.getDenominator());

        // small
        f = Fraction.from(1.0d / 10001d);
        assertEquals(1, f.getNumerator());
        assertEquals(10001, f.getDenominator());

        // normal
        Fraction f2 = null;
        for (int i = 1; i <= 100; i++) {  // denominator
            for (int j = 1; j <= i; j++) {  // numerator
                f = Fraction.from((double) j / (double) i);

                f2 = Fraction.of(j, i);
                assertEquals(f2.getNumerator(), f.getNumerator());
                assertEquals(f2.getDenominator(), f.getDenominator());
            }
        }
        // save time by skipping some tests!  (
        for (int i = 1001; i <= 10000; i += SKIP) {  // denominator
            for (int j = 1; j <= i; j++) {  // numerator
                f = Fraction.from((double) j / (double) i, 1e-8, 100);
                f2 = Fraction.of(j, i);
                assertEquals(f2.getNumerator(), f.getNumerator());
                assertEquals(f2.getDenominator(), f.getDenominator());
            }
        }
    }

/*
 *  Removed as not supported in numbers.
 *
 *  @Test
 *  void testFactory_String() {
 *      assertThrows(NullPointerException.class, () -> Fraction.from(null));
 *  }
 *
 *
 *  @Test
 *  void testFactory_String_double() {
 *      Fraction f = null;
 *
 *      f = Fraction.from("0.0");
 *      assertEquals(0, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      f = Fraction.from("0.2");
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(5, f.getDenominator());
 *
 *      f = Fraction.from("0.5");
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.from("0.66666");
 *      assertEquals(2, f.getNumerator());
 *      assertEquals(3, f.getDenominator());
 *
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2.3R"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2147483648")); // too big
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("."));
 *  }
 *
 *  @Test
 *  void testFactory_String_proper() {
 *      Fraction f = null;
 *
 *      f = Fraction.from("0 0/1");
 *      assertEquals(0, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      f = Fraction.from("1 1/5");
 *      assertEquals(6, f.getNumerator());
 *      assertEquals(5, f.getDenominator());
 *
 *      f = Fraction.from("7 1/2");
 *      assertEquals(15, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.from("1 2/4");
 *      assertEquals(3, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.from("-7 1/2");
 *      assertEquals(-15, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.from("-1 2/4");
 *      assertEquals(-3, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2 3"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("a 3"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2 b/4"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2 "));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from(" 3"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from(" "));
 *  }
 *
 *  @Test
 *  void testFactory_String_improper() {
 *      Fraction f = null;
 *
 *      f = Fraction.from("0/1");
 *      assertEquals(0, f.getNumerator());
 *      assertEquals(1, f.getDenominator());
 *
 *      f = Fraction.from("1/5");
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(5, f.getDenominator());
 *
 *      f = Fraction.from("1/2");
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.from("2/3");
 *      assertEquals(2, f.getNumerator());
 *      assertEquals(3, f.getDenominator());
 *
 *      f = Fraction.from("7/3");
 *      assertEquals(7, f.getNumerator());
 *      assertEquals(3, f.getDenominator());
 *
 *      f = Fraction.from("2/4");
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2/d"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2e/3"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("2/"));
 *      assertThrows(NumberFormatException.class, () -> Fraction.from("/"));
 *  }
 *
 *  @Test
 *  void testGets() {
 *      Fraction f = null;
 *
 *      f = Fraction.of(3, 5, 6);
 *      assertEquals(23, f.getNumerator());
 *      assertEquals(3, f.getProperWhole());
 *      assertEquals(5, f.getProperNumerator());
 *      assertEquals(6, f.getDenominator());
 *
 *      f = Fraction.of(-3, 5, 6);
 *      assertEquals(-23, f.getNumerator());
 *      assertEquals(-3, f.getProperWhole());
 *      assertEquals(5, f.getProperNumerator());
 *      assertEquals(6, f.getDenominator());
 *
 *      f = Fraction.of(Integer.MIN_VALUE, 0, 1);
 *      assertEquals(Integer.MIN_VALUE, f.getNumerator());
 *      assertEquals(Integer.MIN_VALUE, f.getProperWhole());
 *      assertEquals(0, f.getProperNumerator());
 *      assertEquals(1, f.getDenominator());
 *  }
 *
 *  @Test
 *  void testConversions() {
 *      Fraction f = null;
 *
 *      f = Fraction.of(3, 7, 8);
 *      assertEquals(3, f.intValue());
 *      assertEquals(3L, f.longValue());
 *      assertEquals(3.875f, f.floatValue(), 0.00001f);
 *      assertEquals(3.875d, f.doubleValue(), 0.00001d);
 *  }
 *
 *  @Test
 *  void testReduce() {
 *      Fraction f = null;
 *
 *      f = Fraction.of(50, 75);
 *      Fraction result = f.reduce();
 *      assertEquals(2, result.getNumerator());
 *      assertEquals(3, result.getDenominator());
 *
 *      f = Fraction.of(-2, -3);
 *      result = f.reduce();
 *      assertEquals(2, result.getNumerator());
 *      assertEquals(3, result.getDenominator());
 *
 *      f = Fraction.of(2, -3);
 *      result = f.reduce();
 *      assertEquals(-2, result.getNumerator());
 *      assertEquals(3, result.getDenominator());
 *
 *      f = Fraction.of(-2, 3);
 *      result = f.reduce();
 *      assertEquals(-2, result.getNumerator());
 *      assertEquals(3, result.getDenominator());
 *      assertSame(f, result);
 *
 *      f = Fraction.of(2, 3);
 *      result = f.reduce();
 *      assertEquals(2, result.getNumerator());
 *      assertEquals(3, result.getDenominator());
 *      assertSame(f, result);
 *
 *      f = Fraction.of(0, 1);
 *      result = f.reduce();
 *      assertEquals(0, result.getNumerator());
 *      assertEquals(1, result.getDenominator());
 *      assertSame(f, result);
 *
 *      f = Fraction.of(0, 100);
 *      result = f.reduce();
 *      assertEquals(0, result.getNumerator());
 *      assertEquals(1, result.getDenominator());
 *      assertSame(result, Fraction.ZERO);
 *
 *      f = Fraction.of(Integer.MIN_VALUE, 2);
 *      result = f.reduce();
 *      assertEquals(Integer.MIN_VALUE / 2, result.getNumerator());
 *      assertEquals(1, result.getDenominator());
 *  }
 *
 *  @Test
 *  void testreciprocal() {
 *      Fraction f = null;
 *
 *      f = Fraction.of(50, 75);
 *      f = f.reciprocal();
 *      assertEquals(3, f.getNumerator());
 *      assertEquals(2, f.getDenominator());
 *
 *      f = Fraction.of(4, 3);
 *      f = f.reciprocal();
 *      assertEquals(3, f.getNumerator());
 *      assertEquals(4, f.getDenominator());
 *
 *      f = Fraction.of(-15, 47);
 *      f = f.reciprocal();
 *      assertEquals(47, f.getNumerator());
 *      assertEquals(-15, f.getDenominator());
 *
 *      assertThrows(ArithmeticException.class, () -> Fraction.of(0, 3).reciprocal());
 *      Fraction.of(Integer.MIN_VALUE, 1).reciprocal();
 *
 *      f = Fraction.of(Integer.MAX_VALUE, 1);
 *      f = f.reciprocal();
 *      assertEquals(1, f.getNumerator());
 *      assertEquals(Integer.MAX_VALUE, f.getDenominator());
 *  }
 */

    @Test
    void testNegate() {
        Fraction f = null;

        f = Fraction.of(50, 75);
        f = f.negate();
        assertEquals(-2, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f = Fraction.of(-50, 75);
        f = f.negate();
        assertEquals(2, f.getNumerator());
        assertEquals(3, f.getDenominator());

        // large values
        f = Fraction.of(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
        f = f.negate();
        assertEquals(Integer.MIN_VALUE + 2, f.getNumerator());
        assertEquals(Integer.MAX_VALUE, f.getDenominator());

        // lang requires the sign in the numerator and so cannot negate MIN_VALUE as the numerator
        // assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MIN_VALUE, 1).negate());
        // numbers allows the sign in the numerator or denominator
        f = Fraction.of(Integer.MIN_VALUE, 1).negate();
        assertEquals(1, f.signum());
        assertEquals(Integer.MIN_VALUE, f.getNumerator());
        assertEquals(-1, f.getDenominator());
    }

    @Test
    void testAbs() {
        Fraction f = null;

        f = Fraction.of(50, 75);
        f = f.abs();
        assertEquals(2, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f = Fraction.of(-50, 75);
        f = f.abs();
        assertEquals(2, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f = Fraction.of(Integer.MAX_VALUE, 1);
        f = f.abs();
        assertEquals(Integer.MAX_VALUE, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f = Fraction.of(Integer.MAX_VALUE, -1);
        f = f.abs();
        assertEquals(-Integer.MAX_VALUE, f.getNumerator());
        assertEquals(-1, f.getDenominator());

        // lang requires the sign in the numerator and so cannot compute the absolute with MIN_VALUE as the numerator
        // assertThrows(ArithmeticException.class, () -> Fraction.getFraction(Integer.MIN_VALUE, 1).abs());
        // numbers allows the sign in the numerator or denominator
        f = Fraction.of(Integer.MIN_VALUE, 1).abs();
        assertEquals(1, f.signum());
        assertEquals(Integer.MIN_VALUE, f.getNumerator());
        assertEquals(-1, f.getDenominator());
    }

    @Test
    void testPow() {
        Fraction f = null;

        f = Fraction.of(3, 5);
        assertEquals(Fraction.ONE, f.pow(0));

        f = Fraction.of(3, 5);
        assertEquals(f, f.pow(1));
        assertEquals(f, f.pow(1));

        f = Fraction.of(3, 5);
        f = f.pow(2);
        assertEquals(9, f.getNumerator());
        assertEquals(25, f.getDenominator());

        f = Fraction.of(3, 5);
        f = f.pow(3);
        assertEquals(27, f.getNumerator());
        assertEquals(125, f.getDenominator());

        f = Fraction.of(3, 5);
        f = f.pow(-1);
        assertEquals(5, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f = Fraction.of(3, 5);
        f = f.pow(-2);
        assertEquals(25, f.getNumerator());
        assertEquals(9, f.getDenominator());

        // check unreduced fractions stay that way.
        f = Fraction.of(6, 10);
        assertEquals(Fraction.ONE, f.pow(0));

        f = Fraction.of(6, 10);
        assertEquals(f, f.pow(1));
        assertEquals(f.pow(1), Fraction.of(3, 5));

        f = Fraction.of(6, 10);
        f = f.pow(2);
        assertEquals(9, f.getNumerator());
        assertEquals(25, f.getDenominator());

        f = Fraction.of(6, 10);
        f = f.pow(3);
        assertEquals(27, f.getNumerator());
        assertEquals(125, f.getDenominator());

        f = Fraction.of(6, 10);
        f = f.pow(-1);
        assertEquals(5, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f = Fraction.of(6, 10);
        f = f.pow(-2);
        assertEquals(25, f.getNumerator());
        assertEquals(9, f.getDenominator());

        // zero to any positive power is still zero.
        f = Fraction.of(0, 1231);
        f = f.pow(1);
        assertEquals(0, f.compareTo(Fraction.ZERO));
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());
        f = f.pow(2);
        assertEquals(0, f.compareTo(Fraction.ZERO));
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // zero to negative powers should throw an exception
        final Fraction fr = f;
        assertThrows(ArithmeticException.class, () -> fr.pow(-1));
        assertThrows(ArithmeticException.class, () -> fr.pow(Integer.MIN_VALUE));

        // one to any power is still one.
        f = Fraction.of(1, 1);
        f = f.pow(0);
        assertEquals(Fraction.ONE, f);
        f = f.pow(1);
        assertEquals(Fraction.ONE, f);
        f = f.pow(-1);
        assertEquals(Fraction.ONE, f);
        f = f.pow(Integer.MAX_VALUE);
        assertEquals(Fraction.ONE, f);
        f = f.pow(Integer.MIN_VALUE);
        assertEquals(Fraction.ONE, f);

        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MAX_VALUE, 1), a -> a.pow(2));

        // Numerator growing too negative during the pow operation.
        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MIN_VALUE, 1), a -> a.pow(3));

        assertOperationThrows(ArithmeticException.class, Fraction.of(65536, 1), a -> a.pow(2));
    }

    @Test
    void testAdd() {
        Fraction f = null;
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(1, 5);
        f = f1.add(f2);
        assertEquals(4, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(2, 5);
        f = f1.add(f2);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(3, 5);
        f = f1.add(f2);
        assertEquals(6, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(-4, 5);
        f = f1.add(f2);
        assertEquals(-1, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(Integer.MAX_VALUE - 1, 1);
        f2 = Fraction.ONE;
        f = f1.add(f2);
        assertEquals(Integer.MAX_VALUE, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(1, 2);
        f = f1.add(f2);
        assertEquals(11, f.getNumerator());
        assertEquals(10, f.getDenominator());

        f1 = Fraction.of(3, 8);
        f2 = Fraction.of(1, 6);
        f = f1.add(f2);
        assertEquals(13, f.getNumerator());
        assertEquals(24, f.getDenominator());

        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(1, 5);
        f = f1.add(f2);
        assertSame(f2, f);
        f = f2.add(f1);
        assertSame(f2, f);

        f1 = Fraction.of(-1, 13 * 13 * 2 * 2);
        f2 = Fraction.of(-2, 13 * 17 * 2);
        final Fraction fr = f1.add(f2);
        assertEquals(13 * 13 * 17 * 2 * 2, fr.getDenominator());
        assertEquals(-17 - 2 * 13 * 2, fr.getNumerator());

        assertThrows(NullPointerException.class, () -> fr.add(null));

        // if this fraction is added naively, it will overflow.
        // check that it doesn't.
        f1 = Fraction.of(1, 32768 * 3);
        f2 = Fraction.of(1, 59049);
        f = f1.add(f2);
        assertEquals(52451, f.getNumerator());
        assertEquals(1934917632, f.getDenominator());

        f1 = Fraction.of(Integer.MIN_VALUE, 3);
        f2 = Fraction.of(1, 3);
        f = f1.add(f2);
        assertEquals(Integer.MIN_VALUE + 1, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f1 = Fraction.of(Integer.MAX_VALUE - 1, 1);
        f2 = Fraction.ONE;
        f = f1.add(f2);
        assertEquals(Integer.MAX_VALUE, f.getNumerator());
        assertEquals(1, f.getDenominator());

        final Fraction overflower = f;
        assertThrows(ArithmeticException.class, () -> overflower.add(Fraction.ONE)); // should overflow

        // denominator should not be a multiple of 2 or 3 to trigger overflow
        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MIN_VALUE, 5), Fraction.of(-1, 5), Fraction::add);

        final Fraction maxValue = Fraction.of(-Integer.MAX_VALUE, 1);
        assertThrows(ArithmeticException.class, () -> maxValue.add(maxValue));

        final Fraction negativeMaxValue = Fraction.of(-Integer.MAX_VALUE, 1);
        assertThrows(ArithmeticException.class, () -> negativeMaxValue.add(negativeMaxValue));

        final Fraction f3 = Fraction.of(3, 327680);
        final Fraction f4 = Fraction.of(2, 59049);
        assertThrows(ArithmeticException.class, () -> f3.add(f4)); // should overflow
    }

    @Test
    void testSubtract() {
        Fraction f = null;
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(1, 5);
        f = f1.subtract(f2);
        assertEquals(2, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(7, 5);
        f2 = Fraction.of(2, 5);
        f = f1.subtract(f2);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(3, 5);
        f = f1.subtract(f2);
        assertEquals(0, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(-4, 5);
        f = f1.subtract(f2);
        assertEquals(7, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(4, 5);
        f = f1.subtract(f2);
        assertEquals(-4, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(-4, 5);
        f = f1.subtract(f2);
        assertEquals(4, f.getNumerator());
        assertEquals(5, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(1, 2);
        f = f1.subtract(f2);
        assertEquals(1, f.getNumerator());
        assertEquals(10, f.getDenominator());

        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(1, 5);
        f = f2.subtract(f1);
        assertSame(f2, f);

        final Fraction fr = f;
        assertThrows(NullPointerException.class, () -> fr.subtract(null));

        // if this fraction is subtracted naively, it will overflow.
        // check that it doesn't.
        f1 = Fraction.of(1, 32768 * 3);
        f2 = Fraction.of(1, 59049);
        f = f1.subtract(f2);
        assertEquals(-13085, f.getNumerator());
        assertEquals(1934917632, f.getDenominator());

        f1 = Fraction.of(Integer.MIN_VALUE, 3);
        f2 = Fraction.of(1, 3).negate();
        f = f1.subtract(f2);
        assertEquals(Integer.MIN_VALUE + 1, f.getNumerator());
        assertEquals(3, f.getDenominator());

        f1 = Fraction.of(Integer.MAX_VALUE, 1);
        f2 = Fraction.ONE;
        f = f1.subtract(f2);
        assertEquals(Integer.MAX_VALUE - 1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        // Should overflow
        assertOperationThrows(ArithmeticException.class, Fraction.of(1, Integer.MAX_VALUE), Fraction.of(1, Integer.MAX_VALUE - 1), Fraction::subtract);
        f = f1.subtract(f2);

        // denominator should not be a multiple of 2 or 3 to trigger overflow
        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MIN_VALUE, 5), Fraction.of(1, 5), Fraction::subtract);

        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MIN_VALUE, 1), Fraction.ONE, Fraction::subtract);

        assertOperationThrows(ArithmeticException.class, Fraction.of(Integer.MAX_VALUE, 1), Fraction.ONE.negate(), Fraction::subtract);

        // Should overflow
        assertOperationThrows(ArithmeticException.class, Fraction.of(3, 327680), Fraction.of(2, 59049), Fraction::subtract);
    }

    @Test
    void testMultiply() {
        Fraction f = null;
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(2, 5);
        f = f1.multiply(f2);
        assertEquals(6, f.getNumerator());
        assertEquals(25, f.getDenominator());

        f1 = Fraction.of(6, 10);
        f2 = Fraction.of(6, 10);
        f = f1.multiply(f2);
        assertEquals(9, f.getNumerator());
        assertEquals(25, f.getDenominator());
        f = f.multiply(f2);
        assertEquals(27, f.getNumerator());
        assertEquals(125, f.getDenominator());

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(-2, 5);
        f = f1.multiply(f2);
        assertEquals(-6, f.getNumerator());
        assertEquals(25, f.getDenominator());

        f1 = Fraction.of(-3, 5);
        f2 = Fraction.of(-2, 5);
        f = f1.multiply(f2);
        assertEquals(6, f.getNumerator());
        assertEquals(25, f.getDenominator());


        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(2, 7);
        f = f1.multiply(f2);
        assertSame(Fraction.ZERO, f);

        f1 = Fraction.of(2, 7);
        f2 = Fraction.ONE;
        f = f1.multiply(f2);
        assertEquals(2, f.getNumerator());
        assertEquals(7, f.getDenominator());

        f1 = Fraction.of(Integer.MAX_VALUE, 1);
        f2 = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
        f = f1.multiply(f2);
        assertEquals(Integer.MIN_VALUE, f.getNumerator());
        assertEquals(1, f.getDenominator());

        final Fraction fr = f;
        assertThrows(NullPointerException.class, () -> fr.multiply(null));

        final Fraction fr1 = Fraction.of(1, Integer.MAX_VALUE);
        assertThrows(ArithmeticException.class, () -> fr1.multiply(fr1));

        final Fraction fr2 = Fraction.of(1, -Integer.MAX_VALUE);
        assertThrows(ArithmeticException.class, () -> fr2.multiply(fr2));
    }

    @Test
    void testDivide() {
        Fraction f = null;
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(2, 5);
        f = f1.divide(f2);
        assertEquals(3, f.getNumerator());
        assertEquals(2, f.getDenominator());

        assertOperationThrows(ArithmeticException.class, Fraction.of(3, 5), Fraction.ZERO, Fraction::divide);

        f1 = Fraction.of(0, 5);
        f2 = Fraction.of(2, 7);
        f = f1.divide(f2);
        assertSame(Fraction.ZERO, f);

        f1 = Fraction.of(2, 7);
        f2 = Fraction.ONE;
        f = f1.divide(f2);
        assertEquals(2, f.getNumerator());
        assertEquals(7, f.getDenominator());

        f1 = Fraction.of(1, Integer.MAX_VALUE);
        f = f1.divide(f1);
        assertEquals(1, f.getNumerator());
        assertEquals(1, f.getDenominator());

        f1 = Fraction.of(Integer.MIN_VALUE, Integer.MAX_VALUE);
        f2 = Fraction.of(1, Integer.MAX_VALUE);
        final Fraction fr = f1.divide(f2);
        assertEquals(Integer.MIN_VALUE, fr.getNumerator());
        assertEquals(1, fr.getDenominator());

        assertThrows(NullPointerException.class, () -> fr.divide(null));

        final Fraction smallest = Fraction.of(1, Integer.MAX_VALUE);
        final Fraction smallestReciprocal = smallest.reciprocal();
        assertThrows(ArithmeticException.class, () -> smallest.divide(smallestReciprocal)); // Should overflow

        final Fraction negative = Fraction.of(1, -Integer.MAX_VALUE);
        final Fraction negativeReciprocal = negative.reciprocal();
        assertThrows(ArithmeticException.class, () -> negative.divide(negativeReciprocal)); // Should overflow
    }

    @Test
    void testEquals() {
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        assertNotEquals(null, f1);
        assertNotEquals(f1, new Object());
        assertNotEquals(f1, Integer.valueOf(6));

        f1 = Fraction.of(3, 5);
        f2 = Fraction.of(2, 5);
        assertNotEquals(f1, f2);
        assertEquals(f1, f1);
        assertEquals(f2, f2);

        f2 = Fraction.of(3, 5);
        assertEquals(f1, f2);

        f2 = Fraction.of(6, 10);
        assertEquals(f1, f2);
    }

    @Test
    void testHashCode() {
        final Fraction f1 = Fraction.of(3, 5);
        Fraction f2 = Fraction.of(3, 5);

        assertEquals(f1.hashCode(), f2.hashCode());

        f2 = Fraction.of(2, 5);
        assertNotEquals(f1.hashCode(), f2.hashCode());

        f2 = Fraction.of(6, 10);
        assertEquals(f1.hashCode(), f2.hashCode());
    }

    @Test
    void testCompareTo() {
        Fraction f1 = null;
        Fraction f2 = null;

        f1 = Fraction.of(3, 5);
        assertEquals(0, f1.compareTo(f1));

        final Fraction fr = f1;
        assertThrows(NullPointerException.class, () -> fr.compareTo(null));

        f2 = Fraction.of(2, 5);
        assertTrue(f1.compareTo(f2) > 0);
        assertEquals(0, f2.compareTo(f2));

        f2 = Fraction.of(4, 5);
        assertTrue(f1.compareTo(f2) < 0);
        assertEquals(0, f2.compareTo(f2));

        f2 = Fraction.of(3, 5);
        assertEquals(0, f1.compareTo(f2));
        assertEquals(0, f2.compareTo(f2));

        f2 = Fraction.of(6, 10);
        assertEquals(0, f1.compareTo(f2));
        assertEquals(0, f2.compareTo(f2));

        /*
         *  Removed as not supported in numbers.
         *
         *  f2 = Fraction.of(-1, 1, Integer.MAX_VALUE);
         *  assertTrue(f1.compareTo(f2) > 0);
         *  assertEquals(0, f2.compareTo(f2));
         */
    }

    @Test
    void testToString() {
        Fraction f = null;

        f = Fraction.of(3, 5);
        final String str = f.toString();
        assertEquals("3 / 5", str);
        assertEquals(str, f.toString());

        f = Fraction.of(7, 5);
        assertEquals("7 / 5", f.toString());

        f = Fraction.of(4, 2);
        assertEquals("2", f.toString());

        f = Fraction.of(0, 2);
        assertEquals("0", f.toString());

        f = Fraction.of(2, 2);
        assertEquals("1", f.toString());

        f = Fraction.of(Integer.MIN_VALUE);
        assertEquals("-2147483648", f.toString());

        f = Fraction.of(-1).add(Fraction.of(-1, Integer.MAX_VALUE));
        assertEquals("-2147483648 / 2147483647", f.toString());
    }

/*
 *  Removed as not supported in numbers.
 *
 *  @Test
 *  void testToProperString() {
 *      Fraction f = null;
 *
 *      f = Fraction.of(3, 5);
 *      final String str = f.toProperString();
 *      assertEquals("3/5", str);
 *      assertSame(str, f.toProperString());
 *
 *      f = Fraction.of(7, 5);
 *      assertEquals("1 2/5", f.toProperString());
 *
 *      f = Fraction.of(14, 10);
 *      assertEquals("1 2/5", f.toProperString());
 *
 *      f = Fraction.of(4, 2);
 *      assertEquals("2", f.toProperString());
 *
 *      f = Fraction.of(0, 2);
 *      assertEquals("0", f.toProperString());
 *
 *      f = Fraction.of(2, 2);
 *      assertEquals("1", f.toProperString());
 *
 *      f = Fraction.of(-7, 5);
 *      assertEquals("-1 2/5", f.toProperString());
 *
 *      f = Fraction.of(Integer.MIN_VALUE, 0, 1);
 *      assertEquals("-2147483648", f.toProperString());
 *
 *      f = Fraction.of(-1, 1, Integer.MAX_VALUE);
 *      assertEquals("-1 1/2147483647", f.toProperString());
 *
 *      assertEquals("-1", Fraction.of(-1).toProperString());
 *  }
 */

    /**
     * Assert the specified operation on the fraction throws the expected type.
     * This method exists to ensure the fractions are constructed without an exception
     * and the operation is tested to throw the exception.
     *
     * @param <T> the generic type
     * @param expectedType the expected type
     * @param f the fraction
     * @param operation the operation
     * @return the throwable
     */
    private static <T extends Throwable> T assertOperationThrows(Class<T> expectedType,
            Fraction f, UnaryOperator<Fraction> operation) {
        return assertThrows(expectedType, () -> operation.apply(f));
    }

    /**
     * Assert the specified operation on two fractions throws the expected type.
     * This method exists to ensure the fractions are constructed without an exception
     * and the operation is tested to throw the exception.
     *
     * @param <T> the generic type
     * @param expectedType the expected type
     * @param f1 the first fraction
     * @param f2 the second fraction
     * @param operation the operation
     * @return the throwable
     */
    private static <T extends Throwable> T assertOperationThrows(Class<T> expectedType,
            Fraction f1, Fraction f2, BiFunction<Fraction, Fraction, Fraction> operation) {
        return assertThrows(expectedType, () -> operation.apply(f1, f2));
    }
}
