import unittest

from pygraph.graphdemo import Graph


class GraphTestCase(unittest.TestCase):
    def test_construct_a_graph(self):
        g = Graph()
        g.add_edge(1, 2)
        g.add_edge(1, 3)
        g.add_edge(2, 3)
        g.add_edge(2, 4)
        txt = str(g)
        expected = '''1 → [2, 3]
2 → [1, 3, 4]
3 → [1, 2]
4 → [2]'''
        self.assertEqual(expected, txt)
        vertices = [1, 2, 3, 4]
        # def action(v): self.assertTrue(v in vertices)
        g.for_each_vertices(lambda v : self.assertTrue(v in vertices))

    def test_iterate_all_edges(self):
        g = Graph()
        g.add_edge(1, 2)
        g.add_edge(1, 3)
        g.add_edge(2, 3)
        g.add_edge(2, 4)
        edges = [
            "1-2", "1-3", "2-3", "2-4"
        ]
        def action(a, b):
            (s,e) = (a,b) if a < b else (b,a)
            edge = f"{s}-{e}"
            self.assertTrue(edge in edges)
        g.for_each_edges(action)

    def test_iterate_all_vertices(self):
        g = Graph()
        g.add_edge(1, 2)
        g.add_edge(1, 3)
        g.add_edge(2, 3)
        g.add_edge(2, 4)
        vertices = []
        for v in g.vertices():
            vertices.append(v)
        expected = [1, 2, 3, 4]
        self.assertListEqual(sorted(vertices), expected)
        pass

    def test_iterate_neighbor_vertex(self):
        g = Graph()
        g.add_edge(1, 2)
        g.add_edge(1, 3)
        g.add_edge(2, 3)
        g.add_edge(2, 4)
        g.add_edge(4, 1)
        vertices = []
        for v in g.adjacent_of(1):
            vertices.append(v)
        expected = [2, 3, 4]
        self.assertListEqual(sorted(vertices), expected)
        pass

    def test_not_add_float_to_vertex(self):
        g = Graph()
        try:
            g.add_vertex(1.2)
            pass
        except TypeError as ex:
            expected_msg = "Argument 1.2 is not a valid vertex"
            self.assertEqual(str(ex), expected_msg)
            pass
        pass

    def test_not_add_string_to_vertex(self):
        g = Graph()
        try:
            g.add_vertex("add")
        except TypeError as ex:
            expected_msg = 'Argument add is not a valid vertex'
            self.assertEqual(str(ex), expected_msg)
            pass
        pass


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