"""Tests for function exercises"""
from helpers import BaseTestCase
from functions import (
    get_hypotenuse,
    parse_time,
    format_time,
    coalesce,
    to_percent,
    to_celsius,
    is_leap_year,
    is_perfect_square,
)


class GetHypotenuseTests(BaseTestCase):

    """Tests for get_hypotenuse."""

    def test_3_and_4(self):
        self.assertEqual(get_hypotenuse(3, 4), 5.0)

    def test_5_and_12(self):
        self.assertEqual(get_hypotenuse(5, 12), 13.0)


class ParseTimeTests(BaseTestCase):

    """Tests for parse_time."""

    def test_valid_times(self):
        self.assertEqual(parse_time("05:30"), 330)
        self.assertEqual(parse_time("02:45"), 165)
        self.assertEqual(parse_time("10:00"), 600)
        self.assertEqual(parse_time("00:15"), 15)
        self.assertEqual(parse_time("15:00"), 900)
        self.assertEqual(parse_time("01:00"), 60)

    def test_edge_case_times(self):
        self.assertEqual(parse_time("00:00"), 0)
        self.assertEqual(parse_time("01:01"), 61)
        self.assertEqual(parse_time("23:59"), 1439)


class FormatTimeTests(BaseTestCase):

    """Tests for format_time."""

    def test_format_time_single_digit_seconds(self):
        self.assertEqual(format_time(65), "1:05")
        self.assertEqual(format_time(301), "5:01")

    def test_format_time_even_minutes(self):
        self.assertEqual(format_time(120), "2:00")
        self.assertEqual(format_time(600), "10:00")
        self.assertEqual(format_time(180), "3:00")
        self.assertEqual(format_time(3600), "60:00")

    def test_format_time_double_digit_seconds(self):
        self.assertEqual(format_time(75), "1:15")
        self.assertEqual(format_time(119), "1:59")
        self.assertEqual(format_time(3715), "61:55")

    def test_format_time_zero_seconds(self):
        self.assertEqual(format_time(0), "0:00")

    def test_format_time_large_seconds(self):
        self.assertEqual(format_time(86400), "1440:00")
        self.assertEqual(format_time(90061), "1501:01")


class CoalesceTests(BaseTestCase):

    """Tests for coalesce."""

    def test_coalesce_to_empty_string(self):
        self.assertEqual(coalesce("Trey", ""), "Trey")
        self.assertEqual(coalesce("", ""), "")
        self.assertEqual(coalesce(None, ""), "")
        self.assertEqual(coalesce(4, ""), 4)

    def test_coalasce_to_empty_list(self):
        self.assertEqual(coalesce("Trey", []), "Trey")
        self.assertEqual(coalesce("", []), "")
        self.assertEqual(coalesce(None, []), [])
        self.assertEqual(coalesce([1, 2, 3], []), [1, 2, 3])
        x = []
        self.assertEqual(coalesce(x, []), x)
        self.assertIs(coalesce(x, []), x)


class ToPercentTests(BaseTestCase):

    """Tests for to_percent."""

    def test_100_percent(self):
        self.assertEqual(to_percent(1.0), "100.0%")

    def test_50_percent(self):
        self.assertEqual(to_percent(0.5), "50.0%")

    def test_less_than_one_percent(self):
        self.assertEqual(to_percent(0.0054), "0.5%")

    def test_rounds_up(self):
        self.assertEqual(to_percent(0.1347), "13.5%")

    def test_one_third(self):
        self.assertEqual(to_percent(1.0 / 3), "33.3%")


class ToCelsiusTests(BaseTestCase):

    """Tests for to_celsius."""

    def test_freezing(self):
        self.assertEqual(to_celsius(32), 0.0)

    def test_boiling(self):
        self.assertEqual(to_celsius(212), 100.0)


class IsLeapYearTests(BaseTestCase):

    """Tests for is_leap_year."""

    def test_2000(self):
        self.assertEqual(is_leap_year(2000), True)

    def test_1996(self):
        self.assertEqual(is_leap_year(1996), True)

    def test_2016(self):
        self.assertEqual(is_leap_year(2016), True)

    def test_1600(self):
        self.assertEqual(is_leap_year(1600), True)

    def test_1900(self):
        self.assertEqual(is_leap_year(1900), False)


class IsPerfectSquareTests(BaseTestCase):

    """Tests for is_perfect_square."""

    def test_small_number(self):
        self.assertTrue(is_perfect_square(1))
        self.assertTrue(is_perfect_square(4))
        self.assertFalse(is_perfect_square(8))
        self.assertFalse(is_perfect_square(35))

    def test_4_digit_number(self):
        self.assertTrue(is_perfect_square(5776))
        self.assertFalse(is_perfect_square(9306))

    def test_big_number(self):
        self.assertTrue(is_perfect_square(1586375448590241))
        self.assertFalse(is_perfect_square(1420958445736851))


if __name__ == "__main__":
    from helpers import error_message

    error_message()
