/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2225.1.1 by Aaron Bentley
Added revert change display, with tests
1
# Copyright (C) 2007 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
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
17
import os
18
from StringIO import StringIO
19
2225.1.1 by Aaron Bentley
Added revert change display, with tests
20
from bzrlib import (
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
21
    delta as _mod_delta,
2225.1.1 by Aaron Bentley
Added revert change display, with tests
22
    tests,
23
    )
24
25
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
26
class InstrumentedReporter(object):
27
    def __init__(self):
28
        self.calls = []
29
30
    def report(self, file_id, path, versioned, renamed, modified, exe_change,
31
               kind):
32
        self.calls.append((file_id, path, versioned, renamed, modified,
33
                           exe_change, kind))
34
2225.1.4 by Aaron Bentley
PEP8 cleanup
35
2225.1.1 by Aaron Bentley
Added revert change display, with tests
36
class TestReportChanges(tests.TestCase):
2225.1.4 by Aaron Bentley
PEP8 cleanup
37
    """Test the new change reporting infrastructure"""
2225.1.1 by Aaron Bentley
Added revert change display, with tests
38
2225.1.3 by Aaron Bentley
change method names to assertFoo
39
    def assertReport(self, expected, file_id='fid', path='path',
40
                     versioned_change='unchanged', renamed=False,
41
                     modified='unchanged', exe_change=False,
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
42
                     kind=('file', 'file'), old_path=None,
43
                     unversioned_filter=None):
2225.1.1 by Aaron Bentley
Added revert change display, with tests
44
        result = []
45
        def result_line(format, *args):
46
            result.append(format % args)
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
47
        reporter = _mod_delta.ChangeReporter(result_line,
48
            unversioned_filter=unversioned_filter)
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
49
        reporter.report(file_id, (old_path, path), versioned_change, renamed,
50
            modified, exe_change, kind)
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
51
        if expected is not None:
52
            self.assertEqualDiff(expected, result[0])
53
        else:
54
            self.assertEqual([], result)
2225.1.1 by Aaron Bentley
Added revert change display, with tests
55
56
    def test_rename(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
57
        self.assertReport('R   old => path', renamed=True, old_path='old')
58
        self.assertReport('    path')
1551.10.12 by Aaron Bentley
Handle simultaneous creation+rename
59
        self.assertReport('RN  old => path', renamed=True, old_path='old',
60
                          modified='created', kind=(None, 'file'))
2225.1.1 by Aaron Bentley
Added revert change display, with tests
61
62
    def test_kind(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
63
        self.assertReport(' K  path => path/', modified='kind changed',
2255.7.96 by Robert Collins
Change _iter_changes interface to yield both old and new paths.
64
                          kind=('file', 'directory'), old_path='path')
2225.1.3 by Aaron Bentley
change method names to assertFoo
65
        self.assertReport(' K  path/ => path', modified='kind changed',
66
                          kind=('directory', 'file'), old_path='old')
67
        self.assertReport('RK  old => path/', renamed=True,
2225.1.5 by Aaron Bentley
Clean up whitespace changes
68
                          modified='kind changed',
2225.1.3 by Aaron Bentley
change method names to assertFoo
69
                          kind=('file', 'directory'), old_path='old')
2225.1.1 by Aaron Bentley
Added revert change display, with tests
70
    def test_new(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
71
        self.assertReport(' N  path/', modified='created',
72
                          kind=(None, 'directory'))
73
        self.assertReport('+   path/', versioned_change='added',
74
                          modified='unchanged', kind=(None, 'directory'))
1551.10.11 by Aaron Bentley
Handle case where file-id only is added
75
        self.assertReport('+   path', versioned_change='added',
76
                          modified='unchanged', kind=(None, None))
2225.1.3 by Aaron Bentley
change method names to assertFoo
77
        self.assertReport('+N  path/', versioned_change='added',
78
                          modified='created', kind=(None, 'directory'))
79
        self.assertReport('+M  path/', versioned_change='added',
80
                          modified='modified', kind=(None, 'directory'))
2225.1.1 by Aaron Bentley
Added revert change display, with tests
81
82
    def test_removal(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
83
        self.assertReport(' D  path/', modified='deleted',
84
                          kind=('directory', None), old_path='old')
85
        self.assertReport('-   path/', versioned_change='removed',
86
                          kind=(None, 'directory'))
87
        self.assertReport('-D  path', versioned_change='removed',
88
                          modified='deleted', kind=('file', 'directory'))
2225.1.1 by Aaron Bentley
Added revert change display, with tests
89
90
    def test_modification(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
91
        self.assertReport(' M  path', modified='modified')
92
        self.assertReport(' M* path', modified='modified', exe_change=True)
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
93
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
94
    def test_unversioned(self):
95
        # by default any unversioned file is output
96
        self.assertReport('?   subdir/foo~', file_id=None, path='subdir/foo~',
97
            old_path=None, versioned_change='unversioned',
98
            renamed=False, modified='created', exe_change=False,
99
            kind=(None, 'file'))
100
        # but we can choose to filter these. Probably that should be done 
101
        # close to the tree, but this is a reasonable starting point.
102
        self.assertReport(None, file_id=None, path='subdir/foo~',
103
            old_path=None, versioned_change='unversioned',
104
            renamed=False, modified='created', exe_change=False,
105
            kind=(None, 'file'), unversioned_filter=lambda x:True)
106
2225.1.3 by Aaron Bentley
change method names to assertFoo
107
    def assertChangesEqual(self,
108
                           file_id='fid',
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
109
                           paths=('path', 'path'),
2225.1.3 by Aaron Bentley
change method names to assertFoo
110
                           content_change=False,
111
                           versioned=(True, True),
112
                           parent_id=('pid', 'pid'),
113
                           name=('name', 'name'),
114
                           kind=('file', 'file'),
115
                           executable=(False, False),
116
                           versioned_change='unchanged',
117
                           renamed=False,
118
                           modified='unchanged',
119
                           exe_change=False):
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
120
        reporter = InstrumentedReporter()
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
121
        _mod_delta.report_changes([(file_id, paths, content_change, versioned,
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
122
            parent_id, name, kind, executable)], reporter)
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
123
        output = reporter.calls[0]
124
        self.assertEqual(file_id, output[0])
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
125
        self.assertEqual(paths, output[1])
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
126
        self.assertEqual(versioned_change, output[2])
127
        self.assertEqual(renamed, output[3])
128
        self.assertEqual(modified, output[4])
129
        self.assertEqual(exe_change, output[5])
130
        self.assertEqual(kind, output[6])
131
132
    def test_report_changes(self):
133
        """Test change detection of report_changes"""
134
        #Ensure no changes are detected by default
2225.1.3 by Aaron Bentley
change method names to assertFoo
135
        self.assertChangesEqual(modified='unchanged', renamed=False,
136
                                versioned_change='unchanged',
137
                                exe_change=False)
138
        self.assertChangesEqual(modified='kind changed',
139
                                kind=('file', 'directory'))
140
        self.assertChangesEqual(modified='created', kind=(None, 'directory'))
141
        self.assertChangesEqual(modified='deleted', kind=('directory', None))
142
        self.assertChangesEqual(content_change=True, modified='modified')
143
        self.assertChangesEqual(renamed=True, name=('old', 'new'))
144
        self.assertChangesEqual(renamed=True,
145
                                parent_id=('old-parent', 'new-parent'))
146
        self.assertChangesEqual(versioned_change='added',
147
                                versioned=(False, True))
148
        self.assertChangesEqual(versioned_change='removed',
149
                                versioned=(True, False))
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
150
        # execute bit is only detected as "changed" if the file is and was
151
        # a regular file.
2225.1.3 by Aaron Bentley
change method names to assertFoo
152
        self.assertChangesEqual(exe_change=True, executable=(True, False))
153
        self.assertChangesEqual(exe_change=False, executable=(True, False),
154
                                kind=('directory', 'directory'))
155
        self.assertChangesEqual(exe_change=False, modified='kind changed',
156
                                executable=(False, True),
157
                                kind=('directory', 'file'))
1551.11.3 by Aaron Bentley
Use tree transform to emit upcoming change list
158
        self.assertChangesEqual(parent_id=('pid', None))
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
159
160
        # Now make sure they all work together
2225.1.3 by Aaron Bentley
change method names to assertFoo
161
        self.assertChangesEqual(versioned_change='removed',
162
                                modified='deleted', versioned=(True, False),
163
                                kind=('directory', None))
164
        self.assertChangesEqual(versioned_change='removed',
165
                                modified='created', versioned=(True, False),
166
                                kind=(None, 'file'))
167
        self.assertChangesEqual(versioned_change='removed',
168
                                modified='modified', renamed=True,
169
                                exe_change=True, versioned=(True, False),
170
                                content_change=True, name=('old', 'new'),
171
                                executable=(False, True))
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
172
2255.7.97 by Robert Collins
Teach delta.report_changes about unversioned files, removing all inventory access during status --short.
173
    def test_report_unversioned(self):
174
        """Unversioned entries are reported well."""
175
        self.assertChangesEqual(file_id=None, paths=(None, 'full/path'),
176
                           content_change=True,
177
                           versioned=(False, False),
178
                           parent_id=(None, None),
179
                           name=(None, 'path'),
180
                           kind=(None, 'file'),
181
                           executable=(None, False),
182
                           versioned_change='unversioned',
183
                           renamed=False,
184
                           modified='created',
185
                           exe_change=False)
186
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
187
188
class TestChangesFrom (tests.TestCaseWithTransport):
189
190
    def show_string(self, delta, *args,  **kwargs):
191
        to_file = StringIO()
192
        delta.show(to_file, *args, **kwargs)
193
        return to_file.getvalue()
194
195
    def test_kind_change(self):
196
        """Doing a status when a file has changed kind should work"""
197
        tree = self.make_branch_and_tree('.')
198
        self.build_tree(['filename'])
199
        tree.add('filename', 'file-id')
200
        tree.commit('added filename')
201
        os.unlink('filename')
202
        self.build_tree(['filename/'])
203
        delta = tree.changes_from(tree.basis_tree())
204
        self.assertEqual([('filename', 'file-id', 'file', 'directory')],
205
                         delta.kind_changed)
206
        self.assertEqual([], delta.added)
207
        self.assertEqual([], delta.removed)
208
        self.assertEqual([], delta.renamed)
209
        self.assertEqual([], delta.modified)
210
        self.assertEqual([], delta.unchanged)
211
        self.assertTrue(delta.has_changed())
212
        self.assertTrue(delta.touches_file_id('file-id'))
213
        self.assertEqual('kind changed:\n  filename (file => directory)\n',
214
                         self.show_string(delta))
215
        other_delta = _mod_delta.TreeDelta()
216
        self.assertNotEqual(other_delta, delta)
217
        other_delta.kind_changed = [('filename', 'file-id', 'file',
218
                                     'symlink')]
219
        self.assertNotEqual(other_delta, delta)
220
        other_delta.kind_changed = [('filename', 'file-id', 'file',
221
                                     'directory')]
222
        self.assertEqual(other_delta, delta)
223
        self.assertEqualDiff("TreeDelta(added=[], removed=[], renamed=[],"
224
            " kind_changed=[(u'filename', 'file-id', 'file', 'directory')],"
2255.7.90 by Robert Collins
Add unversioned path reporting to TreeDelta.
225
            " modified=[], unchanged=[], unversioned=[])", repr(delta))
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
226
        self.assertEqual('K  filename (file => directory) file-id\n',
227
                         self.show_string(delta, show_ids=True,
228
                         short_status=True))
229
230
        tree.rename_one('filename', 'dirname')
231
        delta = tree.changes_from(tree.basis_tree())
232
        self.assertEqual([], delta.kind_changed)
233
        # This loses the fact that kind changed, remembering it as a
234
        # modification
235
        self.assertEqual([('filename', 'dirname', 'file-id', 'directory',
236
                           True, False)], delta.renamed)
237
        self.assertTrue(delta.has_changed())
238
        self.assertTrue(delta.touches_file_id('file-id'))