120
120
'rev2b': ['rev1'], 'rev2c': ['rev1'],
121
121
'rev3a': ['rev2a', 'rev2b'], 'rev3b': ['rev2b', 'rev2c']}
133
boundary = {'a': ['b'], 'c': ['b', 'd'], 'b':['e'], 'd':['e'], 'e': ['f'],
137
class InstrumentedParentsProvider(object):
139
def __init__(self, parents_provider):
141
self._real_parents_provider = parents_provider
143
def get_parents(self, nodes):
144
self.calls.extend(nodes)
145
return self._real_parents_provider.get_parents(nodes)
124
148
class TestGraph(TestCaseWithMemoryTransport):
181
205
self.assertEqual(set(['rev1']), graph.find_lca('rev1', 'rev1'))
182
206
self.assertEqual(set(['rev1']), graph.find_lca('rev2a', 'rev2b'))
208
def test_no_unique_lca(self):
209
"""Test error when one revision is not in the graph"""
210
graph = self.make_graph(ancestry_1)
211
self.assertRaises(errors.NoCommonAncestor, graph.find_unique_lca,
184
214
def test_lca_criss_cross(self):
185
215
"""Test least-common-ancestor after a criss-cross merge."""
186
216
graph = self.make_graph(criss_cross)
272
302
parents1 = ParentsProvider({'rev2': ['rev3']})
273
303
parents2 = ParentsProvider({'rev1': ['rev4']})
274
stacked = graph._StackedParentsProvider([parents1, parents2])
304
stacked = _mod_graph._StackedParentsProvider([parents1, parents2])
275
305
self.assertEqual([['rev4',], ['rev3']],
276
306
stacked.get_parents(['rev1', 'rev2']))
277
307
self.assertEqual([['rev3',], ['rev4']],
288
318
self.assertEqual(set(args), set(topo_args))
289
319
self.assertTrue(topo_args.index('rev2a') > topo_args.index('rev1'))
290
320
self.assertTrue(topo_args.index('rev2a') < topo_args.index('rev3'))
322
def test_is_ancestor(self):
323
graph = self.make_graph(ancestry_1)
324
self.assertEqual(True, graph.is_ancestor('null:', 'null:'))
325
self.assertEqual(True, graph.is_ancestor('null:', 'rev1'))
326
self.assertEqual(False, graph.is_ancestor('rev1', 'null:'))
327
self.assertEqual(True, graph.is_ancestor('null:', 'rev4'))
328
self.assertEqual(False, graph.is_ancestor('rev4', 'null:'))
329
self.assertEqual(False, graph.is_ancestor('rev4', 'rev2b'))
330
self.assertEqual(True, graph.is_ancestor('rev2b', 'rev4'))
331
self.assertEqual(False, graph.is_ancestor('rev2b', 'rev3'))
332
self.assertEqual(False, graph.is_ancestor('rev3', 'rev2b'))
333
instrumented_provider = InstrumentedParentsProvider(graph)
334
instrumented_graph = _mod_graph.Graph(instrumented_provider)
335
instrumented_graph.is_ancestor('rev2a', 'rev2b')
336
self.assertTrue('null:' not in instrumented_provider.calls)
338
def test_is_ancestor_boundary(self):
339
"""Ensure that we avoid searching the whole graph.
341
This requires searching through b as a common ancestor, so we
342
can identify that e is common.
344
graph = self.make_graph(boundary)
345
instrumented_provider = InstrumentedParentsProvider(graph)
346
graph = _mod_graph.Graph(instrumented_provider)
347
self.assertFalse(graph.is_ancestor('a', 'c'))
348
self.assertTrue('null:' not in instrumented_provider.calls)