#!/usr/bin/env python3
import murd
import unittest


class MyTestCase(unittest.TestCase):

    def test_plus(self):
        res = murd.Murd(2, 5).plus(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(2, 3), res, "2/5 + 4/15 peab olema 2/3")
        res = murd.Murd(-2, 5).plus(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(-2, 15), res, "-2/5 + 4/15 peab olema -2/15")

    def test_minus(self):
        res = murd.Murd(2, 5).minus(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(2, 15), res, "2/5 - 4/15 peab olema 2/15")
        res = murd.Murd(-2, 5).minus(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(-2, 3), res, "-2/5 - 4/15 peab olema -2/3")

    def test_opposite(self):
        res = murd.Murd(-3, 5).opposite()
        self.assertEqual(murd.Murd(3, 5), res, "-3/5 vastandarv peaks olema 3/5")
        res = murd.Murd(3, 5).opposite()
        self.assertEqual(murd.Murd(-3, 5), res, "3/5 vastandarv peaks olema -3/5")

    def test_times(self):
        res = murd.Murd(3, 4).times(murd.Murd(6, 7))
        self.assertEqual(murd.Murd(9, 14), res, "3/4 * 6/7 peab olema 9/14")
        res = murd.Murd(-3, 4).times(murd.Murd(-6, 7))
        self.assertEqual(murd.Murd(9, 14), res, "-3/4 * -6/7 peab olema 9/14")

    def test_divide_by(self):
        res = murd.Murd(2, 5).divide_by(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(3, 2), res, "2/5 / 4/15 peab olema 3/2")
        res = murd.Murd(-2, 5).divide_by(murd.Murd(4, 15))
        self.assertEqual(murd.Murd(-3, 2), res, "-2/5 / 4/15 peab olema -3/2")

    def test_div_by_zero(self):
        with self.assertRaises(ZeroDivisionError, msg="nulliga jagamine peaks olema viga"):
            murd.Murd(3, 4).divide_by(murd.Murd(0, 3))

    def test_inverse(self):
        res = murd.Murd(-3, 5).inverse()
        self.assertEqual(murd.Murd(-5, 3), res, "-3/5 p66rdarv peaks olema -5/3")
        res = murd.Murd(33, 5).inverse()
        self.assertEqual(murd.Murd(5, 33), res, "33/5 p66rdarv peaks olema 5/33")

    def test_inverse_zero(self):
        with self.assertRaises(ZeroDivisionError, msg="nulli p66ramine peaks olema viga"):
            murd.Murd(0, 3).inverse()

    def test_parse_murd(self):
        res = murd.Murd.parse_murd("2/-4")
        self.assertEqual(murd.Murd(-1, 2), res, "'2/-4' peaks andma murru -1/2")

    def test_parse_murd_invalid(self):
        with self.assertRaises(Exception, msg="Tundmatu symbol ei tohi olla t6lgendatav murruna"):
            murd.Murd.parse_murd("2x/7")

    def test_lt(self):
        res = murd.Murd(2, 5) < murd.Murd(4, 7)
        self.assertEqual(True, res, "2/5 peab olema v2iksem kui 4/7")
        res = murd.Murd(4, 7) < murd.Murd(2, 5)
        self.assertEqual(False, res, "2/5 peab olema v2iksem kui 4/7")

    def test_gt(self):
        res = murd.Murd(2, 5) > murd.Murd(4, 7)
        self.assertEqual(False, res, "2/5 peab olema v2iksem kui 4/7")
        res = murd.Murd(4, 7) > murd.Murd(2, 5)
        self.assertEqual(True, res, "2/5 peab olema v2iksem kui 4/7")

    def test_le(self):
        res = murd.Murd(2, 5) <= murd.Murd(4, 7)
        self.assertEqual(True, res, "2/5 peab olema v2iksem-v6rdne kui 4/7")
        res = murd.Murd(2, 5) <= murd.Murd(2, 5)
        self.assertEqual(True, res, "2/5 peab olema v2iksem-v6rdne kui 2/5")

    def test_ge(self):
        res = murd.Murd(2, 5) >= murd.Murd(4, 7)
        self.assertEqual(False, res, "2/5 peab olema v2iksem-v6rdne kui 4/7")
        res = murd.Murd(4, 7) >= murd.Murd(4, 7)
        self.assertEqual(True, res, "4/7 peab olema suurem-v6rdne kui 4/7")

    def test_eq(self):
        res = murd.Murd(249, 109) == murd.Murd(148, 5)  # 386/3 86/113
        self.assertEqual(False, res, "249/109 ei ole 148/5")  # hash collision
        res = murd.Murd(2, 5) == murd.Murd(4, 10)
        self.assertEqual(True, res, "2/5 peab olema 4/10")

    def test_exact(self):
        res = murd.Murd(12345678901234567, 1) == \
            murd.Murd(12345678901234568, 1)
        self.assertEqual(False, res,
                         "12345678901234567/1 != 12345678901234568/1")

    def test_neq(self):
        res = murd.Murd(2, 5) != murd.Murd(4, 7)
        self.assertEqual(True, res, "2/5 ei ole 4/7")
        res = murd.Murd(2, 5) != murd.Murd(4, 10)
        self.assertEqual(False, res, "2/5 peab olema 4/10")


if __name__ == '__main__':
    unittest.main()
