#!/usr/bin/env python3

from __future__ import division
from __future__ import print_function

import unittest

from romans import RomanNumeral


class RomansTests(unittest.TestCase):
    """
    Tests for RomanNumeral.
    """

    def test_base_four(self):
        four = RomanNumeral("IV")
        self.assertEqual(int(four), 4)

    def test_base_illegal_forms(self):
        with self.assertRaises(ValueError) as context:
            RomanNumeral("VX")
        self.assertEqual(
            str(context.exception),
            "'VX' is not allowed in RomanNumeral"
        )
        with self.assertRaises(ValueError) as context:
            RomanNumeral("VVVV")
        self.assertEqual(
            str(context.exception),
            "'VVVV' is not allowed in RomanNumeral"
        )

    def test_base_five(self):
        five = RomanNumeral("V")
        self.assertEqual(int(five), 5)

    def test_base_big(self):
        year = RomanNumeral("MMXX")
        self.assertEqual(int(year), 2020)

        year = RomanNumeral("MCMLXXVIII")
        self.assertEqual(int(year), 1978)

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus_1(self):
        year = RomanNumeral("MCMLXXVIII")
        self.assertEqual(repr(year), "RomanNumeral('MCMLXXVIII')")
        self.assertEqual(str(year), "MCMLXXVIII")

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus_2(self):
        year = RomanNumeral.from_int(1978)
        self.assertEqual(repr(year), "RomanNumeral('MCMLXXVIII')")
        self.assertEqual(str(year), "MCMLXXVIII")
        for i in range(1, 2345, 33):
            self.assertEqual(int(RomanNumeral.from_int(i)), i)

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus_3(self):
        two = RomanNumeral("II")
        four = RomanNumeral("IV")
        five = RomanNumeral("V")
        self.assertEqual(int(two + two), 4)
        self.assertEqual(int(four - two), 2)
        self.assertEqual(int(five * two), 10)

        self.assertEqual(int(two + 2), 4)
        self.assertEqual(int(four - 2), 2)
        self.assertEqual(int(two * 5), 10)

        self.assertEqual(int(2 + two), 4)
        self.assertEqual(int(6 - four), 2)
        self.assertEqual(int(5 * two), 10)

    # Comment the following line to force the check the bonus code
    @unittest.expectedFailure
    def test_bonus_4(self):
        two = RomanNumeral("II")
        four = RomanNumeral("IV")
        five = RomanNumeral("V")
        self.assertEqual(two, 2)
        self.assertEqual(two, two)
        self.assertEqual(four, two + two)
        self.assertEqual(four, "IV")
        self.assertEqual(RomanNumeral.from_int(1978), "MCMLXXVIII")

        self.assertTrue(two != four)
        self.assertTrue(two < four)
        self.assertTrue(two <= four)
        self.assertTrue(four > two)
        self.assertTrue(four >= two)

        self.assertTrue(five < 10)
        self.assertTrue(five <= 10)
        self.assertTrue(10 > five)
        self.assertTrue(10 >= five)

        with self.assertRaises(TypeError) as context:
            five < "VI"
        self.assertEqual(str(context.exception), "'<' not supported between instances of 'RomanNumeral' and 'str'")

        with self.assertRaises(TypeError) as context:
            five > "VI"
        self.assertEqual(str(context.exception), "'>' not supported between instances of 'RomanNumeral' and 'str'")


if __name__ == "__main__":
    unittest.main(verbosity=2)
