235
complex_shortcut2 = {'a':[NULL_REVISION], 'b':['a'], 'c':['b'], 'd':['c'],
236
'e':['d'], 'f':['e'], 'g':['f'], 'h':['d'], 'i':['g'],
237
'j':['h'], 'k':['h', 'i'], 'l':['k'], 'm':['l'], 'n':['m'],
238
'o':['n'], 'p':['o'], 'q':['p'], 'r':['q'], 's':['r'],
239
't':['i', 's'], 'u':['s', 'j'],
235
complex_shortcut2 = {'a': [NULL_REVISION], 'b': ['a'], 'c': ['b'], 'd': ['c'],
236
'e': ['d'], 'f': ['e'], 'g': ['f'], 'h': ['d'], 'i': ['g'],
237
'j': ['h'], 'k': ['h', 'i'], 'l': ['k'], 'm': ['l'], 'n': ['m'],
238
'o': ['n'], 'p': ['o'], 'q': ['p'], 'r': ['q'], 's': ['r'],
239
't': ['i', 's'], 'u': ['s', 'j'],
242
242
# Graph where different walkers will race to find the common and uncommon
894
894
def test_heads_limits_search(self):
895
895
# test that a heads query does not search all of history
899
'common': ['deeper'],
901
901
self.assertEqual({'left', 'right'},
902
902
self._run_heads_break_deeper(graph_dict, ['left', 'right']))
904
904
def test_heads_limits_search_assymetric(self):
905
905
# test that a heads query does not search all of history
908
'midleft':['common'],
910
'common':['aftercommon'],
911
'aftercommon':['deeper'],
908
'midleft': ['common'],
910
'common': ['aftercommon'],
911
'aftercommon': ['deeper'],
913
913
self.assertEqual({'left', 'right'},
914
914
self._run_heads_break_deeper(graph_dict, ['left', 'right']))
917
917
# test that common nodes are still queried, preventing
918
918
# all-the-way-to-origin behaviour in the following graph:
920
'h1':['shortcut', 'common1'],
922
'shortcut':['common2'],
923
'common1':['common2'],
924
'common2':['deeper'],
920
'h1': ['shortcut', 'common1'],
922
'shortcut': ['common2'],
923
'common1': ['common2'],
924
'common2': ['deeper'],
926
926
self.assertEqual({'h1', 'h2'},
927
927
self._run_heads_break_deeper(graph_dict, ['h1', 'h2']))
940
940
def test_breadth_first_search_deep_ghosts(self):
941
941
graph = self.make_graph({
943
'present':['child', 'ghost'],
943
'present': ['child', 'ghost'],
946
946
# with_ghosts reports the ghosts
947
947
search = graph._make_breadth_first_searcher(['head'])
962
962
# To make the API robust, we allow calling both next() and
963
963
# next_with_ghosts() on the same searcher.
964
964
graph = self.make_graph({
966
'present':['child', 'ghost'],
966
'present': ['child', 'ghost'],
969
969
# start with next_with_ghosts
970
970
search = graph._make_breadth_first_searcher(['head'])
984
984
def test_breadth_first_change_search(self):
985
985
# Changing the search should work with both next and next_with_ghosts.
986
986
graph = self.make_graph({
988
'present':['stopped'],
988
'present': ['stopped'],
989
'other': ['other_2'],
992
992
search = graph._make_breadth_first_searcher(['head'])
993
993
self.assertEqual(({'head'}, set()), search.next_with_ghosts())
1036
1036
def test_breadth_first_get_result_excludes_current_pending(self):
1037
1037
graph = self.make_graph({
1039
'child':[NULL_REVISION],
1039
'child': [NULL_REVISION],
1042
1042
search = graph._make_breadth_first_searcher(['head'])
1043
1043
# At the start, nothing has been seen, to its all excluded:
1102
1102
# A client should be able to say 'stop node X' even if X has not been
1103
1103
# returned to the client.
1104
1104
graph = self.make_graph({
1105
'head':['child', 'ghost1'],
1106
'child':[NULL_REVISION],
1105
'head': ['child', 'ghost1'],
1106
'child': [NULL_REVISION],
1109
1109
search = graph._make_breadth_first_searcher(['head'])
1128
1128
# from the result even if X was seen in an older iteration of the
1130
1130
graph = self.make_graph({
1133
'child':[NULL_REVISION],
1132
'middle': ['child'],
1133
'child': [NULL_REVISION],
1136
1136
search = graph._make_breadth_first_searcher(['head'])
1153
1153
def test_breadth_first_get_result_ghosts_are_excluded(self):
1154
1154
graph = self.make_graph({
1155
'head':['child', 'ghost'],
1156
'child':[NULL_REVISION],
1155
'head': ['child', 'ghost'],
1156
'child': [NULL_REVISION],
1159
1159
search = graph._make_breadth_first_searcher(['head'])
1174
1174
def test_breadth_first_get_result_starting_a_ghost_ghost_is_excluded(self):
1175
1175
graph = self.make_graph({
1177
'child':[NULL_REVISION],
1177
'child': [NULL_REVISION],
1180
1180
search = graph._make_breadth_first_searcher(['head'])