def test_remove_should_acquire_lock_on_parent_nodes(self):
        parent1 = Node((1, 2))
        parent2 = Node((2, 3))
        node = Node((3, 4), parents=set([(1, 2), (2, 3)]))
        parent1.children = set([(3, 4)])
        parent2.children = set([(3, 4)])
        leaf_queue = Mock()

        parent1.lock = Mock()
        parent1.lock.aquire.side_effect = lambda: self.assertTrue(node in parent1.children)
        parent1.lock.release.side_effect = lambda: self.assertFalse(node in parent1.children)

        parent2.lock = Mock()
        parent2.lock.aquire.side_effect = lambda: self.assertTrue(node in parent2.children)
        parent2.lock.release.side_effect = lambda: self.assertFalse(node in parent2.children)

        node.remove_from_parents([parent1, parent2], leaf_queue)

        self.assertTrue(parent1.lock.acquire.called)
        self.assertTrue(parent1.lock.release.called)
        self.assertTrue(parent2.lock.acquire.called)
        self.assertTrue(parent2.lock.release.called)

        self.assertEquals(
            leaf_queue.put.call_args_list,
            [call((1, 2)), call((2, 3))]
        )
    def test_equality(self):
        n1 = Node((1, 2), children=set([1]))
        n1.parents = set([2])
        n2 = Node((1, 2), children=set([1]))
        n2.parents = set([2])

        self.assertTrue(n1 == n2)
        self.assertFalse(n1 != n2)

        n2.location = (3, 4)
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.location = (1, 2)
        n2.parents = set([3])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.children = set([3])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.parents = set([2])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)
Example #3
0
    def test_returns_graph_and_leaf_nodes(self):
        worksheet = Worksheet()
        worksheet[1, 1].formula = '=A2 + B2'
        worksheet[1, 2].formula = '=A3'
        worksheet[2, 2].formula = '=B3'
        worksheet[1, 3].formula = '=1'
        worksheet[2, 3].formula = '1'
        worksheet[3, 3].python_formula = '1'

        graph, leaves = build_dependency_graph(worksheet)

        self.maxDiff = None
        self.assertEquals(
            graph, {
                (1, 1): Node(
                    (1, 1), children=set([(1, 2), (2, 2)]), parents=set()),
                (1, 2): Node(
                    (1, 2), children=set([(1, 3)]), parents=set([(1, 1)])),
                (2, 2): Node((2, 2), children=set(), parents=set([(1, 1)])),
                (1, 3): Node((1, 3), children=set(), parents=set([(1, 2)])),
                (3, 3): Node((3, 3), children=set(), parents=set()),
            })
        self.assertEquals(set(leaves), set([(1, 3), (2, 2), (3, 3)]))

        worksheet[1, 2].formula = '=A3 + B3'
        graph, leaves = build_dependency_graph(worksheet)

        self.assertEquals(
            graph, {
                (1, 1):
                Node(
                    (1, 1),
                    children=set([(1, 2), (2, 2)]),
                    parents=set(),
                ),
                (1, 2):
                Node(
                    (1, 2),
                    children=set([(1, 3)]),
                    parents=set([(1, 1)]),
                ),
                (2, 2):
                Node((2, 2), children=set(), parents=set([(1, 1)])),
                (1, 3):
                Node((1, 3), children=set(), parents=set([(1, 2)])),
                (3, 3):
                Node((3, 3), children=set(), parents=set()),
            })
        self.assertEquals(set(leaves), set([(1, 3), (2, 2), (3, 3)]))
Example #4
0
    def test_constructor(self):
        self.assertRaises(TypeError, lambda: Node())

        n1 = Node((1, 2))
        self.assertEquals(n1.location, (1, 2))
        self.assertEquals(n1.children, set())
        self.assertEquals(n1.parents, set())

        n2 = Node((2, 3), children=set([1, 2, 3]))
        self.assertEquals(n2.location, (2, 3))
        self.assertEquals(n2.children, set([1, 2, 3]))
        self.assertEquals(n2.parents, set())

        n3 = Node((4, 5), parents=set([1, 2, 3]))
        self.assertEquals(n3.location, (4, 5))
        self.assertEquals(n3.children, set())
        self.assertEquals(n3.parents, set([1, 2, 3]))
    def test_remove_should_add_new_leaves_to_queue(self):
        parent = Node((1, 2))
        child1 = Node((2, 3), parents=set([parent.location]))
        child2 = Node((3, 4), parents=set([parent.location]))
        parent.children = set([child1.location, child2.location])
        leaf_queue = Mock()

        child1.remove_from_parents([parent], leaf_queue)

        self.assertFalse(leaf_queue.put.called)

        child2.remove_from_parents([parent], leaf_queue)

        self.assertEquals(leaf_queue.put.call_args, ((parent.location,), {}))
Example #6
0
    def test_is_robust_against_references_to_empty_cells(self):
        worksheet = Worksheet()
        worksheet[1, 1].formula = '=A2'

        # NB we're making sure that this call doesn't raise an error
        # because the cell A2 is created in the dictionary while we're
        # iterating over it.
        graph, leaves = build_dependency_graph(worksheet)

        self.maxDiff = None
        self.assertEquals(
            graph, {(1, 1): Node((1, 1), children=set(), parents=set())})
        self.assertEquals(leaves, [(1, 1)])
Example #7
0
    def test_does_not_include_discovered_cycle_in_deps_of_current_cell(
            self):  #
        worksheet = Worksheet()
        worksheet[1, 1].formula = '=A2'
        worksheet[1, 2].formula = '=A1'
        worksheet[1, 3].formula = '=A1'

        visited = set()
        graph = {}

        _generate_cell_subgraph(worksheet, graph, (1, 3), visited, [])
        self.assertEquals(graph, {(1, 3): Node((1, 3), set())})
        self.assertEquals(visited, set([(1, 2), (1, 3), (1, 1)]))
Example #8
0
    def test_puts_errors_on_cells_in_cycles_and_omits_them_from_graph(
            self, mock_report_cell_error):
        mock_report_cell_error.side_effect = report_cell_error
        worksheet = Worksheet()
        worksheet[1, 1].formula = '=A2'
        worksheet[1, 2].formula = '=A1'
        worksheet[1, 3].formula = '=A1'
        worksheet[1, 4].formula = '=A5'
        worksheet[1, 5].formula = '=5'

        graph, leaves = build_dependency_graph(worksheet)
        self.assertEquals(
            graph, {
                (1, 3): Node((1, 3), children=set(), parents=set()),
                (1, 4): Node((1, 4), children=set([(1, 5)]), parents=set()),
                (1, 5): Node((1, 5), children=set(), parents=set([(1, 4)])),
            })
        self.assertEquals(leaves, [(1, 5), (1, 3)])
        a1_cycle_error = CycleError([(1, 2), (1, 1), (1, 2)])
        self.assertEquals(mock_report_cell_error.call_args_list, [
            call(worksheet, (1, 2), a1_cycle_error),
            call(worksheet, (1, 1), a1_cycle_error),
        ])
Example #9
0
    def test_should_not_recurse_into_existing_cycle_errors_or_include_them_in_its_deps(
            self, mock_recursive_call):
        cycle_error = CycleError([(1, 2), (3, 4), (1, 2)])
        worksheet = Worksheet()
        worksheet[1, 2].error = cycle_error
        worksheet[3, 4].error = cycle_error
        worksheet[1, 3].formula = "=foo"
        worksheet[1, 3].dependencies = [(3, 4)]

        visited = set([(1, 2), (3, 4)])
        graph = {}
        _generate_cell_subgraph(worksheet, graph, (1, 3), visited, [])

        dep_cell_calls = [c[0][2] for c in mock_recursive_call.call_args_list]
        self.assertNotIn(dep_cell_calls, (3, 4))
        self.assertEquals(visited, set([(1, 2), (1, 3), (3, 4)]))
        self.assertEquals(graph, {(1, 3): Node((1, 3), set())})
Example #10
0
    def test_add_location_dependencies_also_adds_reverse_dependencies(self):
        graph = {}
        parent_loc = (1, 2)
        child1_loc = (2, 3)
        child2_loc = (3, 4)
        grandchild_loc = (4, 5)

        _add_location_dependencies(graph, parent_loc,
                                   set([child1_loc, child2_loc]))
        expected = {
            parent_loc: Node(parent_loc,
                             children=set([child1_loc, child2_loc])),
            child1_loc: Node(child1_loc, parents=set([parent_loc])),
            child2_loc: Node(child2_loc, parents=set([parent_loc])),
        }
        self.assertEquals(expected, graph)

        _add_location_dependencies(graph, grandchild_loc, set())
        expected = {
            parent_loc: Node(parent_loc,
                             children=set([child1_loc, child2_loc])),
            child1_loc: Node(child1_loc, parents=set([parent_loc])),
            child2_loc: Node(child2_loc, parents=set([parent_loc])),
            grandchild_loc: Node(grandchild_loc),
        }
        self.assertEquals(expected, graph)

        _add_location_dependencies(graph, child1_loc, set([grandchild_loc]))
        expected = {
            parent_loc:
            Node(parent_loc, children=set([child1_loc, child2_loc])),
            child1_loc:
            Node(child1_loc,
                 children=set([grandchild_loc]),
                 parents=set([parent_loc])),
            child2_loc:
            Node(child2_loc, parents=set([parent_loc])),
            grandchild_loc:
            Node(grandchild_loc, parents=set([child1_loc])),
        }
        self.assertEquals(expected, graph)
Example #11
0
    def test_remove_should_add_new_leaves_to_queue(self):
        parent = Node((1, 2))
        child1 = Node((2, 3), parents=set([parent.location]))
        child2 = Node((3, 4), parents=set([parent.location]))
        parent.children = set([child1.location, child2.location])
        leaf_queue = Mock()

        child1.remove_from_parents([parent], leaf_queue)

        self.assertFalse(leaf_queue.put.called)

        child2.remove_from_parents([parent], leaf_queue)

        self.assertEquals(leaf_queue.put.call_args, ((parent.location, ), {}))
Example #12
0
    def test_remove_should_acquire_lock_on_parent_nodes(self):
        parent1 = Node((1, 2))
        parent2 = Node((2, 3))
        node = Node((3, 4), parents=set([(1, 2), (2, 3)]))
        parent1.children = set([(3, 4)])
        parent2.children = set([(3, 4)])
        leaf_queue = Mock()

        parent1.lock = Mock()
        parent1.lock.aquire.side_effect = lambda: self.assertTrue(
            node in parent1.children)
        parent1.lock.release.side_effect = lambda: self.assertFalse(
            node in parent1.children)

        parent2.lock = Mock()
        parent2.lock.aquire.side_effect = lambda: self.assertTrue(
            node in parent2.children)
        parent2.lock.release.side_effect = lambda: self.assertFalse(
            node in parent2.children)

        node.remove_from_parents([parent1, parent2], leaf_queue)

        self.assertTrue(parent1.lock.acquire.called)
        self.assertTrue(parent1.lock.release.called)
        self.assertTrue(parent2.lock.acquire.called)
        self.assertTrue(parent2.lock.release.called)

        self.assertEquals(leaf_queue.put.call_args_list,
                          [call((1, 2)), call((2, 3))])
Example #13
0
 def test_repr(self):
     self.assertEquals(str(Node((1, 2), children=set([1, 2, 3]))),
                       "<Node 1,2 children={1, 2, 3} parents={}>")
Example #14
0
    def test_equality(self):
        n1 = Node((1, 2), children=set([1]))
        n1.parents = set([2])
        n2 = Node((1, 2), children=set([1]))
        n2.parents = set([2])

        self.assertTrue(n1 == n2)
        self.assertFalse(n1 != n2)

        n2.location = (3, 4)
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.location = (1, 2)
        n2.parents = set([3])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.children = set([3])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)

        n2.parents = set([2])
        self.assertFalse(n1 == n2)
        self.assertTrue(n1 != n2)
Example #15
0
 def test_nodes_should_have_a_lock(self):
     node = Node((1, 2))
     self.assertIsNotNone(node.lock.acquire)
     self.assertIsNotNone(node.lock.release)