/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
    inventory,
23
    tests,
24
    )
25
26
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
27
class InstrumentedReporter(object):
28
    def __init__(self):
29
        self.calls = []
30
31
    def report(self, file_id, path, versioned, renamed, modified, exe_change,
32
               kind):
33
        self.calls.append((file_id, path, versioned, renamed, modified,
34
                           exe_change, kind))
35
2225.1.4 by Aaron Bentley
PEP8 cleanup
36
2225.1.1 by Aaron Bentley
Added revert change display, with tests
37
class TestReportChanges(tests.TestCase):
2225.1.4 by Aaron Bentley
PEP8 cleanup
38
    """Test the new change reporting infrastructure"""
2225.1.1 by Aaron Bentley
Added revert change display, with tests
39
2225.1.3 by Aaron Bentley
change method names to assertFoo
40
    def assertReport(self, expected, file_id='fid', path='path',
41
                     versioned_change='unchanged', renamed=False,
42
                     modified='unchanged', exe_change=False,
43
                     kind=('file', 'file'), old_path=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)
47
        inv = inventory.Inventory()
48
        if old_path is not None:
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
49
            inv.add(inventory.InventoryFile(file_id, old_path,
2225.1.1 by Aaron Bentley
Added revert change display, with tests
50
                                            inv.root.file_id))
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
51
        reporter = _mod_delta.ChangeReporter(inv, result_line)
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
52
        reporter.report(file_id, path, versioned_change, renamed, modified,
2225.1.1 by Aaron Bentley
Added revert change display, with tests
53
                         exe_change, kind)
54
        self.assertEqualDiff(expected, result[0])
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',
64
                          kind=('file', 'directory'))
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'))
81
        self.assertReport('+K  path => path/', versioned_change='added',
82
                          modified='kind changed', kind=('file', 'directory'))
2225.1.1 by Aaron Bentley
Added revert change display, with tests
83
84
    def test_removal(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
85
        self.assertReport(' D  path/', modified='deleted',
86
                          kind=('directory', None), old_path='old')
87
        self.assertReport('-   path/', versioned_change='removed',
88
                          kind=(None, 'directory'))
89
        self.assertReport('-D  path', versioned_change='removed',
90
                          modified='deleted', kind=('file', 'directory'))
2225.1.1 by Aaron Bentley
Added revert change display, with tests
91
92
    def test_modification(self):
2225.1.3 by Aaron Bentley
change method names to assertFoo
93
        self.assertReport(' M  path', modified='modified')
94
        self.assertReport(' M* path', modified='modified', exe_change=True)
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
95
2225.1.3 by Aaron Bentley
change method names to assertFoo
96
    def assertChangesEqual(self,
97
                           file_id='fid',
98
                           path='path',
99
                           content_change=False,
100
                           versioned=(True, True),
101
                           parent_id=('pid', 'pid'),
102
                           name=('name', 'name'),
103
                           kind=('file', 'file'),
104
                           executable=(False, False),
105
                           versioned_change='unchanged',
106
                           renamed=False,
107
                           modified='unchanged',
108
                           exe_change=False):
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
109
        reporter = InstrumentedReporter()
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
110
        _mod_delta.report_changes([(file_id, path, content_change, versioned,
111
            parent_id, name, kind, executable)], reporter)
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
112
        output = reporter.calls[0]
113
        self.assertEqual(file_id, output[0])
114
        self.assertEqual(path, output[1])
115
        self.assertEqual(versioned_change, output[2])
116
        self.assertEqual(renamed, output[3])
117
        self.assertEqual(modified, output[4])
118
        self.assertEqual(exe_change, output[5])
119
        self.assertEqual(kind, output[6])
120
121
    def test_report_changes(self):
122
        """Test change detection of report_changes"""
123
        #Ensure no changes are detected by default
2225.1.3 by Aaron Bentley
change method names to assertFoo
124
        self.assertChangesEqual(modified='unchanged', renamed=False,
125
                                versioned_change='unchanged',
126
                                exe_change=False)
127
        self.assertChangesEqual(modified='kind changed',
128
                                kind=('file', 'directory'))
129
        self.assertChangesEqual(modified='created', kind=(None, 'directory'))
130
        self.assertChangesEqual(modified='deleted', kind=('directory', None))
131
        self.assertChangesEqual(content_change=True, modified='modified')
132
        self.assertChangesEqual(renamed=True, name=('old', 'new'))
133
        self.assertChangesEqual(renamed=True,
134
                                parent_id=('old-parent', 'new-parent'))
135
        self.assertChangesEqual(versioned_change='added',
136
                                versioned=(False, True))
137
        self.assertChangesEqual(versioned_change='removed',
138
                                versioned=(True, False))
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
139
        # execute bit is only detected as "changed" if the file is and was
140
        # a regular file.
2225.1.3 by Aaron Bentley
change method names to assertFoo
141
        self.assertChangesEqual(exe_change=True, executable=(True, False))
142
        self.assertChangesEqual(exe_change=False, executable=(True, False),
143
                                kind=('directory', 'directory'))
144
        self.assertChangesEqual(exe_change=False, modified='kind changed',
145
                                executable=(False, True),
146
                                kind=('directory', 'file'))
1551.11.3 by Aaron Bentley
Use tree transform to emit upcoming change list
147
        self.assertChangesEqual(parent_id=('pid', None))
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
148
149
        # Now make sure they all work together
2225.1.3 by Aaron Bentley
change method names to assertFoo
150
        self.assertChangesEqual(versioned_change='removed',
151
                                modified='deleted', versioned=(True, False),
152
                                kind=('directory', None))
153
        self.assertChangesEqual(versioned_change='removed',
154
                                modified='created', versioned=(True, False),
155
                                kind=(None, 'file'))
156
        self.assertChangesEqual(versioned_change='removed',
157
                                modified='modified', renamed=True,
158
                                exe_change=True, versioned=(True, False),
159
                                content_change=True, name=('old', 'new'),
160
                                executable=(False, True))
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
161
162
163
class TestChangesFrom (tests.TestCaseWithTransport):
164
165
    def show_string(self, delta, *args,  **kwargs):
166
        to_file = StringIO()
167
        delta.show(to_file, *args, **kwargs)
168
        return to_file.getvalue()
169
170
    def test_kind_change(self):
171
        """Doing a status when a file has changed kind should work"""
172
        tree = self.make_branch_and_tree('.')
173
        self.build_tree(['filename'])
174
        tree.add('filename', 'file-id')
175
        tree.commit('added filename')
176
        os.unlink('filename')
177
        self.build_tree(['filename/'])
178
        delta = tree.changes_from(tree.basis_tree())
179
        self.assertEqual([('filename', 'file-id', 'file', 'directory')],
180
                         delta.kind_changed)
181
        self.assertEqual([], delta.added)
182
        self.assertEqual([], delta.removed)
183
        self.assertEqual([], delta.renamed)
184
        self.assertEqual([], delta.modified)
185
        self.assertEqual([], delta.unchanged)
186
        self.assertTrue(delta.has_changed())
187
        self.assertTrue(delta.touches_file_id('file-id'))
188
        self.assertEqual('kind changed:\n  filename (file => directory)\n',
189
                         self.show_string(delta))
190
        other_delta = _mod_delta.TreeDelta()
191
        self.assertNotEqual(other_delta, delta)
192
        other_delta.kind_changed = [('filename', 'file-id', 'file',
193
                                     'symlink')]
194
        self.assertNotEqual(other_delta, delta)
195
        other_delta.kind_changed = [('filename', 'file-id', 'file',
196
                                     'directory')]
197
        self.assertEqual(other_delta, delta)
198
        self.assertEqualDiff("TreeDelta(added=[], removed=[], renamed=[],"
199
            " kind_changed=[(u'filename', 'file-id', 'file', 'directory')],"
200
            " modified=[], unchanged=[])", repr(delta))
201
        self.assertEqual('K  filename (file => directory) file-id\n',
202
                         self.show_string(delta, show_ids=True,
203
                         short_status=True))
204
205
        tree.rename_one('filename', 'dirname')
206
        delta = tree.changes_from(tree.basis_tree())
207
        self.assertEqual([], delta.kind_changed)
208
        # This loses the fact that kind changed, remembering it as a
209
        # modification
210
        self.assertEqual([('filename', 'dirname', 'file-id', 'directory',
211
                           True, False)], delta.renamed)
212
        self.assertTrue(delta.has_changed())
213
        self.assertTrue(delta.touches_file_id('file-id'))