10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport difflib 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import run_unittest, findfile 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport unittest 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport doctest 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestWithAscii(unittest.TestCase): 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_one_insert(self): 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sm = difflib.SequenceMatcher(None, 'b' * 100, 'a' + 'b' * 100) 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertAlmostEqual(sm.ratio(), 0.995, places=3) 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(sm.get_opcodes()), 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [ ('insert', 0, 0, 0, 1), 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('equal', 0, 100, 1, 101)]) 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sm = difflib.SequenceMatcher(None, 'b' * 100, 'b' * 50 + 'a' + 'b' * 50) 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertAlmostEqual(sm.ratio(), 0.995, places=3) 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(sm.get_opcodes()), 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [ ('equal', 0, 50, 0, 50), 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('insert', 50, 50, 50, 51), 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('equal', 50, 100, 51, 101)]) 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_one_delete(self): 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sm = difflib.SequenceMatcher(None, 'a' * 40 + 'c' + 'b' * 40, 'a' * 40 + 'b' * 40) 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertAlmostEqual(sm.ratio(), 0.994, places=3) 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(sm.get_opcodes()), 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [ ('equal', 0, 40, 0, 40), 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('delete', 40, 41, 40, 40), 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('equal', 41, 81, 40, 80)]) 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestAutojunk(unittest.TestCase): 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Tests for the autojunk parameter added in 2.7""" 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_one_insert_homogenous_sequence(self): 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # By default autojunk=True and the heuristic kicks in for a sequence 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # of length 200+ 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi seq1 = 'b' * 200 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi seq2 = 'a' + 'b' * 200 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sm = difflib.SequenceMatcher(None, seq1, seq2) 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertAlmostEqual(sm.ratio(), 0, places=3) 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Now turn the heuristic off 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sm = difflib.SequenceMatcher(None, seq1, seq2, autojunk=False) 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertAlmostEqual(sm.ratio(), 0.9975, places=3) 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestSFbugs(unittest.TestCase): 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_ratio_for_null_seqn(self): 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check clearing of SF bug 763023 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = difflib.SequenceMatcher(None, [], []) 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.ratio(), 1) 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.quick_ratio(), 1) 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.real_quick_ratio(), 1) 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_comparing_empty_lists(self): 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check fix for bug #979794 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi group_gen = difflib.SequenceMatcher(None, [], []).get_grouped_opcodes() 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(StopIteration, group_gen.next) 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi diff_gen = difflib.unified_diff([], []) 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(StopIteration, diff_gen.next) 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_added_tab_hint(self): 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check fix for bug #1488943 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi diff = list(difflib.Differ().compare(["\tI am a buggy"],["\t\tI am a bug"])) 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual("- \tI am a buggy", diff[0]) 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual("? --\n", diff[1]) 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual("+ \t\tI am a bug", diff[2]) 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual("? +\n", diff[3]) 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_from1 = """ 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1. Beautiful is beTTer than ugly. 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2. Explicit is better than implicit. 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3. Simple is better than complex. 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4. Complex is better than complicated. 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_to1 = """ 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1. Beautiful is better than ugly. 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3. Simple is better than complex. 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4. Complicated is better than complex. 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5. Flat is better than nested. 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_from2 = """ 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\t\tLine 1: preceeded by from:[tt] to:[ssss] 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi \t\tLine 2: preceeded by from:[sstt] to:[sssst] 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi \t \tLine 3: preceeded by from:[sstst] to:[ssssss] 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiLine 4: \thas from:[sst] to:[sss] after : 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiLine 5: has from:[t] to:[ss] at end\t 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_to2 = """ 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Line 1: preceeded by from:[tt] to:[ssss] 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi \tLine 2: preceeded by from:[sstt] to:[sssst] 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Line 3: preceeded by from:[sstst] to:[ssssss] 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiLine 4: has from:[sst] to:[sss] after : 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiLine 5: has from:[t] to:[ss] at end 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_from3 = """line 0 1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1234567890123456789012345689012345 1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 1 1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 2 1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 3 1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 4 changed 1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 5 changed 1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 6 changed 1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 7 1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 8 subtracted 1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 9 1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1234567890123456789012345689012345 1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yishort line 1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yijust fits in!! 1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yijust fits in two lines yup!! 1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe end""" 1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yipatch914575_to3 = """line 0 1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1234567890123456789012345689012345 1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 1 1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 2 added 1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 3 1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 4 chanGEd 1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 5a chanGed 1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 6a changEd 1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 7 1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 8 1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiline 9 1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi1234567890 1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yianother long line that needs to be wrapped 1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yijust fitS in!! 1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yijust fits in two lineS yup!! 1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yithe end""" 1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestSFpatches(unittest.TestCase): 1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_html_diff(self): 1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check SF patch 914575 for generating HTML differences 1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f1a = ((patch914575_from1 + '123\n'*10)*3) 1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t1a = (patch914575_to1 + '123\n'*10)*3 1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f1b = '456\n'*10 + f1a 1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t1b = '456\n'*10 + t1a 1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f1a = f1a.splitlines() 1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t1a = t1a.splitlines() 1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f1b = f1b.splitlines() 1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t1b = t1b.splitlines() 1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f2 = patch914575_from2.splitlines() 1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t2 = patch914575_to2.splitlines() 1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi f3 = patch914575_from3 1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t3 = patch914575_to3 1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i = difflib.HtmlDiff() 1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi j = difflib.HtmlDiff(tabsize=2) 1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k = difflib.HtmlDiff(wrapcolumn=14) 1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi full = i.make_file(f1a,t1a,'from','to',context=False,numlines=5) 1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tables = '\n'.join( 1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [ 1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Context (first diff within numlines=5(default))</h2>', 1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1a,t1a,'from','to',context=True), 1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Context (first diff after numlines=5(default))</h2>', 1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1b,t1b,'from','to',context=True), 1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Context (numlines=6)</h2>', 1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1a,t1a,'from','to',context=True,numlines=6), 1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Context (numlines=0)</h2>', 1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1a,t1a,'from','to',context=True,numlines=0), 1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Same Context</h2>', 1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1a,f1a,'from','to',context=True), 1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Same Full</h2>', 1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f1a,f1a,'from','to',context=False), 1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Empty Context</h2>', 1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table([],[],'from','to',context=True), 1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Empty Full</h2>', 1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table([],[],'from','to',context=False), 1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>tabsize=2</h2>', 1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi j.make_table(f2,t2), 1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>tabsize=default</h2>', 1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi i.make_table(f2,t2), 1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>Context (wrapcolumn=14,numlines=0)</h2>', 1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k.make_table(f3.splitlines(),t3.splitlines(),context=True,numlines=0), 1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>wrapcolumn=14,splitlines()</h2>', 1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k.make_table(f3.splitlines(),t3.splitlines()), 1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<h2>wrapcolumn=14,splitlines(True)</h2>', 1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi k.make_table(f3.splitlines(True),t3.splitlines(True)), 1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ]) 1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi actual = full.replace('</body>','\n%s\n</body>' % tables) 1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # temporarily uncomment next two lines to baseline this test 1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi #with open('test_difflib_expect.html','w') as fp: 1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # fp.write(actual) 1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi with open(findfile('test_difflib_expect.html')) as fp: 1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(actual, fp.read()) 1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_recursion_limit(self): 1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check if the problem described in patch #1413711 exists. 1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi limit = sys.getrecursionlimit() 1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old = [(i%2 and "K:%d" or "V:A:%d") % i for i in range(limit*2)] 1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi new = [(i%2 and "K:%d" or "V:B:%d") % i for i in range(limit*2)] 1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi difflib.SequenceMatcher(None, old, new).get_opcodes() 1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestOutputFormat(unittest.TestCase): 2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_tab_delimiter(self): 2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi args = ['one', 'two', 'Original', 'Current', 2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '2005-01-26 23:30:50', '2010-04-02 10:20:52'] 2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ud = difflib.unified_diff(*args, lineterm='') 2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(ud)[0:2], [ 2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "--- Original\t2005-01-26 23:30:50", 2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "+++ Current\t2010-04-02 10:20:52"]) 2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cd = difflib.context_diff(*args, lineterm='') 2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(cd)[0:2], [ 2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "*** Original\t2005-01-26 23:30:50", 2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "--- Current\t2010-04-02 10:20:52"]) 2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_trailing_tab_on_empty_filedate(self): 2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi args = ['one', 'two', 'Original', 'Current'] 2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ud = difflib.unified_diff(*args, lineterm='') 2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(ud)[0:2], ["--- Original", "+++ Current"]) 2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cd = difflib.context_diff(*args, lineterm='') 2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(list(cd)[0:2], ["*** Original", "--- Current"]) 2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_range_format_unified(self): 2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Per the diff spec at http://www.unix.org/single_unix_specification/ 2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec = '''\ 2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Each <range> field shall be of the form: 2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi %1d", <beginning line number> if the range contains exactly one line, 2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and: 2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "%1d,%1d", <beginning line number>, <number of lines> otherwise. 2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi If a range is empty, its beginning line number shall be the number of 2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi the line just before the range, or 0 if the empty range starts the file. 2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ''' 2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fmt = difflib._format_range_unified 2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,3), '3,0') 2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,4), '4') 2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,5), '4,2') 2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,6), '4,3') 2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(0,0), '0,0') 2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_range_format_context(self): 2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Per the diff spec at http://www.unix.org/single_unix_specification/ 2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spec = '''\ 2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The range of lines in file1 shall be written in the following format 2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if the range contains two or more lines: 2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "*** %d,%d ****\n", <beginning line number>, <ending line number> 2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and the following format otherwise: 2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "*** %d ****\n", <ending line number> 2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi The ending line number of an empty range shall be the number of the preceding line, 2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi or 0 if the range is at the start of the file. 2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Next, the range of lines in file2 shall be written in the following format 2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if the range contains two or more lines: 2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "--- %d,%d ----\n", <beginning line number>, <ending line number> 2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi and the following format otherwise: 2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "--- %d ----\n", <ending line number> 2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ''' 2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fmt = difflib._format_range_context 2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,3), '3') 2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,4), '4') 2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,5), '4,5') 2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(3,6), '4,6') 2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(fmt(0,0), '0') 2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main(): 2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi difflib.HtmlDiff._default_prefix = 0 2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Doctests = doctest.DocTestSuite(difflib) 2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi run_unittest( 2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi TestWithAscii, TestAutojunk, TestSFpatches, TestSFbugs, 2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi TestOutputFormat, Doctests) 2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == '__main__': 2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi test_main() 273