/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_diff.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-11 04:08:32 UTC
  • mto: (7143.16.20 even-more-cleanups)
  • mto: This revision was merged to the branch mainline in revision 7175.
  • Revision ID: jelmer@jelmer.uk-20181111040832-nsljjynzzwmznf3h
Run autopep8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
class TestDiffOptionsScenarios(tests.TestCase):
106
106
 
107
107
    scenarios = [(s, dict(style=s)) for s in diff.style_option_list]
108
 
    style = None # Set by load_tests_apply_scenarios from scenarios
 
108
    style = None  # Set by load_tests_apply_scenarios from scenarios
109
109
 
110
110
    def test_unified_not_added(self):
111
111
        # Verify that for all valid style options, '-u' is not
121
121
        lines = udiff_lines([b'boo'], [b'boo\n'])
122
122
        self.check_patch(lines)
123
123
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
124
 
            ## "expected no-nl, got %r" % lines[4]
 
124
        ## "expected no-nl, got %r" % lines[4]
125
125
 
126
126
    def test_add_nl_2(self):
127
127
        """diff generates a valid diff for patches that change last line and
130
130
        lines = udiff_lines([b'boo'], [b'goo\n'])
131
131
        self.check_patch(lines)
132
132
        self.assertEqual(lines[4], b'\\ No newline at end of file\n')
133
 
            ## "expected no-nl, got %r" % lines[4]
 
133
        ## "expected no-nl, got %r" % lines[4]
134
134
 
135
135
    def test_remove_nl(self):
136
136
        """diff generates a valid diff for patches that change last line and
139
139
        lines = udiff_lines([b'boo\n'], [b'boo'])
140
140
        self.check_patch(lines)
141
141
        self.assertEqual(lines[5], b'\\ No newline at end of file\n')
142
 
            ## "expected no-nl, got %r" % lines[5]
 
142
        ## "expected no-nl, got %r" % lines[5]
143
143
 
144
144
    def check_patch(self, lines):
145
145
        self.assertTrue(len(lines) > 1)
146
 
            ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
147
 
        self.assertTrue(lines[0].startswith (b'---'))
148
 
            ## 'No orig line for patch:\n%s' % "".join(lines)
149
 
        self.assertTrue(lines[1].startswith (b'+++'))
150
 
            ## 'No mod line for patch:\n%s' % "".join(lines)
 
146
        ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
 
147
        self.assertTrue(lines[0].startswith(b'---'))
 
148
        ## 'No orig line for patch:\n%s' % "".join(lines)
 
149
        self.assertTrue(lines[1].startswith(b'+++'))
 
150
        ## 'No mod line for patch:\n%s' % "".join(lines)
151
151
        self.assertTrue(len(lines) > 2)
152
 
            ## "No hunks for patch:\n%s" % "".join(lines)
 
152
        ## "No hunks for patch:\n%s" % "".join(lines)
153
153
        self.assertTrue(lines[2].startswith(b'@@'))
154
 
            ## "No hunk header for patch:\n%s" % "".join(lines)
 
154
        ## "No hunk header for patch:\n%s" % "".join(lines)
155
155
        self.assertTrue(b'@@' in lines[2][2:])
156
 
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
 
156
        ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
157
157
 
158
158
    def test_binary_lines(self):
159
159
        empty = []
171
171
    def test_external_diff_no_fileno(self):
172
172
        # Make sure that we can handle not having a fileno, even
173
173
        # if the diff is large
174
 
        lines = external_udiff_lines([b'boo\n']*10000,
175
 
                                     [b'goo\n']*10000,
 
174
        lines = external_udiff_lines([b'boo\n'] * 10000,
 
175
                                     [b'goo\n'] * 10000,
176
176
                                     use_stringio=True)
177
177
        self.check_patch(lines)
178
178
 
182
182
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
183
183
        # Older versions of diffutils say "Binary files", newer
184
184
        # versions just say "Files".
185
 
        self.assertContainsRe(lines[0], b'(Binary f|F)iles old and new differ\n')
 
185
        self.assertContainsRe(
 
186
            lines[0], b'(Binary f|F)iles old and new differ\n')
186
187
        self.assertEqual(lines[1:], [b'\n'])
187
188
 
188
189
    def test_no_external_diff(self):
202
203
        lines = output.getvalue().splitlines(True)
203
204
        self.check_patch(lines)
204
205
        self.assertEqual([b'--- old_\xc2\xb5\n',
205
 
                           b'+++ new_\xc3\xa5\n',
206
 
                           b'@@ -1,1 +1,1 @@\n',
207
 
                           b'-old_text\n',
208
 
                           b'+new_text\n',
209
 
                           b'\n',
210
 
                          ]
211
 
                          , lines)
 
206
                          b'+++ new_\xc3\xa5\n',
 
207
                          b'@@ -1,1 +1,1 @@\n',
 
208
                          b'-old_text\n',
 
209
                          b'+new_text\n',
 
210
                          b'\n',
 
211
                          ], lines)
212
212
 
213
213
    def test_internal_diff_utf8(self):
214
214
        output = BytesIO()
218
218
        lines = output.getvalue().splitlines(True)
219
219
        self.check_patch(lines)
220
220
        self.assertEqual([b'--- old_\xc2\xb5\n',
221
 
                           b'+++ new_\xc3\xa5\n',
222
 
                           b'@@ -1,1 +1,1 @@\n',
223
 
                           b'-old_text\n',
224
 
                           b'+new_text\n',
225
 
                           b'\n',
226
 
                          ]
227
 
                          , lines)
 
221
                          b'+++ new_\xc3\xa5\n',
 
222
                          b'@@ -1,1 +1,1 @@\n',
 
223
                          b'-old_text\n',
 
224
                          b'+new_text\n',
 
225
                          b'\n',
 
226
                          ], lines)
228
227
 
229
228
    def test_internal_diff_iso_8859_1(self):
230
229
        output = BytesIO()
239
238
                          b'-old_text\n',
240
239
                          b'+new_text\n',
241
240
                          b'\n',
242
 
                          ]
243
 
                          , lines)
 
241
                          ], lines)
244
242
 
245
243
    def test_internal_diff_no_content(self):
246
244
        output = BytesIO()
263
261
    def test_internal_diff_default_context(self):
264
262
        output = BytesIO()
265
263
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
266
 
                           b'same_text\n', b'same_text\n', b'old_text\n'],
 
264
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
267
265
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
268
 
                           b'same_text\n', b'same_text\n', b'new_text\n'], output)
 
266
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output)
269
267
        lines = output.getvalue().splitlines(True)
270
268
        self.check_patch(lines)
271
269
        self.assertEqual([b'--- old\n',
272
 
                           b'+++ new\n',
273
 
                           b'@@ -3,4 +3,4 @@\n',
274
 
                           b' same_text\n',
275
 
                           b' same_text\n',
276
 
                           b' same_text\n',
277
 
                           b'-old_text\n',
278
 
                           b'+new_text\n',
279
 
                           b'\n',
280
 
                          ]
281
 
                          , lines)
 
270
                          b'+++ new\n',
 
271
                          b'@@ -3,4 +3,4 @@\n',
 
272
                          b' same_text\n',
 
273
                          b' same_text\n',
 
274
                          b' same_text\n',
 
275
                          b'-old_text\n',
 
276
                          b'+new_text\n',
 
277
                          b'\n',
 
278
                          ], lines)
282
279
 
283
280
    def test_internal_diff_no_context(self):
284
281
        output = BytesIO()
285
282
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
286
 
                           b'same_text\n', b'same_text\n', b'old_text\n'],
 
283
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
287
284
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
288
 
                           b'same_text\n', b'same_text\n', b'new_text\n'], output,
 
285
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
289
286
                           context_lines=0)
290
287
        lines = output.getvalue().splitlines(True)
291
288
        self.check_patch(lines)
292
289
        self.assertEqual([b'--- old\n',
293
 
                           b'+++ new\n',
294
 
                           b'@@ -6,1 +6,1 @@\n',
295
 
                           b'-old_text\n',
296
 
                           b'+new_text\n',
297
 
                           b'\n',
298
 
                          ]
299
 
                          , lines)
 
290
                          b'+++ new\n',
 
291
                          b'@@ -6,1 +6,1 @@\n',
 
292
                          b'-old_text\n',
 
293
                          b'+new_text\n',
 
294
                          b'\n',
 
295
                          ], lines)
300
296
 
301
297
    def test_internal_diff_more_context(self):
302
298
        output = BytesIO()
303
299
        diff.internal_diff('old', [b'same_text\n', b'same_text\n', b'same_text\n',
304
 
                           b'same_text\n', b'same_text\n', b'old_text\n'],
 
300
                                   b'same_text\n', b'same_text\n', b'old_text\n'],
305
301
                           'new', [b'same_text\n', b'same_text\n', b'same_text\n',
306
 
                           b'same_text\n', b'same_text\n', b'new_text\n'], output,
 
302
                                   b'same_text\n', b'same_text\n', b'new_text\n'], output,
307
303
                           context_lines=4)
308
304
        lines = output.getvalue().splitlines(True)
309
305
        self.check_patch(lines)
317
313
                          b'-old_text\n',
318
314
                          b'+new_text\n',
319
315
                          b'\n',
320
 
                          ]
321
 
                          , lines)
322
 
 
 
316
                          ], lines)
323
317
 
324
318
 
325
319
class TestDiffFiles(tests.TestCaseInTempDir):
332
326
        lines = external_udiff_lines([b'\x00foobar\n'], [b'foo\x00bar\n'])
333
327
 
334
328
        cmd = ['diff', '-u', '--binary', 'old', 'new']
335
 
        with open('old', 'wb') as f: f.write(b'\x00foobar\n')
336
 
        with open('new', 'wb') as f: f.write(b'foo\x00bar\n')
 
329
        with open('old', 'wb') as f:
 
330
            f.write(b'\x00foobar\n')
 
331
        with open('new', 'wb') as f:
 
332
            f.write(b'foo\x00bar\n')
337
333
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
338
 
                                     stdin=subprocess.PIPE)
 
334
                                stdin=subprocess.PIPE)
339
335
        out, err = pipe.communicate()
340
336
        # We should output whatever diff tells us, plus a trailing newline
341
337
        self.assertEqual(out.splitlines(True) + [b'\n'], lines)
348
344
    else:
349
345
        extra_trees = ()
350
346
    diff.show_diff_trees(tree1, tree2, output,
351
 
        specific_files=specific_files,
352
 
        extra_trees=extra_trees, old_label='old/',
353
 
        new_label='new/')
 
347
                         specific_files=specific_files,
 
348
                         extra_trees=extra_trees, old_label='old/',
 
349
                         new_label='new/')
354
350
    return output.getvalue()
355
351
 
356
352
 
367
363
        self.wt.add(['file1', 'file2'])
368
364
        self.wt.commit(
369
365
            message='Revision 1',
370
 
            timestamp=1143849600, # 2006-04-01 00:00:00 UTC
 
366
            timestamp=1143849600,  # 2006-04-01 00:00:00 UTC
371
367
            timezone=0,
372
368
            rev_id=b'rev-1')
373
369
        self.build_tree_contents([('file1', b'file1 contents at rev 2\n')])
374
370
        self.wt.commit(
375
371
            message='Revision 2',
376
 
            timestamp=1143936000, # 2006-04-02 00:00:00 UTC
 
372
            timestamp=1143936000,  # 2006-04-02 00:00:00 UTC
377
373
            timezone=28800,
378
374
            rev_id=b'rev-2')
379
375
        self.build_tree_contents([('file2', b'file2 contents at rev 3\n')])
380
376
        self.wt.commit(
381
377
            message='Revision 3',
382
 
            timestamp=1144022400, # 2006-04-03 00:00:00 UTC
 
378
            timestamp=1144022400,  # 2006-04-03 00:00:00 UTC
383
379
            timezone=-3600,
384
380
            rev_id=b'rev-3')
385
381
        self.wt.remove(['file2'])
386
382
        self.wt.commit(
387
383
            message='Revision 4',
388
 
            timestamp=1144108800, # 2006-04-04 00:00:00 UTC
 
384
            timestamp=1144108800,  # 2006-04-04 00:00:00 UTC
389
385
            timezone=0,
390
386
            rev_id=b'rev-4')
391
387
        self.build_tree_contents([
392
388
            ('file1', b'file1 contents in working tree\n')
393
389
            ])
394
390
        # set the date stamps for files in the working tree to known values
395
 
        os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
 
391
        os.utime('file1', (1144195200, 1144195200))  # 2006-04-05 00:00:00 UTC
396
392
 
397
393
    def test_diff_rev_tree_working_tree(self):
398
394
        output = get_diff_as_string(self.wt.basis_tree(), self.wt)
464
460
        old_tree = self.b.repository.revision_tree(b'rev-1')
465
461
        new_tree = self.b.repository.revision_tree(b'rev-4')
466
462
        out = get_diff_as_string(old_tree, new_tree, specific_files=['file1b'],
467
 
                            working_tree=self.wt)
 
463
                                 working_tree=self.wt)
468
464
        self.assertContainsRe(out, b'file1\t')
469
465
 
470
466
    def test_recursive_diff(self):
476
472
        old_tree = self.b.repository.revision_tree(b'rev-1')
477
473
        new_tree = self.b.repository.revision_tree(b'rev-4')
478
474
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir1'],
479
 
                            working_tree=self.wt)
 
475
                                 working_tree=self.wt)
480
476
        self.assertContainsRe(out, b'file1\t')
481
477
        out = get_diff_as_string(old_tree, new_tree, specific_files=['dir2'],
482
 
                            working_tree=self.wt)
 
478
                                 working_tree=self.wt)
483
479
        self.assertNotContainsRe(out, b'file1\t')
484
480
 
485
481
 
565
561
        self.assertContainsRe(d, b'-contents\n'
566
562
                                 b'\\+new contents\n')
567
563
 
568
 
 
569
564
    def test_internal_diff_exec_property(self):
570
565
        tree = self.make_branch_and_tree('tree')
571
566
 
636
631
        autf8, outf8 = alpha.encode('utf8'), omega.encode('utf8')
637
632
 
638
633
        tree = self.make_branch_and_tree('tree')
639
 
        self.build_tree_contents([('tree/ren_'+alpha, b'contents\n')])
640
 
        tree.add(['ren_'+alpha], [b'file-id-2'])
641
 
        self.build_tree_contents([('tree/del_'+alpha, b'contents\n')])
642
 
        tree.add(['del_'+alpha], [b'file-id-3'])
643
 
        self.build_tree_contents([('tree/mod_'+alpha, b'contents\n')])
644
 
        tree.add(['mod_'+alpha], [b'file-id-4'])
 
634
        self.build_tree_contents([('tree/ren_' + alpha, b'contents\n')])
 
635
        tree.add(['ren_' + alpha], [b'file-id-2'])
 
636
        self.build_tree_contents([('tree/del_' + alpha, b'contents\n')])
 
637
        tree.add(['del_' + alpha], [b'file-id-3'])
 
638
        self.build_tree_contents([('tree/mod_' + alpha, b'contents\n')])
 
639
        tree.add(['mod_' + alpha], [b'file-id-4'])
645
640
 
646
641
        tree.commit('one', rev_id=b'rev-1')
647
642
 
648
 
        tree.rename_one('ren_'+alpha, 'ren_'+omega)
649
 
        tree.remove('del_'+alpha)
650
 
        self.build_tree_contents([('tree/add_'+alpha, b'contents\n')])
651
 
        tree.add(['add_'+alpha], [b'file-id'])
652
 
        self.build_tree_contents([('tree/mod_'+alpha, b'contents_mod\n')])
 
643
        tree.rename_one('ren_' + alpha, 'ren_' + omega)
 
644
        tree.remove('del_' + alpha)
 
645
        self.build_tree_contents([('tree/add_' + alpha, b'contents\n')])
 
646
        tree.add(['add_' + alpha], [b'file-id'])
 
647
        self.build_tree_contents([('tree/mod_' + alpha, b'contents_mod\n')])
653
648
 
654
649
        d = get_diff_as_string(tree.basis_tree(), tree)
655
650
        self.assertContainsRe(d,
656
 
                b"=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
657
 
        self.assertContainsRe(d, b"=== added file 'add_%s'"%autf8)
658
 
        self.assertContainsRe(d, b"=== modified file 'mod_%s'"%autf8)
659
 
        self.assertContainsRe(d, b"=== removed file 'del_%s'"%autf8)
 
651
                              b"=== renamed file 'ren_%s' => 'ren_%s'\n" % (autf8, outf8))
 
652
        self.assertContainsRe(d, b"=== added file 'add_%s'" % autf8)
 
653
        self.assertContainsRe(d, b"=== modified file 'mod_%s'" % autf8)
 
654
        self.assertContainsRe(d, b"=== removed file 'del_%s'" % autf8)
660
655
 
661
656
    def test_unicode_filename_path_encoding(self):
662
657
        """Test for bug #382699: unicode filenames on Windows should be shown
679
674
 
680
675
        sio = BytesIO()
681
676
        diff.show_diff_trees(tree.basis_tree(), tree, sio,
682
 
            path_encoding='cp1251')
 
677
                             path_encoding='cp1251')
683
678
 
684
679
        output = subst_dates(sio.getvalue())
685
680
        shouldbe = (b'''\
697
692
+foo
698
693
 
699
694
''' % {b'directory': _russian_test.encode('cp1251'),
700
 
       b'test_txt': test_txt.encode('cp1251'),
701
 
      })
 
695
            b'test_txt': test_txt.encode('cp1251'),
 
696
       })
702
697
        self.assertEqualDiff(output, shouldbe)
703
698
 
704
699
 
837
832
    def test_register_diff(self):
838
833
        self.create_old_new()
839
834
        old_diff_factories = diff.DiffTree.diff_factories
840
 
        diff.DiffTree.diff_factories=old_diff_factories[:]
 
835
        diff.DiffTree.diff_factories = old_diff_factories[:]
841
836
        diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
842
837
        try:
843
838
            differ = diff.DiffTree(self.old_tree, self.new_tree, BytesIO())
870
865
        self.old_tree.add('b-file')
871
866
        self.differ.show_diff(None)
872
867
        self.assertContainsRe(self.differ.to_file.getvalue(),
873
 
            b'.*a-file(.|\n)*b-file')
 
868
                              b'.*a-file(.|\n)*b-file')
874
869
 
875
870
 
876
871
class TestPatienceDiffLib(tests.TestCase):
897
892
        self.assertEqual(unique_lcs('a', 'a'), [(0, 0)])
898
893
        self.assertEqual(unique_lcs('a', 'b'), [])
899
894
        self.assertEqual(unique_lcs('ab', 'ab'), [(0, 0), (1, 1)])
900
 
        self.assertEqual(unique_lcs('abcde', 'cdeab'), [(2, 0), (3, 1), (4, 2)])
901
 
        self.assertEqual(unique_lcs('cdeab', 'abcde'), [(0, 2), (1, 3), (2, 4)])
 
895
        self.assertEqual(unique_lcs('abcde', 'cdeab'),
 
896
                         [(2, 0), (3, 1), (4, 2)])
 
897
        self.assertEqual(unique_lcs('cdeab', 'abcde'),
 
898
                         [(0, 2), (1, 3), (2, 4)])
902
899
        self.assertEqual(unique_lcs('abXde', 'abYde'), [(0, 0), (1, 1),
903
 
                                                         (3, 3), (4, 4)])
 
900
                                                        (3, 3), (4, 4)])
904
901
        self.assertEqual(unique_lcs('acbac', 'abc'), [(2, 1)])
905
902
 
906
903
    def test_recurse_matches(self):
967
964
 
968
965
        # make sure it supports passing in lists
969
966
        self.assertDiffBlocks(
970
 
                   ['hello there\n',
971
 
                    'world\n',
972
 
                    'how are you today?\n'],
973
 
                   ['hello there\n',
974
 
                    'how are you today?\n'],
975
 
                [(0, 0, 1), (2, 1, 1)])
 
967
            ['hello there\n',
 
968
             'world\n',
 
969
             'how are you today?\n'],
 
970
            ['hello there\n',
 
971
             'how are you today?\n'],
 
972
            [(0, 0, 1), (2, 1, 1)])
976
973
 
977
974
        # non unique lines surrounded by non-matching lines
978
975
        # won't be found
979
976
        self.assertDiffBlocks('aBccDe', 'abccde', [(0, 0, 1), (5, 5, 1)])
980
977
 
981
978
        # But they only need to be locally unique
982
 
        self.assertDiffBlocks('aBcDec', 'abcdec', [(0, 0, 1), (2, 2, 1), (4, 4, 2)])
 
979
        self.assertDiffBlocks('aBcDec', 'abcdec', [
 
980
                              (0, 0, 1), (2, 2, 1), (4, 4, 2)])
983
981
 
984
982
        # non unique blocks won't be matched
985
983
        self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0, 0, 1), (8, 8, 1)])
986
984
 
987
985
        # but locally unique ones will
988
986
        self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0, 0, 1), (2, 2, 2),
989
 
                                              (5, 4, 1), (7, 5, 2), (10, 8, 1)])
 
987
                                                           (5, 4, 1), (7, 5, 2), (10, 8, 1)])
990
988
 
991
989
        self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7, 7, 1)])
992
990
        self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
1025
1023
        chk_ops([], [], [])
1026
1024
        chk_ops('abc', '', [('delete', 0, 3, 0, 0)])
1027
1025
        chk_ops('', 'abc', [('insert', 0, 0, 0, 3)])
1028
 
        chk_ops('abcd', 'abcd', [('equal',    0, 4, 0, 4)])
1029
 
        chk_ops('abcd', 'abce', [('equal',   0, 3, 0, 3),
 
1026
        chk_ops('abcd', 'abcd', [('equal', 0, 4, 0, 4)])
 
1027
        chk_ops('abcd', 'abce', [('equal', 0, 3, 0, 3),
1030
1028
                                 ('replace', 3, 4, 3, 4)
1031
 
                                ])
 
1029
                                 ])
1032
1030
        chk_ops('eabc', 'abce', [('delete', 0, 1, 0, 0),
1033
 
                                 ('equal',  1, 4, 0, 3),
 
1031
                                 ('equal', 1, 4, 0, 3),
1034
1032
                                 ('insert', 4, 4, 3, 4)
1035
 
                                ])
 
1033
                                 ])
1036
1034
        chk_ops('eabce', 'abce', [('delete', 0, 1, 0, 0),
1037
 
                                  ('equal',  1, 5, 0, 4)
1038
 
                                 ])
1039
 
        chk_ops('abcde', 'abXde', [('equal',   0, 2, 0, 2),
 
1035
                                  ('equal', 1, 5, 0, 4)
 
1036
                                  ])
 
1037
        chk_ops('abcde', 'abXde', [('equal', 0, 2, 0, 2),
1040
1038
                                   ('replace', 2, 3, 2, 3),
1041
 
                                   ('equal',   3, 5, 3, 5)
1042
 
                                  ])
1043
 
        chk_ops('abcde', 'abXYZde', [('equal',   0, 2, 0, 2),
 
1039
                                   ('equal', 3, 5, 3, 5)
 
1040
                                   ])
 
1041
        chk_ops('abcde', 'abXYZde', [('equal', 0, 2, 0, 2),
1044
1042
                                     ('replace', 2, 3, 2, 5),
1045
 
                                     ('equal',   3, 5, 5, 7)
 
1043
                                     ('equal', 3, 5, 5, 7)
 
1044
                                     ])
 
1045
        chk_ops('abde', 'abXYZde', [('equal', 0, 2, 0, 2),
 
1046
                                    ('insert', 2, 2, 2, 5),
 
1047
                                    ('equal', 2, 4, 5, 7)
1046
1048
                                    ])
1047
 
        chk_ops('abde', 'abXYZde', [('equal',  0, 2, 0, 2),
1048
 
                                    ('insert', 2, 2, 2, 5),
1049
 
                                    ('equal',  2, 4, 5, 7)
1050
 
                                   ])
1051
1049
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1052
 
                [('equal',  0, 6,  0, 6),
1053
 
                 ('insert', 6, 6,  6, 11),
1054
 
                 ('equal',  6, 16, 11, 21)
1055
 
                ])
 
1050
                [('equal', 0, 6, 0, 6),
 
1051
                 ('insert', 6, 6, 6, 11),
 
1052
                 ('equal', 6, 16, 11, 21)
 
1053
                 ])
1056
1054
        chk_ops(
1057
 
                [ 'hello there\n'
1058
 
                , 'world\n'
1059
 
                , 'how are you today?\n'],
1060
 
                [ 'hello there\n'
1061
 
                , 'how are you today?\n'],
1062
 
                [('equal',  0, 1, 0, 1),
1063
 
                 ('delete', 1, 2, 1, 1),
1064
 
                 ('equal',  2, 3, 1, 2),
1065
 
                ])
 
1055
            ['hello there\n', 'world\n', 'how are you today?\n'],
 
1056
            ['hello there\n', 'how are you today?\n'],
 
1057
            [('equal', 0, 1, 0, 1),
 
1058
             ('delete', 1, 2, 1, 1),
 
1059
             ('equal', 2, 3, 1, 2),
 
1060
             ])
1066
1061
        chk_ops('aBccDe', 'abccde',
1067
 
                [('equal',   0, 1, 0, 1),
 
1062
                [('equal', 0, 1, 0, 1),
1068
1063
                 ('replace', 1, 5, 1, 5),
1069
 
                 ('equal',   5, 6, 5, 6),
1070
 
                ])
 
1064
                 ('equal', 5, 6, 5, 6),
 
1065
                 ])
1071
1066
        chk_ops('aBcDec', 'abcdec',
1072
 
                [('equal',   0, 1, 0, 1),
 
1067
                [('equal', 0, 1, 0, 1),
1073
1068
                 ('replace', 1, 2, 1, 2),
1074
 
                 ('equal',   2, 3, 2, 3),
 
1069
                 ('equal', 2, 3, 2, 3),
1075
1070
                 ('replace', 3, 4, 3, 4),
1076
 
                 ('equal',   4, 6, 4, 6),
1077
 
                ])
 
1071
                 ('equal', 4, 6, 4, 6),
 
1072
                 ])
1078
1073
        chk_ops('aBcdEcdFg', 'abcdecdfg',
1079
 
                [('equal',   0, 1, 0, 1),
 
1074
                [('equal', 0, 1, 0, 1),
1080
1075
                 ('replace', 1, 8, 1, 8),
1081
 
                 ('equal',   8, 9, 8, 9)
1082
 
                ])
 
1076
                 ('equal', 8, 9, 8, 9)
 
1077
                 ])
1083
1078
        chk_ops('aBcdEeXcdFg', 'abcdecdfg',
1084
 
                [('equal',   0, 1, 0, 1),
 
1079
                [('equal', 0, 1, 0, 1),
1085
1080
                 ('replace', 1, 2, 1, 2),
1086
 
                 ('equal',   2, 4, 2, 4),
 
1081
                 ('equal', 2, 4, 2, 4),
1087
1082
                 ('delete', 4, 5, 4, 4),
1088
 
                 ('equal',   5, 6, 4, 5),
 
1083
                 ('equal', 5, 6, 4, 5),
1089
1084
                 ('delete', 6, 7, 5, 5),
1090
 
                 ('equal',   7, 9, 5, 7),
 
1085
                 ('equal', 7, 9, 5, 7),
1091
1086
                 ('replace', 9, 10, 7, 8),
1092
 
                 ('equal',   10, 11, 8, 9)
1093
 
                ])
 
1087
                 ('equal', 10, 11, 8, 9)
 
1088
                 ])
1094
1089
 
1095
1090
    def test_grouped_opcodes(self):
1096
1091
        def chk_ops(a, b, expected_codes, n=3):
1102
1097
        chk_ops('abc', '', [[('delete', 0, 3, 0, 0)]])
1103
1098
        chk_ops('', 'abc', [[('insert', 0, 0, 0, 3)]])
1104
1099
        chk_ops('abcd', 'abcd', [])
1105
 
        chk_ops('abcd', 'abce', [[('equal',   0, 3, 0, 3),
 
1100
        chk_ops('abcd', 'abce', [[('equal', 0, 3, 0, 3),
1106
1101
                                  ('replace', 3, 4, 3, 4)
1107
 
                                 ]])
 
1102
                                  ]])
1108
1103
        chk_ops('eabc', 'abce', [[('delete', 0, 1, 0, 0),
1109
 
                                 ('equal',  1, 4, 0, 3),
1110
 
                                 ('insert', 4, 4, 3, 4)
1111
 
                                ]])
 
1104
                                  ('equal', 1, 4, 0, 3),
 
1105
                                  ('insert', 4, 4, 3, 4)
 
1106
                                  ]])
1112
1107
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1113
 
                [[('equal',  3, 6, 3, 6),
 
1108
                [[('equal', 3, 6, 3, 6),
1114
1109
                  ('insert', 6, 6, 6, 11),
1115
 
                  ('equal',  6, 9, 11, 14)
 
1110
                  ('equal', 6, 9, 11, 14)
1116
1111
                  ]])
1117
1112
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1118
 
                [[('equal',  2, 6, 2, 6),
 
1113
                [[('equal', 2, 6, 2, 6),
1119
1114
                  ('insert', 6, 6, 6, 11),
1120
 
                  ('equal',  6, 10, 11, 15)
 
1115
                  ('equal', 6, 10, 11, 15)
1121
1116
                  ]], 4)
1122
1117
        chk_ops('Xabcdef', 'abcdef',
1123
1118
                [[('delete', 0, 1, 0, 0),
1124
 
                  ('equal',  1, 4, 0, 3)
 
1119
                  ('equal', 1, 4, 0, 3)
1125
1120
                  ]])
1126
1121
        chk_ops('abcdef', 'abcdefX',
1127
 
                [[('equal',  3, 6, 3, 6),
 
1122
                [[('equal', 3, 6, 3, 6),
1128
1123
                  ('insert', 6, 6, 6, 7)
1129
1124
                  ]])
1130
1125
 
1131
 
 
1132
1126
    def test_multiple_ranges(self):
1133
1127
        # There was an earlier bug where we used a bad set of ranges,
1134
1128
        # this triggers that specific bug, to make sure it doesn't regress
1184
1178
 
1185
1179
 
1186
1180
pynff pzq_zxqve(Pbzznaq):
1187
 
'''.splitlines(True)
1188
 
, [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
 
1181
'''.splitlines(True), [(0, 0, 1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
1189
1182
 
1190
1183
    def test_patience_unified_diff(self):
1191
1184
        txt_a = ['hello there\n',
1196
1189
        unified_diff = patiencediff.unified_diff
1197
1190
        psm = self._PatienceSequenceMatcher
1198
1191
        self.assertEqual(['--- \n',
1199
 
                           '+++ \n',
1200
 
                           '@@ -1,3 +1,2 @@\n',
1201
 
                           ' hello there\n',
1202
 
                           '-world\n',
1203
 
                           ' how are you today?\n'
1204
 
                          ]
1205
 
                          , list(unified_diff(txt_a, txt_b,
1206
 
                                 sequencematcher=psm)))
1207
 
        txt_a = [x+'\n' for x in 'abcdefghijklmnop']
1208
 
        txt_b = [x+'\n' for x in 'abcdefxydefghijklmnop']
 
1192
                          '+++ \n',
 
1193
                          '@@ -1,3 +1,2 @@\n',
 
1194
                          ' hello there\n',
 
1195
                          '-world\n',
 
1196
                          ' how are you today?\n'
 
1197
                          ], list(unified_diff(txt_a, txt_b,
 
1198
                                               sequencematcher=psm)))
 
1199
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
 
1200
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
1209
1201
        # This is the result with LongestCommonSubstring matching
1210
1202
        self.assertEqual(['--- \n',
1211
 
                           '+++ \n',
1212
 
                           '@@ -1,6 +1,11 @@\n',
1213
 
                           ' a\n',
1214
 
                           ' b\n',
1215
 
                           ' c\n',
1216
 
                           '+d\n',
1217
 
                           '+e\n',
1218
 
                           '+f\n',
1219
 
                           '+x\n',
1220
 
                           '+y\n',
1221
 
                           ' d\n',
1222
 
                           ' e\n',
1223
 
                           ' f\n']
1224
 
                          , list(unified_diff(txt_a, txt_b)))
 
1203
                          '+++ \n',
 
1204
                          '@@ -1,6 +1,11 @@\n',
 
1205
                          ' a\n',
 
1206
                          ' b\n',
 
1207
                          ' c\n',
 
1208
                          '+d\n',
 
1209
                          '+e\n',
 
1210
                          '+f\n',
 
1211
                          '+x\n',
 
1212
                          '+y\n',
 
1213
                          ' d\n',
 
1214
                          ' e\n',
 
1215
                          ' f\n'], list(unified_diff(txt_a, txt_b)))
1225
1216
        # And the patience diff
1226
1217
        self.assertEqual(['--- \n',
1227
 
                           '+++ \n',
1228
 
                           '@@ -4,6 +4,11 @@\n',
1229
 
                           ' d\n',
1230
 
                           ' e\n',
1231
 
                           ' f\n',
1232
 
                           '+x\n',
1233
 
                           '+y\n',
1234
 
                           '+d\n',
1235
 
                           '+e\n',
1236
 
                           '+f\n',
1237
 
                           ' g\n',
1238
 
                           ' h\n',
1239
 
                           ' i\n',
1240
 
                          ]
1241
 
                          , list(unified_diff(txt_a, txt_b,
1242
 
                                 sequencematcher=psm)))
 
1218
                          '+++ \n',
 
1219
                          '@@ -4,6 +4,11 @@\n',
 
1220
                          ' d\n',
 
1221
                          ' e\n',
 
1222
                          ' f\n',
 
1223
                          '+x\n',
 
1224
                          '+y\n',
 
1225
                          '+d\n',
 
1226
                          '+e\n',
 
1227
                          '+f\n',
 
1228
                          ' g\n',
 
1229
                          ' h\n',
 
1230
                          ' i\n',
 
1231
                          ], list(unified_diff(txt_a, txt_b,
 
1232
                                               sequencematcher=psm)))
1243
1233
 
1244
1234
    def test_patience_unified_diff_with_dates(self):
1245
1235
        txt_a = ['hello there\n',
1250
1240
        unified_diff = patiencediff.unified_diff
1251
1241
        psm = self._PatienceSequenceMatcher
1252
1242
        self.assertEqual(['--- a\t2008-08-08\n',
1253
 
                           '+++ b\t2008-09-09\n',
1254
 
                           '@@ -1,3 +1,2 @@\n',
1255
 
                           ' hello there\n',
1256
 
                           '-world\n',
1257
 
                           ' how are you today?\n'
1258
 
                          ]
1259
 
                          , list(unified_diff(txt_a, txt_b,
1260
 
                                 fromfile='a', tofile='b',
1261
 
                                 fromfiledate='2008-08-08',
1262
 
                                 tofiledate='2008-09-09',
1263
 
                                 sequencematcher=psm)))
 
1243
                          '+++ b\t2008-09-09\n',
 
1244
                          '@@ -1,3 +1,2 @@\n',
 
1245
                          ' hello there\n',
 
1246
                          '-world\n',
 
1247
                          ' how are you today?\n'
 
1248
                          ], list(unified_diff(txt_a, txt_b,
 
1249
                                               fromfile='a', tofile='b',
 
1250
                                               fromfiledate='2008-08-08',
 
1251
                                               tofiledate='2008-09-09',
 
1252
                                               sequencematcher=psm)))
1264
1253
 
1265
1254
 
1266
1255
class TestPatienceDiffLib_c(TestPatienceDiffLib):
1280
1269
        # We need to be able to hash items in the sequence, lists are
1281
1270
        # unhashable, and thus cannot be diffed
1282
1271
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1283
 
                                         None, [[]], [])
1284
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1285
 
                                         None, ['valid', []], [])
1286
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1287
 
                                         None, ['valid'], [[]])
1288
 
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
1289
 
                                         None, ['valid'], ['valid', []])
 
1272
                              None, [[]], [])
 
1273
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1274
                              None, ['valid', []], [])
 
1275
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1276
                              None, ['valid'], [[]])
 
1277
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1278
                              None, ['valid'], ['valid', []])
1290
1279
 
1291
1280
 
1292
1281
class TestPatienceDiffLibFiles(tests.TestCaseInTempDir):
1302
1291
                 b'how are you today?\n']
1303
1292
        txt_b = [b'hello there\n',
1304
1293
                 b'how are you today?\n']
1305
 
        with open('a1', 'wb') as f: f.writelines(txt_a)
1306
 
        with open('b1', 'wb') as f: f.writelines(txt_b)
 
1294
        with open('a1', 'wb') as f:
 
1295
            f.writelines(txt_a)
 
1296
        with open('b1', 'wb') as f:
 
1297
            f.writelines(txt_b)
1307
1298
 
1308
1299
        unified_diff_files = patiencediff.unified_diff_files
1309
1300
        psm = self._PatienceSequenceMatcher
1313
1304
                          b' hello there\n',
1314
1305
                          b'-world\n',
1315
1306
                          b' how are you today?\n',
1316
 
                          ]
1317
 
                          , list(unified_diff_files(b'a1', b'b1',
1318
 
                                 sequencematcher=psm)))
 
1307
                          ], list(unified_diff_files(b'a1', b'b1',
 
1308
                                                     sequencematcher=psm)))
1319
1309
 
1320
 
        txt_a = [x+'\n' for x in 'abcdefghijklmnop']
1321
 
        txt_b = [x+'\n' for x in 'abcdefxydefghijklmnop']
1322
 
        with open('a2', 'wt') as f: f.writelines(txt_a)
1323
 
        with open('b2', 'wt') as f: f.writelines(txt_b)
 
1310
        txt_a = [x + '\n' for x in 'abcdefghijklmnop']
 
1311
        txt_b = [x + '\n' for x in 'abcdefxydefghijklmnop']
 
1312
        with open('a2', 'wt') as f:
 
1313
            f.writelines(txt_a)
 
1314
        with open('b2', 'wt') as f:
 
1315
            f.writelines(txt_b)
1324
1316
 
1325
1317
        # This is the result with LongestCommonSubstring matching
1326
1318
        self.assertEqual([b'--- a2\n',
1336
1328
                          b'+y\n',
1337
1329
                          b' d\n',
1338
1330
                          b' e\n',
1339
 
                          b' f\n']
1340
 
                          , list(unified_diff_files(b'a2', b'b2')))
 
1331
                          b' f\n'], list(unified_diff_files(b'a2', b'b2')))
1341
1332
 
1342
1333
        # And the patience diff
1343
1334
        self.assertEqual([b'--- a2\n',
1408
1399
        diff_obj = diff.DiffFromTool.from_string('diff', None, None, None)
1409
1400
        self.addCleanup(diff_obj.finish)
1410
1401
        self.assertEqual(['diff', '@old_path', '@new_path'],
1411
 
            diff_obj.command_template)
 
1402
                         diff_obj.command_template)
1412
1403
 
1413
1404
    def test_from_string_u5(self):
1414
1405
        diff_obj = diff.DiffFromTool.from_string('diff "-u 5"',
1501
1492
        self.addCleanup(diff_obj.finish)
1502
1493
        self.assertContainsRe(diff_obj._root, 'brz-diff-[^/]*')
1503
1494
        old_path, new_path = diff_obj._prepare_files(
1504
 
                'oldname', 'newname', file_id=b'file-id')
 
1495
            'oldname', 'newname', file_id=b'file-id')
1505
1496
        self.assertContainsRe(old_path, 'old/oldname$')
1506
1497
        self.assertEqual(315532800, os.stat(old_path).st_mtime)
1507
1498
        self.assertContainsRe(new_path, 'tree/newname$')