#include #include #include "fraction.hpp" using namespace FractionNS; class FractionTest : public QObject { Q_OBJECT public: FractionTest(); ~FractionTest(); private slots: void test_constructor(); void test_display(); void test_equivalence(); void test_addition(); void test_inequivalence(); void test_substraction(); void test_multiplication(); void test_division(); void test_negation(); void test_unary_plus(); void test_less_than(); void test_greater_than(); void test_less_than_or_equal(); void test_greater_than_or_equal(); void test_inverse(); void test_pow(); void test_math_methods(); void test_increment(); void test_decrement(); }; FractionTest::FractionTest() { qDebug(); }; FractionTest::~FractionTest() {}; void FractionTest::test_constructor() { // Normal fraction Fraction f1 = Fraction(1, 2); QCOMPARE(f1.getNumerator(), 1); QCOMPARE(f1.getDenominator(), 2); // Reducible fraction Fraction f2 = Fraction(2, 4); QCOMPARE(f2.getNumerator(), 1); QCOMPARE(f2.getDenominator(), 2); // Negative fractions Fraction f3 = Fraction(-1, 3); QCOMPARE(f3.getNumerator(), -1); QCOMPARE(f3.getDenominator(), 3); Fraction f4 = Fraction(1, -3); QCOMPARE(f4.getNumerator(), -1); QCOMPARE(f4.getDenominator(), 3); // Double negative (positive) fraction Fraction f5 = Fraction(-2, -3); QCOMPARE(f5.getNumerator(), 2); QCOMPARE(f5.getDenominator(), 3); // Zero Fraction f6 = Fraction(0); QCOMPARE(f6.getNumerator(), 0); Fraction f7 = Fraction(0, 3); QCOMPARE(f7.getNumerator(), 0); QCOMPARE(f6.getDenominator(), f7.getDenominator()); // Invalid zero fraction bool threw_divide_by_zero_error = false; try { Fraction(2, 0); } catch (const divide_by_zero_error&) { threw_divide_by_zero_error = true; } QVERIFY(threw_divide_by_zero_error); } void FractionTest::test_display() { // Normal fraction Fraction f1 = Fraction(1, 2); QCOMPARE(f1.display(), "1/2"); Fraction f2 = Fraction(1, 3); QCOMPARE(f2.display(), "1/3"); // Fractions that reduce Fraction f3 = Fraction(2, 4); QCOMPARE(f3.display(), "1/2"); Fraction f4 = Fraction(982929, 123456); QCOMPARE(f4.display(), "327643/41152"); // Negative Fractions Fraction f5 = Fraction(-5, 2); QCOMPARE(f5.display(), "-5/2"); } void FractionTest::test_equivalence() { Fraction f1 = Fraction(1, 1); Fraction f2 = Fraction(1, 1); Fraction f3 = Fraction(-1, 1); QCOMPARE(f1, f2); QCOMPARE(f1, 1); QCOMPARE(f1, 1.0); QCOMPARE(f1, 1.0f); QCOMPARE(f2, 1); QCOMPARE(f2, 1.0); QCOMPARE(f2, 1.0f); QCOMPARE(f3, -1); QCOMPARE(f3, -1.0); QCOMPARE(f3, -1.0f); Fraction f4 = Fraction(2, 3); Fraction f5 = Fraction(-2, 3); Fraction f6 = Fraction(2, -3); Fraction f7 = Fraction(-2, -3); QCOMPARE(f4, f7); QCOMPARE(f5, f6); QCOMPARE(f4, 2.0f / 3.0f); QCOMPARE(f4, 2.0 / 3.0); QCOMPARE(f7, 2.0f / 3.0f); QCOMPARE(f7, 2.0 / 3.0); QCOMPARE(f5, -2.0f / 3.0f); QCOMPARE(f5, -2.0 / 3.0); QCOMPARE(f6, -2.0f / 3.0f); QCOMPARE(f6, -2.0 / 3.0); } void FractionTest::test_inequivalence() { Fraction f1 = Fraction(1, 1); Fraction f2 = Fraction(-1, 1); Fraction f3 = Fraction(2, 3); QVERIFY(f1 != f2); QVERIFY(f2 != f3); QVERIFY(f3 != f1); QVERIFY(f3 != 1); QVERIFY(f3 != 1.0); QVERIFY(f3 != 1.0f); } void FractionTest::test_addition() { Fraction f1 = Fraction(1, 2); QCOMPARE(f1 + 1, 1.5f); QCOMPARE(f1, 0.5f); f1 += 1; QCOMPARE(f1, 1.5); Fraction f2 = Fraction(1, 2); QCOMPARE(f2 + 1, 1.5f); QCOMPARE(f2, 0.5f); Fraction f3 = Fraction(-2, 9); QCOMPARE(f3, -(2.0 / 9.0)); QCOMPARE(f3, -(2.0f / 9.0f)); f3 += Fraction(2, 9); QCOMPARE(f3, 0); QCOMPARE(f3, 0.0); QCOMPARE(f3, 0.0f); } void FractionTest::test_substraction() { Fraction f1 = Fraction(11) - 10; QCOMPARE(f1, 1); Fraction f2 = Fraction(2, 3); QCOMPARE(f1 - f2, Fraction(1, 3)); QCOMPARE(f2 - f1, Fraction(-1, 3)); Fraction f3 = Fraction(8, 3); f3 -= Fraction(2, 3); QCOMPARE(f3, Fraction(6, 3)); Fraction f4 = Fraction(9, 3); f4 -= 3; QCOMPARE(f4, 0); Fraction f5 = Fraction(8, 3); // (8/3) - ((2/3) - 1) //=(8/3) + (1/3) //= 9/3 //= 3 f5 -= Fraction(2, 3) - 1; QCOMPARE(f5, 3); Fraction f6 = Fraction(-2, 199); // (-2/199) + 8 //=(-2/199) + (1592/199 //=(1590/199) f6 -= Fraction(-4) - 4; QCOMPARE(f6, Fraction(1590, 199)); } void FractionTest::test_multiplication() { Fraction f1 = Fraction(1, 1); const Fraction f2 = Fraction(2, 1); QCOMPARE(f1 * 2, f2); f1 *= 2; QCOMPARE(f1, f2); f1 *= 3; QCOMPARE(f1, 6); QCOMPARE(f1 * Fraction(2, 3), 4); } void FractionTest::test_division() { Fraction f1 = Fraction(1, 1); const Fraction f2 = Fraction(1, 2); QCOMPARE(f1 / 2, f2); f1 /= 2; QCOMPARE(f1, 0.5); QCOMPARE(f1 / 2, 0.25); QCOMPARE((f1 / 2) / Fraction(2, 3), Fraction(3, 8)); } void FractionTest::test_negation() { const Fraction f1 = Fraction(-1, 2); const Fraction f2 = Fraction(1, 2); QCOMPARE(-f1, f2); QCOMPARE(-f2, f1); } void FractionTest::test_unary_plus() { const Fraction f1 = Fraction(2, 3); const Fraction f2 = +f1; QCOMPARE(f1, f2); // Check that it's actually a new Fraction. QVERIFY(&f1 != &f2); } void FractionTest::test_less_than() { const Fraction f1 = Fraction(9, 2); QVERIFY(f1 < 5); QVERIFY(f1 < 9.0); QVERIFY(f1 < 6.0f); QVERIFY(!(f1 < (9.0/2.0))); QVERIFY(!(f1 < 0)); const Fraction large_positive = Fraction(1000000, 17); const Fraction positive = Fraction(9, 8); const Fraction zero = Fraction(0); const Fraction negative = Fraction(-9, 8); const Fraction large_negative = Fraction(-1000000, 17); QVERIFY(large_negative < large_positive); QVERIFY(negative < large_positive); QVERIFY(zero < large_positive); QVERIFY(positive < large_positive); QVERIFY(!(large_positive < large_positive)); QVERIFY(large_negative < positive); QVERIFY(negative < positive); QVERIFY(zero < positive); QVERIFY(!(positive < positive)); QVERIFY(!(large_positive < positive)); QVERIFY(large_negative < zero); QVERIFY(negative < zero); QVERIFY(!(zero < zero)); QVERIFY(!(positive < zero)); QVERIFY(!(large_positive < zero)); QVERIFY(large_negative < negative); QVERIFY(!(negative < negative)); QVERIFY(!(zero < negative)); QVERIFY(!(positive < negative)); QVERIFY(!(large_positive < negative)); QVERIFY(!(large_negative < large_negative)); QVERIFY(!(negative < large_negative)); QVERIFY(!(zero < large_negative)); QVERIFY(!(positive < large_negative)); QVERIFY(!(large_positive < large_negative)); } void FractionTest::test_greater_than() { const Fraction f1 = Fraction(-9, 2); QVERIFY(f1 > -5); QVERIFY(f1 > -9.0); QVERIFY(f1 > -6.0f); QVERIFY(!(f1 > -(9.0/2.0))); QVERIFY(!(f1 > 0)); const Fraction large_positive = Fraction(1000000, 17); const Fraction positive = Fraction(9, 8); const Fraction zero = Fraction(0); const Fraction negative = Fraction(-9, 8); const Fraction large_negative = Fraction(-1000000, 17); QVERIFY(!(large_negative > large_negative)); QVERIFY(negative > large_negative); QVERIFY(zero > large_negative); QVERIFY(positive > large_negative); QVERIFY(large_positive > large_negative); QVERIFY(!(large_negative > negative)); QVERIFY(!(negative > negative)); QVERIFY(zero > negative); QVERIFY(positive > negative); QVERIFY(large_positive > negative); QVERIFY(!(large_negative > zero)); QVERIFY(!(negative > zero)); QVERIFY(!(zero > zero)); QVERIFY(positive > zero); QVERIFY(large_positive > zero); QVERIFY(!(large_negative > positive)); QVERIFY(!(negative > positive)); QVERIFY(!(zero > positive)); QVERIFY(!(positive > positive)); QVERIFY(large_positive > positive); QVERIFY(!(large_negative > large_positive)); QVERIFY(!(negative > large_positive)); QVERIFY(!(zero > large_positive)); QVERIFY(!(positive > large_positive)); QVERIFY(!(large_positive > large_positive)); } void FractionTest::test_less_than_or_equal() { const Fraction f1 = Fraction(9, 2); QVERIFY(f1 <= 5); QVERIFY(f1 <= 9.0); QVERIFY(f1 <= 6.0f); QVERIFY(f1 <= (9.0 / 2.0)); QVERIFY(!(f1 <= 0)); const Fraction large_positive = Fraction(1000000, 17); const Fraction positive = Fraction(9, 8); const Fraction zero = Fraction(0); const Fraction negative = Fraction(-9, 8); const Fraction large_negative = Fraction(-1000000, 17); QVERIFY(large_negative <= large_positive); QVERIFY(negative <= large_positive); QVERIFY(zero <= large_positive); QVERIFY(positive <= large_positive); QVERIFY(large_positive <= large_positive); QVERIFY(large_negative <= positive); QVERIFY(negative <= positive); QVERIFY(zero <= positive); QVERIFY(positive <= positive); QVERIFY(!(large_positive <= positive)); QVERIFY(large_negative <= zero); QVERIFY(negative <= zero); QVERIFY(zero <= zero); QVERIFY(!(positive <= zero)); QVERIFY(!(large_positive <= zero)); QVERIFY(large_negative <= negative); QVERIFY(negative <= negative); QVERIFY(!(zero <= negative)); QVERIFY(!(positive <= negative)); QVERIFY(!(large_positive <= negative)); QVERIFY(large_negative <= large_negative); QVERIFY(!(negative <= large_negative)); QVERIFY(!(zero <= large_negative)); QVERIFY(!(positive <= large_negative)); QVERIFY(!(large_positive <= large_negative)); } void FractionTest::test_greater_than_or_equal() { const Fraction f1 = Fraction(-9, 2); QVERIFY(f1 >= -5); QVERIFY(f1 >= -9.0); QVERIFY(f1 >= -6.0f); QVERIFY(f1 >= -(9.0 / 2.0)); QVERIFY(!(f1 >= 0)); const Fraction large_positive = Fraction(1000000, 17); const Fraction positive = Fraction(9, 8); const Fraction zero = Fraction(0); const Fraction negative = Fraction(-9, 8); const Fraction large_negative = Fraction(-1000000, 17); QVERIFY(large_negative >= large_negative); QVERIFY(negative >= large_negative); QVERIFY(zero >= large_negative); QVERIFY(positive >= large_negative); QVERIFY(large_positive >= large_negative); QVERIFY(!(large_negative >= negative)); QVERIFY(negative >= negative); QVERIFY(zero >= negative); QVERIFY(positive >= negative); QVERIFY(large_positive >= negative); QVERIFY(!(large_negative >= zero)); QVERIFY(!(negative >= zero)); QVERIFY(zero >= zero); QVERIFY(positive >= zero); QVERIFY(large_positive >= zero); QVERIFY(!(large_negative >= positive)); QVERIFY(!(negative >= positive)); QVERIFY(!(zero >= positive)); QVERIFY(positive >= positive); QVERIFY(large_positive >= positive); QVERIFY(!(large_negative >= large_positive)); QVERIFY(!(negative >= large_positive)); QVERIFY(!(zero >= large_positive)); QVERIFY(!(positive >= large_positive)); QVERIFY(large_positive >= large_positive); } void FractionTest::test_inverse() { const Fraction f1 = Fraction(3, 2); const Fraction f2 = Fraction(2, 3); QCOMPARE(f1.inv(), f2); QCOMPARE(f2.inv(), f1); const Fraction f3 = Fraction(0, 2); bool threw_divide_by_zero_error = false; try { f3.inv(); } catch (const divide_by_zero_error&) { threw_divide_by_zero_error = true; } QVERIFY(threw_divide_by_zero_error); } void FractionTest::test_pow() { const Fraction f1 = Fraction(2, 3); const Fraction f2 = Fraction(3, 2); const Fraction f3 = Fraction(4, 9); const Fraction f4 = Fraction(9, 4); QCOMPARE(f3, f1.pow(2)); QCOMPARE(f4, f2.pow(2)); const Fraction f5 = Fraction(9); const Fraction f6 = Fraction(1, 9); const Fraction f7 = Fraction(1, 81); // x ** -y = (1 / x) ** y QCOMPARE(f6, f5.pow(-1)); QCOMPARE(f7, f5.pow(-2)); const Fraction f8 = Fraction(16); // x ** (1/y) = root_y(x) QCOMPARE(f8.pow(Fraction(1, 2)), 4.0); // x ** 0 = 1; (where x != 0 and x ∈ R) // 0 ** 0 depends on context QCOMPARE(f1.pow(0), 1.0); bool threw_not_defined_error = false; try { Fraction(0, 2).pow(0); } catch (const not_defined_error&) { threw_not_defined_error = true; } QVERIFY(threw_not_defined_error); bool threw_not_real_error = false; try { Fraction(0, 1).pow(-1); } catch (const not_real_error&) { threw_not_real_error = true; } QVERIFY(threw_not_real_error); } void FractionTest::test_math_methods() { const Fraction f1 = Fraction(9, 7); const Fraction f2 = Fraction(3, 1); QCOMPARE(f1 + 3, f1.add(3)); QCOMPARE(f1 + f2, f1.add(f2)); QCOMPARE(f1 - 3, f1.sub(3)); QCOMPARE(f1 - f2, f1.sub(f2)); QCOMPARE(f1 * 3, f1.mul(3)); QCOMPARE(f1 * f2, f1.mul(f2)); QCOMPARE(f1 / 3, f1.div(3)); QCOMPARE(f1 / f2, f1.div(f2)); } void FractionTest::test_increment() { Fraction f1 = Fraction(2); const Fraction f2 = f1 + 1; const Fraction f3 = f2 + 1; const Fraction f4 = f3 + 1; QCOMPARE(++f1, f2); QCOMPARE(f1++, f2); QCOMPARE(f1, f3); QCOMPARE(f1.inc(), f4); } void FractionTest::test_decrement() { Fraction f1 = Fraction(2); const Fraction f2 = f1 - 1; const Fraction f3 = f2 - 1; const Fraction f4 = f3 - 1; QCOMPARE(--f1, f2); QCOMPARE(f1--, f2); QCOMPARE(f1, f3); QCOMPARE(f1.dec(), f4); } QTEST_APPLESS_MAIN(FractionTest) #include "tst_fractiontest.moc"