/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'))
2225.1.2 by Aaron Bentley
Ensure that changes are detected correctly
147
148
        # Now make sure they all work together
2225.1.3 by Aaron Bentley
change method names to assertFoo
149
        self.assertChangesEqual(versioned_change='removed',
150
                                modified='deleted', versioned=(True, False),
151
                                kind=('directory', None))
152
        self.assertChangesEqual(versioned_change='removed',
153
                                modified='created', versioned=(True, False),
154
                                kind=(None, 'file'))
155
        self.assertChangesEqual(versioned_change='removed',
156
                                modified='modified', renamed=True,
157
                                exe_change=True, versioned=(True, False),
158
                                content_change=True, name=('old', 'new'),
159
                                executable=(False, True))
1551.10.6 by Aaron Bentley
Support kind changes in tree deltas
160
161
162
class TestChangesFrom (tests.TestCaseWithTransport):
163
164
    def show_string(self, delta, *args,  **kwargs):
165
        to_file = StringIO()
166
        delta.show(to_file, *args, **kwargs)
167
        return to_file.getvalue()
168
169
    def test_kind_change(self):
170
        """Doing a status when a file has changed kind should work"""
171
        tree = self.make_branch_and_tree('.')
172
        self.build_tree(['filename'])
173
        tree.add('filename', 'file-id')
174
        tree.commit('added filename')
175
        os.unlink('filename')
176
        self.build_tree(['filename/'])
177
        delta = tree.changes_from(tree.basis_tree())
178
        self.assertEqual([('filename', 'file-id', 'file', 'directory')],
179
                         delta.kind_changed)
180
        self.assertEqual([], delta.added)
181
        self.assertEqual([], delta.removed)
182
        self.assertEqual([], delta.renamed)
183
        self.assertEqual([], delta.modified)
184
        self.assertEqual([], delta.unchanged)
185
        self.assertTrue(delta.has_changed())
186
        self.assertTrue(delta.touches_file_id('file-id'))
187
        self.assertEqual('kind changed:\n  filename (file => directory)\n',
188
                         self.show_string(delta))
189
        other_delta = _mod_delta.TreeDelta()
190
        self.assertNotEqual(other_delta, delta)
191
        other_delta.kind_changed = [('filename', 'file-id', 'file',
192
                                     'symlink')]
193
        self.assertNotEqual(other_delta, delta)
194
        other_delta.kind_changed = [('filename', 'file-id', 'file',
195
                                     'directory')]
196
        self.assertEqual(other_delta, delta)
197
        self.assertEqualDiff("TreeDelta(added=[], removed=[], renamed=[],"
198
            " kind_changed=[(u'filename', 'file-id', 'file', 'directory')],"
199
            " modified=[], unchanged=[])", repr(delta))
200
        self.assertEqual('K  filename (file => directory) file-id\n',
201
                         self.show_string(delta, show_ids=True,
202
                         short_status=True))
203
204
        tree.rename_one('filename', 'dirname')
205
        delta = tree.changes_from(tree.basis_tree())
206
        self.assertEqual([], delta.kind_changed)
207
        # This loses the fact that kind changed, remembering it as a
208
        # modification
209
        self.assertEqual([('filename', 'dirname', 'file-id', 'directory',
210
                           True, False)], delta.renamed)
211
        self.assertTrue(delta.has_changed())
212
        self.assertTrue(delta.touches_file_id('file-id'))