~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/tree_implementations/__init__.py

merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2006 by Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
"""Tree implementation tests for bzr.
 
19
 
 
20
These test the conformance of all the tree variations to the expected API.
 
21
Specific tests for individual variations are in other places such as:
 
22
 - tests/test_tree.py
 
23
 - tests/test_revision.py
 
24
 - tests/test_workingtree.py
 
25
 - tests/workingtree_implementations/*.py.
 
26
"""
 
27
 
 
28
from bzrlib import (
 
29
    errors,
 
30
    transform,
 
31
    )
 
32
from bzrlib.transport import get_transport
 
33
from bzrlib.tests import (
 
34
                          adapt_modules,
 
35
                          default_transport,
 
36
                          TestCaseWithTransport,
 
37
                          TestLoader,
 
38
                          TestSuite,
 
39
                          )
 
40
from bzrlib.tests.bzrdir_implementations.test_bzrdir import TestCaseWithBzrDir
 
41
from bzrlib.tree import RevisionTree
 
42
from bzrlib.workingtree import (WorkingTreeFormat,
 
43
                                WorkingTreeTestProviderAdapter,
 
44
                                _legacy_formats,
 
45
                                )
 
46
 
 
47
 
 
48
def return_parameter(something):
 
49
    """A trivial thunk to return its input."""
 
50
    return something
 
51
 
 
52
 
 
53
def revision_tree_from_workingtree(tree):
 
54
    """Create a revision tree from a working tree."""
 
55
    revid = tree.commit('save tree', allow_pointless=True)
 
56
    return tree.branch.repository.revision_tree(revid)
 
57
 
 
58
 
 
59
class TestTreeImplementationSupport(TestCaseWithTransport):
 
60
 
 
61
    def test_revision_tree_from_workingtree(self):
 
62
        tree = self.make_branch_and_tree('.')
 
63
        tree = revision_tree_from_workingtree(tree)
 
64
        self.assertIsInstance(tree, RevisionTree)
 
65
 
 
66
 
 
67
class TestCaseWithTree(TestCaseWithBzrDir):
 
68
 
 
69
    def make_branch_and_tree(self, relpath):
 
70
        made_control = self.make_bzrdir(relpath, format=
 
71
            self.workingtree_format._matchingbzrdir)
 
72
        made_control.create_repository()
 
73
        made_control.create_branch()
 
74
        return self.workingtree_format.initialize(made_control)
 
75
 
 
76
    def _convert_tree(self, tree, converter=None):
 
77
        """helper to convert using the converter or a supplied one."""
 
78
        # convert that to the final shape
 
79
        if converter is None:
 
80
            converter = self.workingtree_to_test_tree
 
81
        return converter(tree)
 
82
 
 
83
    def get_tree_no_parents_no_content(self, empty_tree, converter=None):
 
84
        """Make a tree with no parents and no contents from empty_tree.
 
85
        
 
86
        :param empty_tree: A working tree with no content and no parents to
 
87
            modify.
 
88
        """
 
89
        return self._convert_tree(empty_tree, converter)
 
90
 
 
91
    def _make_abc_tree(self, tree):
 
92
        """setup an abc content tree."""
 
93
        files = ['a', 'b/', 'b/c']
 
94
        self.build_tree(files, transport=tree.bzrdir.root_transport)
 
95
        tree.add(files, ['a-id', 'b-id', 'c-id'])
 
96
 
 
97
    def get_tree_no_parents_abc_content(self, tree, converter=None):
 
98
        """return a test tree with a, b/, b/c contents."""
 
99
        self._make_abc_tree(tree)
 
100
        return self._convert_tree(tree, converter)
 
101
 
 
102
    def get_tree_no_parents_abc_content_2(self, tree, converter=None):
 
103
        """return a test tree with a, b/, b/c contents.
 
104
        
 
105
        This variation changes the content of 'a' to foobar\n.
 
106
        """
 
107
        self._make_abc_tree(tree)
 
108
        f = open(tree.basedir + '/a', 'wb')
 
109
        try:
 
110
            f.write('foobar\n')
 
111
        finally:
 
112
            f.close()
 
113
        return self._convert_tree(tree, converter)
 
114
 
 
115
    def get_tree_no_parents_abc_content_3(self, tree, converter=None):
 
116
        """return a test tree with a, b/, b/c contents.
 
117
        
 
118
        This variation changes the executable flag of b/c to True.
 
119
        """
 
120
        self._make_abc_tree(tree)
 
121
        tt = transform.TreeTransform(tree)
 
122
        trans_id = tt.trans_id_tree_path('b/c')
 
123
        tt.set_executability(True, trans_id)
 
124
        tt.apply()
 
125
        return self._convert_tree(tree, converter)
 
126
 
 
127
    def get_tree_no_parents_abc_content_4(self, tree, converter=None):
 
128
        """return a test tree with d, b/, b/c contents.
 
129
        
 
130
        This variation renames a to d.
 
131
        """
 
132
        self._make_abc_tree(tree)
 
133
        tree.rename_one('a', 'd')
 
134
        return self._convert_tree(tree, converter)
 
135
 
 
136
    def get_tree_no_parents_abc_content_5(self, tree, converter=None):
 
137
        """return a test tree with d, b/, b/c contents.
 
138
        
 
139
        This variation renames a to d and alters its content to 'bar\n'.
 
140
        """
 
141
        self._make_abc_tree(tree)
 
142
        tree.rename_one('a', 'd')
 
143
        f = open(tree.basedir + '/d', 'wb')
 
144
        try:
 
145
            f.write('bar\n')
 
146
        finally:
 
147
            f.close()
 
148
        return self._convert_tree(tree, converter)
 
149
 
 
150
    def get_tree_no_parents_abc_content_6(self, tree, converter=None):
 
151
        """return a test tree with a, b/, e contents.
 
152
        
 
153
        This variation renames b/c to e, and makes it executable.
 
154
        """
 
155
        self._make_abc_tree(tree)
 
156
        tt = transform.TreeTransform(tree)
 
157
        trans_id = tt.trans_id_tree_path('b/c')
 
158
        parent_trans_id = tt.trans_id_tree_path('')
 
159
        tt.adjust_path('e', parent_trans_id, trans_id)
 
160
        tt.set_executability(True, trans_id)
 
161
        tt.apply()
 
162
        return self._convert_tree(tree, converter)
 
163
 
 
164
 
 
165
class TreeTestProviderAdapter(WorkingTreeTestProviderAdapter):
 
166
    """Generate test suites for each Tree implementation in bzrlib.
 
167
 
 
168
    Currently this covers all working tree formats, and RevisionTree by 
 
169
    committing a working tree to create the revision tree.
 
170
    """
 
171
 
 
172
    def adapt(self, test):
 
173
        result = super(TreeTestProviderAdapter, self).adapt(test)
 
174
        for adapted_test in result:
 
175
            # for working tree adapted tests, preserve the tree
 
176
            adapted_test.workingtree_to_test_tree = return_parameter
 
177
        default_format = WorkingTreeFormat.get_default_format()
 
178
        revision_tree_test = self._clone_test(
 
179
            test,
 
180
            default_format._matchingbzrdir, 
 
181
            default_format,
 
182
            RevisionTree.__name__)
 
183
        revision_tree_test.workingtree_to_test_tree = revision_tree_from_workingtree
 
184
        result.addTest(revision_tree_test)
 
185
        return result
 
186
 
 
187
 
 
188
def test_suite():
 
189
    result = TestSuite()
 
190
    test_tree_implementations = [
 
191
        'bzrlib.tests.tree_implementations.test_test_trees',
 
192
        ]
 
193
    adapter = TreeTestProviderAdapter(
 
194
        default_transport,
 
195
        # None here will cause a readonly decorator to be created
 
196
        # by the TestCaseWithTransport.get_readonly_transport method.
 
197
        None,
 
198
        [(format, format._matchingbzrdir) for format in 
 
199
         WorkingTreeFormat._formats.values() + _legacy_formats])
 
200
    loader = TestLoader()
 
201
    adapt_modules(test_tree_implementations, adapter, loader, result)
 
202
    result.addTests(loader.loadTestsFromModuleNames(['bzrlib.tests.tree_implementations']))
 
203
    return result