/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
1
from cStringIO import StringIO
2
3
from bzrlib.diff import internal_diff
4
from bzrlib.errors import BinaryFile
1185.81.25 by Aaron Bentley
Clean up test_diff
5
from bzrlib.patiencediff import (recurse_matches, SequenceMatcher, unique_lcs,
6
                                 unified_diff, unified_diff_files)
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
7
from bzrlib.tests import TestCase, TestCaseInTempDir
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
8
9
1558.15.11 by Aaron Bentley
Apply merge review suggestions
10
def udiff_lines(old, new, allow_binary=False):
974.1.6 by Aaron Bentley
Added unit tests
11
    output = StringIO()
1558.15.11 by Aaron Bentley
Apply merge review suggestions
12
    internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
13
    output.seek(0, 0)
14
    return output.readlines()
15
1185.81.25 by Aaron Bentley
Clean up test_diff
16
1102 by Martin Pool
- merge test refactoring from robertc
17
class TestDiff(TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
18
1102 by Martin Pool
- merge test refactoring from robertc
19
    def test_add_nl(self):
20
        """diff generates a valid diff for patches that add a newline"""
974.1.6 by Aaron Bentley
Added unit tests
21
        lines = udiff_lines(['boo'], ['boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
22
        self.check_patch(lines)
23
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
24
            ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
25
1102 by Martin Pool
- merge test refactoring from robertc
26
    def test_add_nl_2(self):
27
        """diff generates a valid diff for patches that change last line and
28
        add a newline.
29
        """
974.1.6 by Aaron Bentley
Added unit tests
30
        lines = udiff_lines(['boo'], ['goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
31
        self.check_patch(lines)
32
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
33
            ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
34
1102 by Martin Pool
- merge test refactoring from robertc
35
    def test_remove_nl(self):
36
        """diff generates a valid diff for patches that change last line and
37
        add a newline.
38
        """
974.1.6 by Aaron Bentley
Added unit tests
39
        lines = udiff_lines(['boo\n'], ['boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
40
        self.check_patch(lines)
41
        self.assertEquals(lines[5], '\\ No newline at end of file\n')
42
            ## "expected no-nl, got %r" % lines[5]
43
44
    def check_patch(self, lines):
45
        self.assert_(len(lines) > 1)
46
            ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
47
        self.assert_(lines[0].startswith ('---'))
48
            ## 'No orig line for patch:\n%s' % "".join(lines)
49
        self.assert_(lines[1].startswith ('+++'))
50
            ## 'No mod line for patch:\n%s' % "".join(lines)
51
        self.assert_(len(lines) > 2)
52
            ## "No hunks for patch:\n%s" % "".join(lines)
53
        self.assert_(lines[2].startswith('@@'))
54
            ## "No hunk header for patch:\n%s" % "".join(lines)
55
        self.assert_('@@' in lines[2][2:])
56
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
57
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
58
    def test_binary_lines(self):
59
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
60
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
1558.15.11 by Aaron Bentley
Apply merge review suggestions
61
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
62
        udiff_lines([], [1023 * 'a' + '\x00'], allow_binary=True)
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
63
1185.81.25 by Aaron Bentley
Clean up test_diff
64
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
65
class TestCDVDiffLib(TestCase):
66
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
67
    def test_unique_lcs(self):
68
        self.assertEquals(unique_lcs('', ''), [])
69
        self.assertEquals(unique_lcs('a', 'a'), [(0,0)])
70
        self.assertEquals(unique_lcs('a', 'b'), [])
71
        self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
72
        self.assertEquals(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
73
        self.assertEquals(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
74
        self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1), 
75
                                                         (3,3), (4,4)])
76
        self.assertEquals(unique_lcs('acbac', 'abc'), [(2,1)])
77
78
    def test_recurse_matches(self):
79
        def test_one(a, b, matches):
80
            test_matches = []
81
            recurse_matches(a, b, len(a), len(b), test_matches, 10)
82
            self.assertEquals(test_matches, matches)
83
84
        test_one(['a', None, 'b', None, 'c'], ['a', 'a', 'b', 'c', 'c'],
85
                 [(0, 0), (2, 2), (4, 4)])
86
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
87
                 [(0, 0), (2, 1), (4, 2)])
88
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
89
        # recurse_matches doesn't match non-unique 
90
        # lines surrounded by bogus text.
1185.81.24 by Aaron Bentley
Reoganize patience-related code
91
        # The update has been done in patiencediff.SequenceMatcher instead
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
92
93
        # This is what it could be
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
94
        #test_one('aBccDe', 'abccde', [(0,0), (2,2), (3,3), (5,5)])
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
95
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
96
        # This is what it currently gives:
97
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
98
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
99
    def test_matching_blocks(self):
100
        def chk_blocks(a, b, matching):
101
            # difflib always adds a signature of the total
102
            # length, with no matching entries at the end
103
            s = SequenceMatcher(None, a, b)
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
104
            blocks = s.get_matching_blocks()
105
            x = blocks.pop()
106
            self.assertEquals(x, (len(a), len(b), 0))
107
            self.assertEquals(matching, blocks)
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
108
1185.81.2 by John Arbash Meinel
A couple small tests.
109
        # Some basic matching tests
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
110
        chk_blocks('', '', [])
111
        chk_blocks([], [], [])
112
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
113
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
114
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
115
        chk_blocks('eabce', 'abce', [(1, 0, 4)])
116
        chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
117
        chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
118
        chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
119
        # This may check too much, but it checks to see that 
120
        # a copied block stays attached to the previous section,
121
        # not the later one.
122
        # difflib would tend to grab the trailing longest match
123
        # which would make the diff not look right
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
124
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
125
                   [(0, 0, 6), (6, 11, 10)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
126
1185.81.2 by John Arbash Meinel
A couple small tests.
127
        # make sure it supports passing in lists
128
        chk_blocks(
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
129
                   ['hello there\n',
130
                    'world\n',
131
                    'how are you today?\n'],
132
                   ['hello there\n',
133
                    'how are you today?\n'],
1185.81.2 by John Arbash Meinel
A couple small tests.
134
                [(0, 0, 1), (2, 1, 1)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
135
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
136
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (2,2,2), (5,5,1)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
137
1185.81.10 by John Arbash Meinel
Added some more test cases.
138
        chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
139
                                              (5,5,2), (8,8,1)])
140
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
141
        chk_blocks('abbabbXd', 'cabbabxd', [(0,1,5), (7,7,1)])
142
        chk_blocks('abbabbbb', 'cabbabbc', [(0,1,6)])
143
        chk_blocks('bbbbbbbb', 'cbbbbbbc', [(0,1,6)])
144
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
145
    def test_opcodes(self):
146
        def chk_ops(a, b, codes):
147
            s = SequenceMatcher(None, a, b)
148
            self.assertEquals(codes, s.get_opcodes())
149
150
        chk_ops('', '', [])
151
        chk_ops([], [], [])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
152
        chk_ops('abcd', 'abcd', [('equal',    0,4, 0,4)])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
153
        chk_ops('abcd', 'abce', [('equal',   0,3, 0,3),
154
                                 ('replace', 3,4, 3,4)
155
                                ])
156
        chk_ops('eabc', 'abce', [('delete', 0,1, 0,0),
157
                                 ('equal',  1,4, 0,3),
158
                                 ('insert', 4,4, 3,4)
159
                                ])
160
        chk_ops('eabce', 'abce', [('delete', 0,1, 0,0),
161
                                  ('equal',  1,5, 0,4)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
162
                                 ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
163
        chk_ops('abcde', 'abXde', [('equal',   0,2, 0,2),
164
                                   ('replace', 2,3, 2,3),
165
                                   ('equal',   3,5, 3,5)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
166
                                  ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
167
        chk_ops('abcde', 'abXYZde', [('equal',   0,2, 0,2),
168
                                     ('replace', 2,3, 2,5),
169
                                     ('equal',   3,5, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
170
                                    ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
171
        chk_ops('abde', 'abXYZde', [('equal',  0,2, 0,2),
172
                                    ('insert', 2,2, 2,5),
173
                                    ('equal',  2,4, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
174
                                   ])
175
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
176
                [('equal',  0,6,  0,6),
177
                 ('insert', 6,6,  6,11),
178
                 ('equal',  6,16, 11,21)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
179
                ])
180
        chk_ops(
181
                [ 'hello there\n'
182
                , 'world\n'
183
                , 'how are you today?\n'],
184
                [ 'hello there\n'
185
                , 'how are you today?\n'],
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
186
                [('equal',  0,1, 0,1),
187
                 ('delete', 1,2, 1,1),
188
                 ('equal',  2,3, 1,2)
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
189
                ])
190
        chk_ops('aBccDe', 'abccde', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
191
                [('equal',   0,1, 0,1),
192
                 ('replace', 1,2, 1,2),
193
                 ('equal',   2,4, 2,4),
194
                 ('replace', 4,5, 4,5),
195
                 ('equal',   5,6, 5,6)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
196
                ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
197
        chk_ops('aBcdEcdFg', 'abcdecdfg', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
198
                [('equal',   0,1, 0,1),
199
                 ('replace', 1,2, 1,2),
200
                 ('equal',   2,4, 2,4),
201
                 ('replace', 4,5, 4,5),
202
                 ('equal',   5,7, 5,7),
203
                 ('replace', 7,8, 7,8),
204
                 ('equal',   8,9, 8,9)
1185.81.10 by John Arbash Meinel
Added some more test cases.
205
                ])
206
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
207
    def test_multiple_ranges(self):
208
        # There was an earlier bug where we used a bad set of ranges,
209
        # this triggers that specific bug, to make sure it doesn't regress
210
        def chk_blocks(a, b, matching):
211
            # difflib always adds a signature of the total
212
            # length, with no matching entries at the end
213
            s = SequenceMatcher(None, a, b)
214
            blocks = s.get_matching_blocks()
215
            x = blocks.pop()
216
            self.assertEquals(x, (len(a), len(b), 0))
217
            self.assertEquals(matching, blocks)
218
219
        chk_blocks('abcdefghijklmnop'
220
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
221
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
222
223
        chk_blocks('ABCd efghIjk  L'
224
                 , 'AxyzBCn mo pqrstuvwI1 2  L'
225
                 , [(0,0,1), (1, 4, 2), (4, 7, 1), (9, 19, 1), (12, 23, 3)])
226
227
        chk_blocks('''\
228
    get added when you add a file in the directory.
229
    """
230
    takes_args = ['file*']
231
    takes_options = ['no-recurse']
232
    
233
    def run(self, file_list, no_recurse=False):
234
        from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
235
        if is_quiet():
236
            reporter = add_reporter_null
237
        else:
238
            reporter = add_reporter_print
239
        smart_add(file_list, not no_recurse, reporter)
240
241
242
class cmd_mkdir(Command):
243
'''.splitlines(True)
244
, '''\
245
    get added when you add a file in the directory.
246
247
    --dry-run will show which files would be added, but not actually 
248
    add them.
249
    """
250
    takes_args = ['file*']
251
    takes_options = ['no-recurse', 'dry-run']
252
253
    def run(self, file_list, no_recurse=False, dry_run=False):
254
        import bzrlib.add
255
256
        if dry_run:
257
            if is_quiet():
258
                # This is pointless, but I'd rather not raise an error
259
                action = bzrlib.add.add_action_null
260
            else:
261
                action = bzrlib.add.add_action_print
262
        elif is_quiet():
263
            action = bzrlib.add.add_action_add
264
        else:
265
            action = bzrlib.add.add_action_add_and_print
266
267
        bzrlib.add.smart_add(file_list, not no_recurse, action)
268
269
270
class cmd_mkdir(Command):
271
'''.splitlines(True)
272
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
273
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
274
    def test_cdv_unified_diff(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
275
        txt_a = ['hello there\n',
276
                 'world\n',
277
                 'how are you today?\n']
278
        txt_b = ['hello there\n',
279
                 'how are you today?\n']
280
        self.assertEquals([ '---  \n',
281
                           '+++  \n',
282
                           '@@ -1,3 +1,2 @@\n',
283
                           ' hello there\n',
284
                           '-world\n',
285
                           ' how are you today?\n'
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
286
                          ]
287
                          , list(unified_diff(txt_a, txt_b
288
                                        , sequencematcher=SequenceMatcher)))
289
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
290
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
291
        # This is the result with LongestCommonSubstring matching
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
292
        self.assertEquals(['---  \n',
293
                           '+++  \n',
294
                           '@@ -1,6 +1,11 @@\n',
295
                           ' a\n',
296
                           ' b\n',
297
                           ' c\n',
298
                           '+d\n',
299
                           '+e\n',
300
                           '+f\n',
301
                           '+x\n',
302
                           '+y\n',
303
                           ' d\n',
304
                           ' e\n',
305
                           ' f\n']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
306
                          , list(unified_diff(txt_a, txt_b)))
307
        # And the cdv diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
308
        self.assertEquals(['---  \n',
309
                           '+++  \n',
310
                           '@@ -4,6 +4,11 @@\n',
311
                           ' d\n',
312
                           ' e\n',
313
                           ' f\n',
314
                           '+x\n',
315
                           '+y\n',
316
                           '+d\n',
317
                           '+e\n',
318
                           '+f\n',
319
                           ' g\n',
320
                           ' h\n',
321
                           ' i\n',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
322
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
323
                          , list(unified_diff(txt_a, txt_b,
324
                                 sequencematcher=SequenceMatcher)))
325
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
326
1185.81.15 by John Arbash Meinel
Forgot to make one of the tests TestCaseInTempDir
327
class TestCDVDiffLibFiles(TestCaseInTempDir):
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
328
329
    def test_cdv_unified_diff_files(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
330
        txt_a = ['hello there\n',
331
                 'world\n',
332
                 'how are you today?\n']
333
        txt_b = ['hello there\n',
334
                 'how are you today?\n']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
335
        open('a1', 'wb').writelines(txt_a)
336
        open('b1', 'wb').writelines(txt_b)
337
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
338
        self.assertEquals(['--- a1 \n',
339
                           '+++ b1 \n',
340
                           '@@ -1,3 +1,2 @@\n',
341
                           ' hello there\n',
342
                           '-world\n',
343
                           ' how are you today?\n',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
344
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
345
                          , list(unified_diff_files('a1', 'b1',
346
                                 sequencematcher=SequenceMatcher)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
347
348
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
349
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
350
        open('a2', 'wb').writelines(txt_a)
351
        open('b2', 'wb').writelines(txt_b)
352
353
        # This is the result with LongestCommonSubstring matching
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
354
        self.assertEquals(['--- a2 \n',
355
                           '+++ b2 \n',
356
                           '@@ -1,6 +1,11 @@\n',
357
                           ' a\n',
358
                           ' b\n',
359
                           ' c\n',
360
                           '+d\n',
361
                           '+e\n',
362
                           '+f\n',
363
                           '+x\n',
364
                           '+y\n',
365
                           ' d\n',
366
                           ' e\n',
367
                           ' f\n']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
368
                          , list(unified_diff_files('a2', 'b2')))
369
370
        # And the cdv diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
371
        self.assertEquals(['--- a2 \n',
372
                           '+++ b2 \n',
373
                           '@@ -4,6 +4,11 @@\n',
374
                           ' d\n',
375
                           ' e\n',
376
                           ' f\n',
377
                           '+x\n',
378
                           '+y\n',
379
                           '+d\n',
380
                           '+e\n',
381
                           '+f\n',
382
                           ' g\n',
383
                           ' h\n',
384
                           ' i\n',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
385
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
386
                          , list(unified_diff_files('a2', 'b2',
387
                                 sequencematcher=SequenceMatcher)))