252
252
class TestGraph(TestCaseWithMemoryTransport):
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()
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']))
655
649
def test_breadth_first_search_start_ghosts(self):
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)
669
660
def test_breadth_first_search_deep_ghosts(self):
661
graph = self.make_graph({
671
662
'head':['present'],
672
663
'present':['child', 'ghost'],
675
parents_provider = InstrumentedParentsProvider(
676
_mod_graph.DictParentsProvider(parent_graph))
677
graph = _mod_graph.Graph(parents_provider)
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.
684
graph = self.make_graph({
697
685
'head':['present'],
698
686
'present':['child', 'ghost'],
701
parents_provider = InstrumentedParentsProvider(
702
_mod_graph.DictParentsProvider(parent_graph))
703
graph = _mod_graph.Graph(parents_provider)
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())
719
704
def test_breadth_first_change_search(self):
720
705
# Changing the search should work with both next and next_with_ghosts.
706
graph = self.make_graph({
722
707
'head':['present'],
723
708
'present':['stopped'],
724
709
'other':['other_2'],
727
parents_provider = InstrumentedParentsProvider(
728
_mod_graph.DictParentsProvider(parent_graph))
729
graph = _mod_graph.Graph(parents_provider)
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)
731
def assertSeenAndRecipes(self, results, search, next):
732
"""Check the results of .seen and get_recipe() for a seach.
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.
738
for seen, recipe in results:
740
self.assertEqual(recipe, search.get_recipe())
741
self.assertEqual(seen, search.seen)
743
def test_breadth_first_get_recipe_excludes_current_pending(self):
744
graph = self.make_graph({
746
'child':[NULL_REVISION],
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)
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())),
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)
750
764
class TestCachingParentsProvider(tests.TestCase):