~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_graph.py

Add basic get_recipe to the graph breadth first searcher.

Show diffs side-by-side

added added

removed removed

Lines of Context:
252
252
class TestGraph(TestCaseWithMemoryTransport):
253
253
 
254
254
    def make_graph(self, ancestors):
255
 
        # XXX: This seems valid, is there a reason to actually create a
256
 
        # repository and put things in it?
257
255
        return _mod_graph.Graph(_mod_graph.DictParentsProvider(ancestors))
258
 
        tree = self.prepare_memory_tree('.')
259
 
        self.build_ancestry(tree, ancestors)
260
 
        self.addCleanup(tree.unlock)
261
 
        return tree.branch.repository.get_graph()
262
256
 
263
257
    def prepare_memory_tree(self, location):
264
258
        tree = self.make_branch_and_memory_tree(location)
653
647
            self._run_heads_break_deeper(graph_dict, ['h1', 'h2']))
654
648
 
655
649
    def test_breadth_first_search_start_ghosts(self):
656
 
        parent_graph = {}
657
 
        parents_provider = InstrumentedParentsProvider(
658
 
            _mod_graph.DictParentsProvider(parent_graph))
659
 
        graph = _mod_graph.Graph(parents_provider)
 
650
        graph = self.make_graph({})
660
651
        # with_ghosts reports the ghosts
661
652
        search = graph._make_breadth_first_searcher(['a-ghost'])
662
653
        self.assertEqual((set(), set(['a-ghost'])), search.next_with_ghosts())
667
658
        self.assertRaises(StopIteration, search.next)
668
659
 
669
660
    def test_breadth_first_search_deep_ghosts(self):
670
 
        parent_graph = {
 
661
        graph = self.make_graph({
671
662
            'head':['present'],
672
663
            'present':['child', 'ghost'],
673
664
            'child':[],
674
 
            }
675
 
        parents_provider = InstrumentedParentsProvider(
676
 
            _mod_graph.DictParentsProvider(parent_graph))
677
 
        graph = _mod_graph.Graph(parents_provider)
 
665
            })
678
666
        # with_ghosts reports the ghosts
679
667
        search = graph._make_breadth_first_searcher(['head'])
680
668
        self.assertEqual((set(['head']), set()), search.next_with_ghosts())
693
681
    def test_breadth_first_search_change_next_to_next_with_ghosts(self):
694
682
        # To make the API robust, we allow calling both next() and
695
683
        # next_with_ghosts() on the same searcher.
696
 
        parent_graph = {
 
684
        graph = self.make_graph({
697
685
            'head':['present'],
698
686
            'present':['child', 'ghost'],
699
687
            'child':[],
700
 
            }
701
 
        parents_provider = InstrumentedParentsProvider(
702
 
            _mod_graph.DictParentsProvider(parent_graph))
703
 
        graph = _mod_graph.Graph(parents_provider)
 
688
            })
704
689
        # start with next_with_ghosts
705
690
        search = graph._make_breadth_first_searcher(['head'])
706
691
        self.assertEqual((set(['head']), set()), search.next_with_ghosts())
718
703
 
719
704
    def test_breadth_first_change_search(self):
720
705
        # Changing the search should work with both next and next_with_ghosts.
721
 
        parent_graph = {
 
706
        graph = self.make_graph({
722
707
            'head':['present'],
723
708
            'present':['stopped'],
724
709
            'other':['other_2'],
725
710
            'other_2':[],
726
 
            }
727
 
        parents_provider = InstrumentedParentsProvider(
728
 
            _mod_graph.DictParentsProvider(parent_graph))
729
 
        graph = _mod_graph.Graph(parents_provider)
 
711
            })
730
712
        search = graph._make_breadth_first_searcher(['head'])
731
713
        self.assertEqual((set(['head']), set()), search.next_with_ghosts())
732
714
        self.assertEqual((set(['present']), set()), search.next_with_ghosts())
746
728
        self.assertEqual(set(['other_2']), search.next())
747
729
        self.assertRaises(StopIteration, search.next)
748
730
 
 
731
    def assertSeenAndRecipes(self, results, search, next):
 
732
        """Check the results of .seen and get_recipe() for a seach.
 
733
 
 
734
        :param results: A list of tuples (seen, get_recipe_result).
 
735
        :param search: The search to use.
 
736
        :param next: A callable to advance the search.
 
737
        """
 
738
        for seen, recipe in results:
 
739
            next()
 
740
            self.assertEqual(recipe, search.get_recipe())
 
741
            self.assertEqual(seen, search.seen)
 
742
 
 
743
    def test_breadth_first_get_recipe_excludes_current_pending(self):
 
744
        graph = self.make_graph({
 
745
            'head':['child'],
 
746
            'child':[NULL_REVISION],
 
747
            })
 
748
        search = graph._make_breadth_first_searcher(['head'])
 
749
        # At the start, nothing has been seen, to its all excluded:
 
750
        self.assertEqual((set(['head']), set(['head'])), search.get_recipe())
 
751
        self.assertEqual(set(), search.seen)
 
752
        # using next:
 
753
        expected = [
 
754
            (set(['head']), (set(['head']), set(['child']))),
 
755
            (set(['head', 'child']), (set(['head']), set([NULL_REVISION]))),
 
756
            (set(['head', 'child', NULL_REVISION]), (set(['head']), set())),
 
757
            ]
 
758
        self.assertSeenAndRecipes(expected, search, search.next)
 
759
        # using next_with_ghosts:
 
760
        search = graph._make_breadth_first_searcher(['head'])
 
761
        self.assertSeenAndRecipes(expected, search, search.next_with_ghosts)
 
762
 
749
763
 
750
764
class TestCachingParentsProvider(tests.TestCase):
751
765