"""Tests for loop exercises"""
from helpers import BaseTestCase
from loops import (
    get_vowel_names,
    sum_timestamps,
    product,
    sum_all,
    flatten,
    matrix_from_string,
    words_containing,
    are_consecutive,
)


class GetVowelNamesTests(BaseTestCase):

    """Tests for get_vowel_names."""

    def test_one_vowel_name(self):
        self.assertEqual(
            get_vowel_names(["Alice", "Bob", "Christy", "Jules"]),
            ["Alice"],
        )

    def test_multiple_vowel_names(self):
        self.assertEqual(
            get_vowel_names(["Scott", "arthur", "Jan", "Elizabeth"]),
            ["arthur", "Elizabeth"],
        )

    def test_empty(self):
        self.assertEqual(get_vowel_names([]), [])


class TestSumTimestamps(BaseTestCase):

    """Tests for sum_timestamps."""

    def test_sum_timestamps_valid_input(self):
        self.assertEqual(sum_timestamps(["05:30", "02:45", "10:00"]), "18:15")
        self.assertEqual(sum_timestamps(["5:30", "2:45", "10:00"]), "18:15")
        self.assertEqual(sum_timestamps(["00:15", "15:00", "01:00"]), "16:15")
        self.assertEqual(sum_timestamps(["0:15", "15:00", "1:00"]), "16:15")
        self.assertEqual(sum_timestamps(["01:00", "02:00", "03:00"]), "6:00")
        self.assertEqual(sum_timestamps(["10:00", "05:30", "02:45"]), "18:15")

    def test_sum_timestamps_edge_cases(self):
        self.assertEqual(sum_timestamps(["00:00", "01:01", "23:59"]), "25:00")
        self.assertEqual(sum_timestamps(["01:01", "00:00", "23:59"]), "25:00")
        self.assertEqual(sum_timestamps(["00:00"]), "0:00")
        self.assertEqual(sum_timestamps(["01:01"]), "1:01")

    def test_sum_timestamps_empty_list(self):
        self.assertEqual(sum_timestamps([]), "0:00")


class ProductTests(BaseTestCase):

    """Tests for product."""

    def test_one_number(self):
        self.assertEqual(product([10]), 10)

    def test_two_numbers(self):
        self.assertEqual(product([2, 8]), 16)

    def test_three_numbers(self):
        self.assertEqual(product([5, 6, 8]), 240)


class SumAllTests(BaseTestCase):

    """Tests for sum_all."""

    def test_three_lists_with_three_items(self):
        self.assertEqual(sum_all([[1, 2, 3], [4, 5, 6]]), 21)

    def test_three_by_two(self):
        self.assertEqual(sum_all([[0, 1], [4, 2], [3, 1]]), 11)

    def test_two_by_three(self):
        self.assertEqual(sum_all([[0, 1, 4], [2, 3, 1]]), 11)

    def test_no_inner_lists(self):
        self.assertEqual(sum_all([]), 0)


class FlattenTests(BaseTestCase):

    """Tests for flatten."""

    def test_3_by_4_matrix(self):
        matrix = [[row * 3 + incr for incr in range(1, 4)] for row in range(4)]
        flattened = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
        self.assertEqual(flatten(matrix), flattened)


class MatrixFromStringTests(BaseTestCase):

    """Tests for matrix_from_string."""

    def test_two_by_two_matrix(self):
        self.assertEqual(
            matrix_from_string("1 2\n10 20"),
            [[1, 2], [10, 20]],
        )

    def test_three_by_two_matrix(self):
        self.assertEqual(
            matrix_from_string("9 8 7\n19 18 17"),
            [[9, 8, 7], [19, 18, 17]],
        )


class WordsContainingTests(BaseTestCase):

    """Tests for words_containing."""

    def test_last_letter(self):
        self.assertEqual(
            words_containing(["My", "life", "is", "my", "message"], "y"),
            ["My", "my"],
        )

    def test_different_positions(self):
        self.assertEqual(
            words_containing(["My", "life", "is", "my", "message"], "i"),
            ["life", "is"]
        )

    def test_case_insensitive(self):
        self.assertEqual(
            words_containing(["My", "life", "is", "my", "message"], "m"),
            ["My", "my", "message"],
        )


class AreConsecutiveTests(BaseTestCase):

    """Tests for are_consecutive."""

    def test_consecutive_numbers(self):
        self.assertTrue(are_consecutive([3, 4, 5, 6]))

    def test_skipped_numbers(self):
        self.assertFalse(are_consecutive([3, 4, 5, 7]))

    def test_repeats(self):
        self.assertFalse(are_consecutive([3, 4, 5, 3]))

    def test_negative_numbers(self):
        self.assertTrue(are_consecutive([-4, -3, -2]))


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

    error_message()
