Exemple #1
0
    def test_remove_block(self, keep_descendants, block_to_remove,
                          children_map):
        ### skip test if invalid
        if (block_to_remove >= len(children_map)) or (keep_descendants and
                                                      block_to_remove == 0):
            return

        ### create structure
        block_structure = self.create_block_structure(BlockStructureBlockData,
                                                      children_map)
        parents_map = self.get_parents_map(children_map)

        ### verify blocks pre-exist
        self.assert_block_structure(block_structure, children_map)

        ### remove block
        block_structure.remove_block(block_to_remove, keep_descendants)
        missing_blocks = [block_to_remove]

        ### compute and verify updated children_map
        removed_children_map = deepcopy(children_map)
        removed_children_map[block_to_remove] = []
        for parent in parents_map[block_to_remove]:
            removed_children_map[parent].remove(block_to_remove)

        if keep_descendants:
            # update the graph connecting the old parents to the old children
            for child in children_map[block_to_remove]:
                for parent in parents_map[block_to_remove]:
                    removed_children_map[parent].append(child)

        self.assert_block_structure(block_structure, removed_children_map,
                                    missing_blocks)

        ### prune the structure
        block_structure._prune_unreachable()

        ### compute and verify updated children_map
        pruned_children_map = deepcopy(removed_children_map)

        if not keep_descendants:
            pruned_parents_map = self.get_parents_map(pruned_children_map)
            # update all descendants
            for child in children_map[block_to_remove]:
                # if the child has another parent, continue
                if pruned_parents_map[child]:
                    continue
                for block in traverse_post_order(
                        child,
                        get_children=lambda block: pruned_children_map[block]):
                    # add descendant to missing blocks and empty its
                    # children
                    missing_blocks.append(block)
                    pruned_children_map[block] = []

        self.assert_block_structure(block_structure, pruned_children_map,
                                    missing_blocks)
    def test_remove_block(self, keep_descendants, block_to_remove, children_map):
        ### skip test if invalid
        if (block_to_remove >= len(children_map)) or (keep_descendants and block_to_remove == 0):
            return

        ### create structure
        block_structure = self.create_block_structure(children_map)
        parents_map = self.get_parents_map(children_map)

        ### verify blocks pre-exist
        self.assert_block_structure(block_structure, children_map)

        ### remove block
        block_structure.remove_block(block_to_remove, keep_descendants)
        missing_blocks = [block_to_remove]

        ### compute and verify updated children_map
        removed_children_map = deepcopy(children_map)
        removed_children_map[block_to_remove] = []
        for parent in parents_map[block_to_remove]:
            removed_children_map[parent].remove(block_to_remove)

        if keep_descendants:
            # update the graph connecting the old parents to the old children
            for child in children_map[block_to_remove]:
                for parent in parents_map[block_to_remove]:
                    removed_children_map[parent].append(child)

        self.assert_block_structure(block_structure, removed_children_map, missing_blocks)

        ### prune the structure
        block_structure._prune_unreachable()

        ### compute and verify updated children_map
        pruned_children_map = deepcopy(removed_children_map)

        if not keep_descendants:
            pruned_parents_map = self.get_parents_map(pruned_children_map)
            # update all descendants
            for child in children_map[block_to_remove]:
                # if the child has another parent, continue
                if pruned_parents_map[child]:
                    continue
                for block in traverse_post_order(child, get_children=lambda block: pruned_children_map[block]):
                    # add descendant to missing blocks and empty its
                    # children
                    missing_blocks.append(block)
                    pruned_children_map[block] = []

        self.assert_block_structure(block_structure, pruned_children_map, missing_blocks)
    def post_order_traversal(
        self,
        filter_func=None,
    ):
        """
        Performs a post-order sort of the block structure and yields
        the usage_key of each block as it is encountered.

        Arguments:
            See the description in
            openedx.core.lib.graph_traversals.traverse_post_order.

        Returns:
            generator - A generator object created from the
                traverse_post_order method.
        """
        return traverse_post_order(
            start_node=self.root_block_usage_key,
            get_children=self.get_children,
            filter_func=filter_func,
        )
    def post_order_traversal(
            self,
            filter_func=None,
    ):
        """
        Performs a post-order sort of the block structure and yields
        the usage_key of each block as it is encountered.

        Arguments:
            See the description in
            openedx.core.lib.graph_traversals.traverse_post_order.

        Returns:
            generator - A generator object created from the
                traverse_post_order method.
        """
        return traverse_post_order(
            start_node=self.root_block_usage_key,
            get_children=self.get_children,
            filter_func=filter_func,
        )