Esempio n. 1
0
    def test_search_dfs_bfs(self):
        """
        The complete result should not change depending on the traversal algorithm. The first match should however.
        """

        graph = initialize_backbone(NetworkxImplementation())

        root = graph.root_key
        base = "NODE"

        node_1 = _add_node(graph, base, root, tag=1)
        node_2 = _add_node(graph, base, root, tag=2)
        node_3 = _add_node(graph, base, node_2, tag=100)
        node_4 = _add_node(graph, base, node_1, tag=4)
        node_5 = _add_node(graph, base, node_2, tag=5)
        node_6 = _add_node(graph, base, node_1, tag=6)
        node_7 = _add_node(graph, base, node_4, tag=100)
        node_8 = _add_node(graph, base, node_4, tag=8)

        result_dfs = sorted(list(filter_dfs(graph, predicate=lambda x: x.get('tag', -1) == 100)))
        result_bfs = sorted(list(filter_bfs(graph, predicate=lambda x: x.get('tag', -1) == 100)))

        self.assertEqual(result_bfs, result_dfs)

        self.assertEqual(len(result_dfs), 2)
        self.assertListEqual(result_dfs, sorted(['NODE [3]', 'NODE [7]']))

        first_bfs = next(filter_bfs(graph, predicate=lambda x: x.get('tag', -1) == 100))
        first_dfs = next(filter_dfs(graph, predicate=lambda x: x.get('tag', -1) == 100))

        self.assertEqual(first_bfs, "NODE [3]")
        self.assertIn(first_dfs, ["NODE [3]", "NODE [7]"])
Esempio n. 2
0
    def test_add_node(self):
        """
        We should be able to add a node to the graph with a dictionary with data to be held by the newly created node
        """

        graph = initialize_backbone(NetworkxImplementation())

        data = {'a': 1, 'b': 2}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        new_node = _add_node(graph, key, parent, **data)

        self.assertEqual(new_node, "NEW NODE [1]")
        self.assertDictEqual(graph[new_node], data)
        self.assertEqual(graph.edges(parent), [('ROOT [0]', 'NEW NODE [1]')])

        data = {}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        new_node = _add_node(graph, key, parent, **data)

        self.assertEqual(new_node, "NEW NODE [2]")
        self.assertDictEqual(graph[new_node], data)
        self.assertEqual(sorted(graph.edges(parent)), sorted([('ROOT [0]', 'NEW NODE [1]'), ('ROOT [0]', 'NEW NODE [2]')]))
Esempio n. 3
0
    def test_search(self):
        """
        Filtering the nodes, reachable from a given source, should be possible by passing a predicate.
        """

        graph = initialize_backbone(NetworkxImplementation())

        parent = graph.root_key
        base = "NODE"
        for i in range(1, 10):
            parent = _add_node(graph, base, parent, tag=i)

        result = list(filter_dfs(graph, predicate=lambda x: x.get('tag', -1) == 5))

        self.assertEqual(len(result), 1)
        self.assertEqual(result[0], 'NODE [5]')

        result = list(filter_dfs(graph, predicate=lambda x: x.get('tag', -1) == 5, source="NODE [7]"))

        self.assertEqual(len(result), 0)
Esempio n. 4
0
    def test_node_id(self):
        """
        `_node_id` should generate a unique id for each node
        The ID should follow a namespace convention like a filesystem
        and take the shape of the document hierarchy
        """
        graph = initialize_backbone(NetworkxImplementation())

        data = {'a': 1, 'b': 2}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        new_node = _add_node(graph, key, parent, **data)

        data = {}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        id = 10

        identifier = _unique_path_identifier(graph, key, parent, id)

        assert identifier == '/root/'
Esempio n. 5
0
    def test_padding_01(self):
        """
        When requested, the insertion of a new node must be preceded of a padding process which ensures an uniform and predictable hierarchy
        """
        descriptor = {
            'components': ['A', 'B', 'C', 'D'],
            'patterns': [r'A', r'B', r'C', r'D']
        }

        descriptor = compile_patterns(descriptor)

        graph = initialize_backbone(NetworkxImplementation())

        data = {'level': 1, 'meta': 'ART'}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        node = _add_node(graph, key, parent, **data)

        last_node = _pad(graph, node, data['level'] + 1, 4, descriptor)

        self.assertListEqual(sorted(graph.nodes()), sorted(['ROOT [0]', 'NEW NODE [1]', 'B [2]', 'C [3]']))

        self.assertEqual(last_node, 'C [3]')
Esempio n. 6
0
    def test_append_content(self):
        """
        Every line should be inserted as content of the node currently in focus
        """

        graph = initialize_backbone(NetworkxImplementation())

        graph = append_content(graph, "this is a sample line")

        self.assertEqual(graph.cursor_data('content'),
                         ["this is a sample line"])

        data = {'level': 1, 'meta': 'ART', 'content': []}
        key = 'NEW NODE'
        parent = "ROOT [0]"

        _ = _add_node(graph, key, parent, **data)

        graph = append_content(graph, "yet another sample")
        graph = append_content(graph, "yet another sample 2")

        self.assertEqual(graph.cursor_data('content'),
                         ["yet another sample", "yet another sample 2"])
Esempio n. 7
0
    def test_padding_no_effect(self):
        """
        If the requested level is just one below the hierarchy the padding process should leave the graph unchanged
        """
        descriptor = {
            'components': ['A', 'B', 'C', 'D'],
            'patterns': [r'A', r'B', r'C', r'D']
        }

        descriptor = compile_patterns(descriptor)

        graph = initialize_backbone(NetworkxImplementation())

        data = {'level': 1, 'meta': 'ART'}
        key = 'NEW NODE'
        parent = "ROOT [0]"
        node = _add_node(graph, key, parent, **data)

        nodes_before = sorted(graph.nodes())
        last_node = _pad(graph, node, 3 + 1, 4, descriptor)
        nodes_after = sorted(graph.nodes())

        self.assertEqual(last_node, node)
        self.assertListEqual(nodes_before, nodes_after)
Esempio n. 8
0
    def test_search_bfs_parents(self):
        """
        We should be able to search from the opposite direction. From bottom to top, assuming a acyclic directed graph
        """

        graph = initialize_backbone(NetworkxImplementation())

        base = "NODE"

        _add_node(graph, base, "ROOT [0]", tag=10) #  NODE[1]
        _add_node(graph, base, "NODE [1]", tag=10)   #  NODE[2]
        _add_node(graph, base, "NODE [1]", tag=10)  #  NODE[3]
        _add_node(graph, base, "NODE [1]", tag=1)   #  NODE[4]
        _add_node(graph, base, "NODE [2]", tag=100)  #  NODE[5]
        _add_node(graph, base, "NODE [2]", tag=1)   #  NODE[6]
        _add_node(graph, base, "NODE [5]", tag=1)   #  NODE[7]

        result_dfs = sorted(list(filter_bfs_ancestors(graph, source="NODE [5]", predicate=lambda x: x.get('tag', -1) == 10)))
        self.assertListEqual(result_dfs, ["NODE [1]", "NODE [2]"])

        result_dfs = sorted(list(filter_bfs_ancestors(graph, source="NODE [7]", predicate=lambda x: x.get('tag', -1) == 100)))
        self.assertListEqual(result_dfs, ["NODE [5]"])

        result_dfs = sorted(list(filter_bfs_ancestors(graph, source="NODE [5]", predicate=lambda x: x.get('tag', -1) == 999)))
        self.assertListEqual(result_dfs, [])