67
73
def describe(self):
68
74
return "%s is locked" % self.lockable_thing
77
class _AncestryMismatch(Mismatch):
78
"""Ancestry matching mismatch."""
80
def __init__(self, tip_revision, got, expected):
81
self.tip_revision = tip_revision
83
self.expected = expected
86
return "mismatched ancestry for revision %r was %r, expected %r" % (
87
self.tip_revision, self.got, self.expected)
90
class MatchesAncestry(Matcher):
91
"""A matcher that checks the ancestry of a particular revision.
93
:ivar graph: Graph in which to check the ancestry
94
:ivar revision_id: Revision id of the revision
97
def __init__(self, repository, revision_id):
98
Matcher.__init__(self)
99
self.repository = repository
100
self.revision_id = revision_id
103
return ('MatchesAncestry(repository=%r, revision_id=%r)' % (
104
self.repository, self.revision_id))
106
def match(self, expected):
107
self.repository.lock_read()
109
graph = self.repository.get_graph()
110
got = [r for r, p in graph.iter_ancestry([self.revision_id])]
111
if _mod_revision.NULL_REVISION in got:
112
got.remove(_mod_revision.NULL_REVISION)
114
self.repository.unlock()
115
if sorted(got) != sorted(expected):
116
return _AncestryMismatch(self.revision_id, sorted(got),
120
class HasLayout(Matcher):
121
"""A matcher that checks if a tree has a specific layout.
123
:ivar entries: List of expected entries, as (path, file_id) pairs.
126
def __init__(self, entries):
127
Matcher.__init__(self)
128
self.entries = entries
130
def get_tree_layout(self, tree):
131
"""Get the (path, file_id) pairs for the current tree."""
134
return [(path, ie.file_id) for path, ie
135
in tree.iter_entries_by_dir()]
140
return ('HasLayout(%r)' % self.entries)
142
def match(self, tree):
143
actual = self.get_tree_layout(tree)
144
if self.entries and isinstance(self.entries[0], basestring):
145
actual = [path for (path, fileid) in actual]
146
return Equals(actual).match(self.entries)