/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/matchers.py

  • Committer: Jelmer Vernooij
  • Date: 2020-05-06 02:13:25 UTC
  • mfrom: (7490.7.21 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200506021325-awbmmqu1zyorz7sj
Merge 3.1 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
__all__ = [
30
30
    'HasLayout',
 
31
    'HasPathRelations',
31
32
    'MatchesAncestry',
32
33
    'ContainsNoVfsCalls',
33
34
    'ReturnsUnlockable',
40
41
    )
41
42
from .. import lazy_import
42
43
lazy_import.lazy_import(globals(),
43
 
"""
 
44
                        """
44
45
from breezy.bzr.smart.request import request_handlers as smart_request_handlers
45
46
from breezy.bzr.smart import vfs
46
47
""")
47
 
from ..sixish import (
48
 
    text_type,
 
48
from ..tree import (
 
49
    find_previous_path,
 
50
    InterTree,
49
51
    )
50
52
 
51
53
from testtools.matchers import Equals, Mismatch, Matcher
67
69
 
68
70
    def __str__(self):
69
71
        return ('ReturnsUnlockable(lockable_thing=%s)' %
70
 
            self.lockable_thing)
 
72
                self.lockable_thing)
71
73
 
72
74
    def match(self, lock_method):
73
75
        lock_method().unlock()
123
125
                got.remove(_mod_revision.NULL_REVISION)
124
126
        if sorted(got) != sorted(expected):
125
127
            return _AncestryMismatch(self.revision_id, sorted(got),
126
 
                sorted(expected))
 
128
                                     sorted(expected))
127
129
 
128
130
 
129
131
class HasLayout(Matcher):
136
138
        Matcher.__init__(self)
137
139
        self.entries = entries
138
140
 
139
 
    def get_tree_layout(self, tree):
 
141
    def get_tree_layout(self, tree, include_file_ids):
140
142
        """Get the (path, file_id) pairs for the current tree."""
141
143
        with tree.lock_read():
142
144
            for path, ie in tree.iter_entries_by_dir():
143
 
                if ie.parent_id is None:
144
 
                    yield (u"", ie.file_id)
 
145
                if path != u'':
 
146
                    path += ie.kind_character()
 
147
                if include_file_ids:
 
148
                    yield (path, ie.file_id)
145
149
                else:
146
 
                    yield (path+ie.kind_character(), ie.file_id)
 
150
                    yield path
147
151
 
148
152
    @staticmethod
149
153
    def _strip_unreferenced_directories(entries):
153
157
        """
154
158
        directories = []
155
159
        for entry in entries:
156
 
            if isinstance(entry, (str, text_type)):
 
160
            if isinstance(entry, str):
157
161
                path = entry
158
162
            else:
159
163
                path = entry[0]
172
176
        return 'HasLayout(%r)' % self.entries
173
177
 
174
178
    def match(self, tree):
175
 
        actual = list(self.get_tree_layout(tree))
176
 
        if self.entries and isinstance(self.entries[0], (str, text_type)):
177
 
            actual = [path for (path, fileid) in actual]
 
179
        include_file_ids = self.entries and not isinstance(
 
180
            self.entries[0], str)
 
181
        actual = list(self.get_tree_layout(
 
182
            tree, include_file_ids=include_file_ids))
178
183
        if not tree.has_versioned_directories():
179
184
            entries = list(self._strip_unreferenced_directories(self.entries))
180
185
        else:
182
187
        return Equals(entries).match(actual)
183
188
 
184
189
 
 
190
class HasPathRelations(Matcher):
 
191
    """Matcher verifies that paths have a relation to those in another tree.
 
192
 
 
193
    :ivar previous_tree: tree to compare to
 
194
    :ivar previous_entries: List of expected entries, as (path, previous_path) pairs.
 
195
    """
 
196
 
 
197
    def __init__(self, previous_tree, previous_entries):
 
198
        Matcher.__init__(self)
 
199
        self.previous_tree = previous_tree
 
200
        self.previous_entries = previous_entries
 
201
 
 
202
    def get_path_map(self, tree):
 
203
        """Get the (path, previous_path) pairs for the current tree."""
 
204
        previous_intertree = InterTree.get(self.previous_tree, tree)
 
205
        with tree.lock_read(), self.previous_tree.lock_read():
 
206
            for path, ie in tree.iter_entries_by_dir():
 
207
                if tree.supports_rename_tracking():
 
208
                    previous_path = previous_intertree.find_source_path(path)
 
209
                else:
 
210
                    if self.previous_tree.is_versioned(path):
 
211
                        previous_path = path
 
212
                    else:
 
213
                        previous_path = None
 
214
                if previous_path:
 
215
                    kind = self.previous_tree.kind(previous_path)
 
216
                    if kind == 'directory':
 
217
                        previous_path += '/'
 
218
                if path == u'':
 
219
                    yield (u"", previous_path)
 
220
                else:
 
221
                    yield (path + ie.kind_character(), previous_path)
 
222
 
 
223
    @staticmethod
 
224
    def _strip_unreferenced_directories(entries):
 
225
        """Strip all directories that don't (in)directly contain any files.
 
226
 
 
227
        :param entries: List of path strings or (path, previous_path) tuples to process
 
228
        """
 
229
        directory_used = set()
 
230
        directories = []
 
231
        for (path, previous_path) in entries:
 
232
            if not path or path[-1] == "/":
 
233
                # directory
 
234
                directories.append((path, previous_path))
 
235
            else:
 
236
                # Yield the referenced parent directories
 
237
                for direntry in directories:
 
238
                    if osutils.is_inside(direntry[0], path):
 
239
                        directory_used.add(direntry[0])
 
240
        for (path, previous_path) in entries:
 
241
            if (not path.endswith("/")) or path in directory_used:
 
242
                yield (path, previous_path)
 
243
 
 
244
    def __str__(self):
 
245
        return 'HasPathRelations(%r, %r)' % (self.previous_tree, self.previous_entries)
 
246
 
 
247
    def match(self, tree):
 
248
        actual = list(self.get_path_map(tree))
 
249
        if not tree.has_versioned_directories():
 
250
            entries = list(self._strip_unreferenced_directories(
 
251
                self.previous_entries))
 
252
        else:
 
253
            entries = self.previous_entries
 
254
        if not tree.supports_rename_tracking():
 
255
            entries = [
 
256
                (path, path if self.previous_tree.is_versioned(path) else None)
 
257
                for (path, previous_path) in entries]
 
258
        return Equals(entries).match(actual)
 
259
 
 
260
 
185
261
class RevisionHistoryMatches(Matcher):
186
262
    """A matcher that checks if a branch has a specific revision history.
187
263
 
213
289
    def describe(self):
214
290
        return "no VFS calls expected, got: %s" % ",".join([
215
291
            "%s(%s)" % (c.method,
216
 
                ", ".join([repr(a) for a in c.args])) for c in self.vfs_calls])
 
292
                        ", ".join([repr(a) for a in c.args])) for c in self.vfs_calls])
217
293
 
218
294
 
219
295
class ContainsNoVfsCalls(Matcher):