183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport difflib
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test.test_support import run_unittest, findfile
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport doctest
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport sys
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestWithAscii(unittest.TestCase):
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_one_insert(self):
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sm = difflib.SequenceMatcher(None, 'b' * 100, 'a' + 'b' * 100)
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertAlmostEqual(sm.ratio(), 0.995, places=3)
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(sm.get_opcodes()),
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            [   ('insert', 0, 0, 0, 1),
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('equal', 0, 100, 1, 101)])
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sm = difflib.SequenceMatcher(None, 'b' * 100, 'b' * 50 + 'a' + 'b' * 50)
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertAlmostEqual(sm.ratio(), 0.995, places=3)
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(sm.get_opcodes()),
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            [   ('equal', 0, 50, 0, 50),
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('insert', 50, 50, 50, 51),
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('equal', 50, 100, 51, 101)])
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_one_delete(self):
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sm = difflib.SequenceMatcher(None, 'a' * 40 + 'c' + 'b' * 40, 'a' * 40 + 'b' * 40)
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertAlmostEqual(sm.ratio(), 0.994, places=3)
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(sm.get_opcodes()),
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            [   ('equal', 0, 40, 0, 40),
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('delete', 40, 41, 40, 40),
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('equal', 41, 81, 40, 80)])
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestAutojunk(unittest.TestCase):
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    """Tests for the autojunk parameter added in 2.7"""
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_one_insert_homogenous_sequence(self):
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # By default autojunk=True and the heuristic kicks in for a sequence
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # of length 200+
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        seq1 = 'b' * 200
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        seq2 = 'a' + 'b' * 200
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sm = difflib.SequenceMatcher(None, seq1, seq2)
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertAlmostEqual(sm.ratio(), 0, places=3)
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Now turn the heuristic off
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        sm = difflib.SequenceMatcher(None, seq1, seq2, autojunk=False)
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertAlmostEqual(sm.ratio(), 0.9975, places=3)
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestSFbugs(unittest.TestCase):
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_ratio_for_null_seqn(self):
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check clearing of SF bug 763023
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        s = difflib.SequenceMatcher(None, [], [])
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(s.ratio(), 1)
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(s.quick_ratio(), 1)
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(s.real_quick_ratio(), 1)
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_comparing_empty_lists(self):
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check fix for bug #979794
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        group_gen = difflib.SequenceMatcher(None, [], []).get_grouped_opcodes()
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(StopIteration, group_gen.next)
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        diff_gen = difflib.unified_diff([], [])
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(StopIteration, diff_gen.next)
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_added_tab_hint(self):
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check fix for bug #1488943
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"]))
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual("- \tI am a buggy", diff[0])
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual("?            --\n", diff[1])
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual("+ \t\tI am a bug", diff[2])
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual("? +\n", diff[3])
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_from1 = """
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   1. Beautiful is beTTer than ugly.
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   2. Explicit is better than implicit.
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   3. Simple is better than complex.
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   4. Complex is better than complicated.
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_to1 = """
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   1. Beautiful is better than ugly.
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   3.   Simple is better than complex.
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   4. Complicated is better than complex.
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh   5. Flat is better than nested.
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_from2 = """
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh\t\tLine 1: preceeded by from:[tt] to:[ssss]
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh  \t\tLine 2: preceeded by from:[sstt] to:[sssst]
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh  \t \tLine 3: preceeded by from:[sstst] to:[ssssss]
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehLine 4:  \thas from:[sst] to:[sss] after :
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehLine 5: has from:[t] to:[ss] at end\t
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_to2 = """
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    Line 1: preceeded by from:[tt] to:[ssss]
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    \tLine 2: preceeded by from:[sstt] to:[sssst]
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh      Line 3: preceeded by from:[sstst] to:[ssssss]
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehLine 4:   has from:[sst] to:[sss] after :
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehLine 5: has from:[t] to:[ss] at end
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh"""
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_from3 = """line 0
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh1234567890123456789012345689012345
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 1
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 2
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 3
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 4   changed
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 5   changed
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 6   changed
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 7
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 8  subtracted
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 9
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh1234567890123456789012345689012345
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehshort line
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehjust fits in!!
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehjust fits in two lines yup!!
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehthe end"""
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehpatch914575_to3 = """line 0
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh1234567890123456789012345689012345
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 1
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 2    added
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 3
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 4   chanGEd
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 5a  chanGed
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 6a  changEd
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 7
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 8
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehline 9
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh1234567890
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehanother long line that needs to be wrapped
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehjust fitS in!!
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehjust fits in two lineS yup!!
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehthe end"""
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestSFpatches(unittest.TestCase):
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_html_diff(self):
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check SF patch 914575 for generating HTML differences
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f1a = ((patch914575_from1 + '123\n'*10)*3)
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t1a = (patch914575_to1 + '123\n'*10)*3
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f1b = '456\n'*10 + f1a
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t1b = '456\n'*10 + t1a
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f1a = f1a.splitlines()
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t1a = t1a.splitlines()
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f1b = f1b.splitlines()
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t1b = t1b.splitlines()
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f2 = patch914575_from2.splitlines()
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t2 = patch914575_to2.splitlines()
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        f3 = patch914575_from3
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t3 = patch914575_to3
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        i = difflib.HtmlDiff()
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        j = difflib.HtmlDiff(tabsize=2)
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        k = difflib.HtmlDiff(wrapcolumn=14)
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        full = i.make_file(f1a,t1a,'from','to',context=False,numlines=5)
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        tables = '\n'.join(
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            [
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Context (first diff within numlines=5(default))</h2>',
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1a,t1a,'from','to',context=True),
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Context (first diff after numlines=5(default))</h2>',
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1b,t1b,'from','to',context=True),
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Context (numlines=6)</h2>',
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1a,t1a,'from','to',context=True,numlines=6),
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Context (numlines=0)</h2>',
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1a,t1a,'from','to',context=True,numlines=0),
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Same Context</h2>',
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1a,f1a,'from','to',context=True),
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Same Full</h2>',
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f1a,f1a,'from','to',context=False),
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Empty Context</h2>',
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table([],[],'from','to',context=True),
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Empty Full</h2>',
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table([],[],'from','to',context=False),
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>tabsize=2</h2>',
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             j.make_table(f2,t2),
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>tabsize=default</h2>',
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             i.make_table(f2,t2),
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>Context (wrapcolumn=14,numlines=0)</h2>',
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             k.make_table(f3.splitlines(),t3.splitlines(),context=True,numlines=0),
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>wrapcolumn=14,splitlines()</h2>',
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             k.make_table(f3.splitlines(),t3.splitlines()),
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '<h2>wrapcolumn=14,splitlines(True)</h2>',
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             k.make_table(f3.splitlines(True),t3.splitlines(True)),
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ])
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        actual = full.replace('</body>','\n%s\n</body>' % tables)
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # temporarily uncomment next two lines to baseline this test
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #with open('test_difflib_expect.html','w') as fp:
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #    fp.write(actual)
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        with open(findfile('test_difflib_expect.html')) as fp:
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(actual, fp.read())
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_recursion_limit(self):
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Check if the problem described in patch #1413711 exists.
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        limit = sys.getrecursionlimit()
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        old = [(i%2 and "K:%d" or "V:A:%d") % i for i in range(limit*2)]
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        new = [(i%2 and "K:%d" or "V:B:%d") % i for i in range(limit*2)]
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        difflib.SequenceMatcher(None, old, new).get_opcodes()
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass TestOutputFormat(unittest.TestCase):
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_tab_delimiter(self):
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args = ['one', 'two', 'Original', 'Current',
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            '2005-01-26 23:30:50', '2010-04-02 10:20:52']
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        ud = difflib.unified_diff(*args, lineterm='')
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(ud)[0:2], [
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           "--- Original\t2005-01-26 23:30:50",
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           "+++ Current\t2010-04-02 10:20:52"])
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        cd = difflib.context_diff(*args, lineterm='')
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(cd)[0:2], [
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           "*** Original\t2005-01-26 23:30:50",
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                           "--- Current\t2010-04-02 10:20:52"])
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_no_trailing_tab_on_empty_filedate(self):
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        args = ['one', 'two', 'Original', 'Current']
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        ud = difflib.unified_diff(*args, lineterm='')
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(ud)[0:2], ["--- Original", "+++ Current"])
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        cd = difflib.context_diff(*args, lineterm='')
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(list(cd)[0:2], ["*** Original", "--- Current"])
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_range_format_unified(self):
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Per the diff spec at http://www.unix.org/single_unix_specification/
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        spec = '''\
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           Each <range> field shall be of the form:
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             %1d", <beginning line number>  if the range contains exactly one line,
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           and:
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            "%1d,%1d", <beginning line number>, <number of lines> otherwise.
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           If a range is empty, its beginning line number shall be the number of
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           the line just before the range, or 0 if the empty range starts the file.
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        '''
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        fmt = difflib._format_range_unified
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,3), '3,0')
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,4), '4')
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,5), '4,2')
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,6), '4,3')
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(0,0), '0,0')
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_range_format_context(self):
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Per the diff spec at http://www.unix.org/single_unix_specification/
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        spec = '''\
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           The range of lines in file1 shall be written in the following format
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           if the range contains two or more lines:
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "*** %d,%d ****\n", <beginning line number>, <ending line number>
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           and the following format otherwise:
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "*** %d ****\n", <ending line number>
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           The ending line number of an empty range shall be the number of the preceding line,
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           or 0 if the range is at the start of the file.
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           Next, the range of lines in file2 shall be written in the following format
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           if the range contains two or more lines:
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "--- %d,%d ----\n", <beginning line number>, <ending line number>
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh           and the following format otherwise:
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh               "--- %d ----\n", <ending line number>
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        '''
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        fmt = difflib._format_range_context
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,3), '3')
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,4), '4')
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,5), '4,5')
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(3,6), '4,6')
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(fmt(0,0), '0')
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    difflib.HtmlDiff._default_prefix = 0
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    Doctests = doctest.DocTestSuite(difflib)
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    run_unittest(
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs,
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        TestOutputFormat, Doctests)
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == '__main__':
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
273