from ploneintranet.workspace.utils import OpenEndedGraph
from unittest import TestCase


class TestSuperspaceGraph(TestCase):
    """Each test shows a graph with this conventions:

    - root is the root node
    - uppercase letters are nodes
    - lowercase letters are not nodes
    """

    def test_empty(self):
        """Test method resilience with an empty graph"""
        graph = OpenEndedGraph(set(), [])
        self.assertSetEqual(graph.get_meaningful_children("root"), set())
        self.assertSetEqual(graph.get_descendants("root"), set())

    def test_simple_graph(self):
        """root
        |---- A
        |---- B
        `---- c
        """
        graph = OpenEndedGraph(
            {"A", "B"}, [["root", "A"], ["root", "B"], ["root", "c"]]
        )
        # c is discarded because it is not a node
        self.assertSetEqual(graph.get_meaningful_children("root"), {"A", "B"})
        # Looking for children of a nont existent node works fine
        self.assertSetEqual(graph.get_meaningful_children("foo"), set())
        # Look for the descendants now
        self.assertSetEqual(graph.get_descendants("root"), {"A", "B", "c"})
        # Look for the descendants now
        self.assertSetEqual(graph.get_descendants("A"), set())

    def test_complex_graph(self):
        """root
        |---- A
        |---- a
        |     `- B
        |---- b
        |     `- c
        |        `- C
        `---- d
        """
        graph = OpenEndedGraph(
            {"A", "B", "C"},
            [
                ["root", "A"],
                ["root", "a"],
                ["root", "b"],
                ["root", "d"],
                ["a", "B"],
                ["b", "c"],
                ["c", "C"],
            ],
        )
        self.assertSetEqual(graph.get_meaningful_children("root"), {"A", "a", "b"})
        self.assertSetEqual(graph.get_meaningful_children("A"), set())
        self.assertSetEqual(graph.get_meaningful_children("a"), {"B"})
        self.assertSetEqual(graph.get_meaningful_children("b"), {"c"})
        self.assertSetEqual(graph.get_meaningful_children("c"), {"C"})
        self.assertSetEqual(graph.get_meaningful_children("d"), set())
        self.assertSetEqual(graph.get_descendants("root"), set("ABCabcd"))
        self.assertSetEqual(graph.get_descendants("a"), set("B"))
        self.assertSetEqual(graph.get_descendants("b"), set("Cc"))

    def test_circular_graph(self):
        """Prove that we can safely deal with circular dependencies
        root
         `---- a
               |- A
               `- b
                  `- a
        """
        graph = OpenEndedGraph(
            {"A"}, [["root", "a"], ["a", "A"], ["a", "b"], ["b", "a"]]
        )
        self.assertSetEqual(graph.get_meaningful_children("root"), {"a"})
        # b is removed because it leads once again to A
        self.assertSetEqual(graph.get_meaningful_children("a"), {"A"})
        self.assertSetEqual(graph.get_meaningful_children("b"), {"a"})
