#!/usr/bin/env python3

# Ragnar Toomla variant lyhendatud

import unittest
from unittest import TestCase
import kompleksarv as k
import math


class TestKompleksarv(TestCase):
    # testib kas tekstiline kuju on õige
    def test_str(self):
        self.assertEqual('1.0+2.0i', str(k.Kompleksarv(1,2)))
        self.assertEqual('-1.0+0.0i', str(k.Kompleksarv(-1,0)))
        self.assertEqual('0.0-2.0i', str(k.Kompleksarv(0,-2)))
        self.assertEqual('1.0-2.0i', str(k.Kompleksarv(1,-2)))

    # testib kas tekib viga kui parameetrid ei ole reaalarvud
    def test_init_typeError(self):
        with self.assertRaises(Exception):
            k.Kompleksarv("a", 1)
            k.Kompleksarv(1, "a")
            k.Kompleksarv(True, 1)
            k.Kompleksarv(1, False)

    # testib kas on tõene kui Kompleksarv ei võrdu nulliga ja väär, kui võrdub nulliga
    def test_boolean(self):
        self.assertTrue(k.Kompleksarv(1, 1))
        self.assertTrue(k.Kompleksarv(0, 1))
        self.assertTrue(k.Kompleksarv(1, 0))
        self.assertFalse(k.Kompleksarv(0, 0))

    # testib reaalosa tagastamist
    def test_reaalosa(self):
        self.assertEqual(1, k.Kompleksarv.reaalosa(k.Kompleksarv(1,2)))
        self.assertEqual(-1, k.Kompleksarv.reaalosa(k.Kompleksarv(-1,2)))
        self.assertEqual(0, k.Kompleksarv.reaalosa(k.Kompleksarv(0,0)))

    # testib imaginaarosa tagastamist
    def test_imaginaarosa(self):
        self.assertEqual(2, k.Kompleksarv.imaginaarosa(k.Kompleksarv(1,2)))
        self.assertEqual(-2, k.Kompleksarv.imaginaarosa(k.Kompleksarv(1,-2)))
        self.assertEqual(0, k.Kompleksarv.imaginaarosa(k.Kompleksarv(0,0)))

    # testib kaaskompleksarvu tagastamist
    def test_kaaskompleksarv(self):
        self.assertEqual('1.0-2.0i', str(k.Kompleksarv.kaaskompleksarv(k.Kompleksarv(1, 2))))
        self.assertEqual('1.0+2.0i', str(k.Kompleksarv.kaaskompleksarv(k.Kompleksarv(1, -2))))
        self.assertEqual('0.0+0.0i', str(k.Kompleksarv.kaaskompleksarv(k.Kompleksarv(0, 0))))
        self.assertEqual('0.0+1.0i', str(k.Kompleksarv.kaaskompleksarv(k.Kompleksarv(0, -1))))

    # testib pöördarvu tagastamist
    def test_poordarv(self):
        self.assertEqual('0.2-0.4i', str(k.Kompleksarv.poordarv(k.Kompleksarv(1, 2))))
        self.assertEqual('0.2+0.4i', str(k.Kompleksarv.poordarv(k.Kompleksarv(1, -2))))

    def test_poordarv_zerodivisionerror(self):
        with self.assertRaises(Exception):
            k.Kompleksarv.poordarv(k.Kompleksarv(0, 0))

    # Kompleksarvu mooduli test
    def test_moodul(self):
        self.assertAlmostEqual(math.sqrt(5), k.Kompleksarv.moodul(k.Kompleksarv(1,2)), places=7)

    # testime võrdsuse kontrolli
    def test_eq(self):
        a = k.Kompleksarv(4, 6)
        b = k.Kompleksarv(4, 6)
        c = k.Kompleksarv(8, 12)
        d = k.Kompleksarv(4, -6)
        self.assertTrue(a == b)
        self.assertFalse(a == c)
        self.assertFalse(a == d)

    # liitmine
    def test_add(self):
        self.assertEqual('6.0+0.0i', str(k.Kompleksarv(3, 2) + k.Kompleksarv(3, -2)))
        self.assertEqual('2.0+4.0i', str(k.Kompleksarv(1, 2) + k.Kompleksarv(1, 2)))
        self.assertEqual('0.0+0.0i', str(k.Kompleksarv(0, 0) + k.Kompleksarv(0, 0)))

    # lahutamine
    def test_sub(self):
        self.assertEqual('6.0+0.0i', str(k.Kompleksarv(9, 2) - k.Kompleksarv(3, 2)))
        self.assertEqual('0.0+0.0i', str(k.Kompleksarv(1, 2) - k.Kompleksarv(1, 2)))
        self.assertEqual('0.0+4.0i', str(k.Kompleksarv(1, 2) - k.Kompleksarv(1, -2)))
        self.assertEqual('0.0+0.0i', str(k.Kompleksarv(0, 0) - k.Kompleksarv(0, 0)))

    # korrutamine
    def test_mul(self):
        self.assertEqual('13.0+0.0i', str(k.Kompleksarv(3, 2) * k.Kompleksarv(3, -2)))
        self.assertEqual('5.0+12.0i', str(k.Kompleksarv(3, 2) * k.Kompleksarv(3, 2)))
        self.assertEqual('0.0+0.0i', str(k.Kompleksarv(0, 0) * k.Kompleksarv(3, 2)))
        self.assertEqual('-4.0+2.0i', str(k.Kompleksarv(0, 2) * k.Kompleksarv(1, 2)))
        self.assertEqual('0.0+6.0i', str(k.Kompleksarv(3, 0) * k.Kompleksarv(0, 2)))

    # Kompleksarvu vastandarv
    def test_neg(self):
        self.assertEqual('-1.0-2.0i', str(-k.Kompleksarv(1, 2)))
        self.assertEqual('1.0+2.0i', str(-k.Kompleksarv(-1, -2)))

    # jagamine
    def test_truediv(self):
        self.assertEqual('0.5+0.0i', str(k.Kompleksarv(1, 1) / k.Kompleksarv(2, 2)))
        self.assertEqual('0.0+1.0i', str(k.Kompleksarv(1, 1) / k.Kompleksarv(1, -1)))  # küsi järgi, mis on õige (i või 1i) https://www.hackmath.net/en/calculator/complex-number?input=%281%2B1i%29%2F%281-1i%29&submit=Calculate

    # jagamine nulliga
    def test_truediv_zerodivisionerror(self):
        with self.assertRaises(Exception):
            k.Kompleksarv(1, 1) / k.Kompleksarv(0, 0)

    # teisendamine stringist ebasobiv sisend
    def test_parse_kompleksarv_input(self):
        with self.assertRaises(Exception):
            k.Kompleksarv.parse_kompleksarv("midagi muud")
            k.Kompleksarv.parse_kompleksarv("")

    # testib polaarkuju argumendi peaväärtuse arvutamist
    def test_nurk(self):
        self.assertAlmostEqual(math.pi / 12, k.Kompleksarv.nurk(k.Kompleksarv(2 + math.sqrt(3), 1)))
        self.assertAlmostEqual(str(-math.pi / 4), str(k.Kompleksarv.nurk(k.Kompleksarv(1, -1))), places=7)
        self.assertAlmostEqual(str(-3 / 4 * math.pi), str(k.Kompleksarv.nurk(k.Kompleksarv(-1, -1))), places=7)
        self.assertAlmostEqual(str(math.pi / 2), str(k.Kompleksarv.nurk(k.Kompleksarv(0, 1))), places=7)
        self.assertAlmostEqual(str(-math.pi / 2), str(k.Kompleksarv.nurk(k.Kompleksarv(0, -1))), places=7)


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

