tests: remove #! lines and leverage pytest further
[git-cola.git] / test / diffparse_test.py
blob9abc5e92f7282cbe4003acd7d2678c6f3554ffd0
1 from __future__ import absolute_import, division, unicode_literals
2 import unittest
4 from cola import core
5 from cola import diffparse
7 from . import helper
10 class ParseDiffTestCase(unittest.TestCase):
12 def test_diff(self):
13 fixture_path = helper.fixture('diff.txt')
14 parser = diffparse.DiffParser('cola/diffparse.py', core.read(fixture_path))
15 hunks = parser.hunks
17 self.assertEqual(len(hunks), 3)
18 self.assertEqual(hunks[0].first_line_idx, 0)
19 self.assertEqual(len(hunks[0].lines), 23)
20 self.assertEqual(
21 hunks[0].lines[0], '@@ -6,10 +6,21 @@ from cola import gitcmds\n'
23 self.assertEqual(hunks[0].lines[1], ' from cola import gitcfg\n')
24 self.assertEqual(hunks[0].lines[2], ' \n')
25 self.assertEqual(hunks[0].lines[3], ' \n')
26 self.assertEqual(hunks[0].lines[4], '+class DiffSource(object):\n')
27 self.assertEqual(
28 hunks[0].lines[-1],
29 r" self._header_start_re = re.compile('^@@ -(\d+)"
30 r" \+(\d+),(\d+) @@.*')"
31 '\n',
34 self.assertEqual(hunks[1].first_line_idx, 23)
35 self.assertEqual(len(hunks[1].lines), 18)
36 self.assertEqual(
37 hunks[1].lines[0], '@@ -29,13 +40,11 @@ class DiffParser(object):\n'
39 self.assertEqual(hunks[1].lines[1], ' self.diff_sel = []\n')
40 self.assertEqual(hunks[1].lines[2], ' self.selected = []\n')
41 self.assertEqual(hunks[1].lines[3], ' self.filename = filename\n')
42 self.assertEqual(
43 hunks[1].lines[4],
44 '+ self.diff_source = diff_source or DiffSource()\n',
46 self.assertEqual(hunks[1].lines[-1], ' self.header = header\n')
48 self.assertEqual(hunks[2].first_line_idx, 41)
49 self.assertEqual(len(hunks[2].lines), 16)
50 self.assertEqual(
51 hunks[2].lines[0], '@@ -43,11 +52,10 @@ class DiffParser(object):\n'
53 self.assertEqual(
54 hunks[2].lines[-1],
55 ' """Writes a new diff corresponding to the user\'s'
56 ' selection."""\n',
59 def test_diff_at_start(self):
60 fixture_path = helper.fixture('diff-start.txt')
61 parser = diffparse.DiffParser('foo bar/a', core.read(fixture_path))
62 hunks = parser.hunks
64 self.assertEqual(hunks[0].lines[0], '@@ -1 +1,4 @@\n')
65 self.assertEqual(hunks[-1].lines[-1], '+c\n')
66 self.assertEqual(hunks[0].old_start, 1)
67 self.assertEqual(hunks[0].old_count, 1)
68 self.assertEqual(hunks[0].new_start, 1)
69 self.assertEqual(hunks[0].new_count, 4)
70 self.assertEqual(
71 parser.generate_patch(1, 3),
72 '--- a/foo bar/a\n'
73 '+++ b/foo bar/a\n'
74 '@@ -1 +1,3 @@\n'
75 ' bar\n'
76 '+a\n'
77 '+b\n',
79 self.assertEqual(
80 parser.generate_patch(0, 4),
81 '--- a/foo bar/a\n'
82 '+++ b/foo bar/a\n'
83 '@@ -1 +1,4 @@\n'
84 ' bar\n'
85 '+a\n'
86 '+b\n'
87 '+c\n',
90 def test_diff_at_end(self):
91 fixture_path = helper.fixture('diff-end.txt')
92 parser = diffparse.DiffParser('rijndael.js', core.read(fixture_path))
93 hunks = parser.hunks
95 self.assertEqual(hunks[0].lines[0], '@@ -1,39 +1 @@\n')
96 self.assertEqual(
97 hunks[-1].lines[-1],
98 "+module.exports = require('./build/Release/rijndael');\n",
100 self.assertEqual(hunks[0].old_start, 1)
101 self.assertEqual(hunks[0].old_count, 39)
102 self.assertEqual(hunks[0].new_start, 1)
103 self.assertEqual(hunks[0].new_count, 1)
105 def test_diff_that_empties_file(self):
106 fixture_path = helper.fixture('diff-empty.txt')
107 parser = diffparse.DiffParser('filename', core.read(fixture_path))
108 hunks = parser.hunks
110 self.assertEqual(hunks[0].lines[0], '@@ -1,2 +0,0 @@\n')
111 self.assertEqual(hunks[-1].lines[-1], '-second\n')
112 self.assertEqual(hunks[0].old_start, 1)
113 self.assertEqual(hunks[0].old_count, 2)
114 self.assertEqual(hunks[0].new_start, 0)
115 self.assertEqual(hunks[0].new_count, 0)
116 self.assertEqual(
117 parser.generate_patch(1, 1),
118 '--- a/filename\n'
119 '+++ b/filename\n'
120 '@@ -1,2 +1 @@\n'
121 '-first\n'
122 ' second\n',
124 self.assertEqual(
125 parser.generate_patch(0, 2),
126 '--- a/filename\n'
127 '+++ b/filename\n'
128 '@@ -1,2 +0,0 @@\n'
129 '-first\n'
130 '-second\n',
133 def test_diff_file_removal(self):
134 diff_text = """\
135 deleted file mode 100755
136 @@ -1,1 +0,0 @@
137 -#!/bin/sh
139 parser = diffparse.DiffParser('deleted.txt', diff_text)
140 self.assertEqual(1, len(parser.hunks))
142 # Selecting the first two lines generate no diff
143 expect = None
144 actual = parser.generate_patch(0, 1)
145 self.assertEqual(expect, actual)
147 # Selecting the last line should generate a line removal
148 expect = """\
149 --- a/deleted.txt
150 +++ b/deleted.txt
151 @@ -1 +0,0 @@
152 -#!/bin/sh
154 actual = parser.generate_patch(1, 2)
155 self.assertEqual(expect, actual)
157 # All three lines should map to the same hunk diff
158 actual = parser.generate_hunk_patch(0)
159 self.assertEqual(expect, actual)
161 actual = parser.generate_hunk_patch(1)
162 self.assertEqual(expect, actual)
164 actual = parser.generate_hunk_patch(2)
165 self.assertEqual(expect, actual)
168 class DiffLinesTestCase(unittest.TestCase):
169 def setUp(self):
170 self.parser = diffparse.DiffLines()
171 fixture_path = helper.fixture('diff.txt')
172 self.text = core.read(fixture_path)
174 def test_basic_diff_line_count(self):
175 """Verify the basic line counts"""
176 lines = self.parser.parse(self.text)
177 expect = len(self.text.splitlines())
178 actual = len(lines)
179 self.assertEqual(expect, actual)
181 def test_diff_line_count_ranges(self):
182 parser = self.parser
183 lines = parser.parse(self.text)
185 # Diff header
186 line = 0
187 count = 1
188 self.assertEqual(lines[line][0], parser.DASH)
189 self.assertEqual(lines[line][1], parser.DASH)
190 line += count
192 # 3 lines of context
193 count = 3
194 current_old = 6
195 current_new = 6
196 for i in range(count):
197 self.assertEqual(lines[line + i][0], current_old + i)
198 self.assertEqual(lines[line + i][1], current_new + i)
199 line += count
200 current_old += count
201 current_new += count
203 # 10 lines of new text
204 count = 10
205 for i in range(count):
206 self.assertEqual(lines[line + i][0], parser.EMPTY)
207 self.assertEqual(lines[line + i][1], current_new + i)
209 line += count
210 current_new += count
212 # 3 more lines of context
213 count = 3
214 for i in range(count):
215 self.assertEqual(lines[line + i][0], current_old + i)
216 self.assertEqual(lines[line + i][1], current_new + i)
217 line += count
218 current_new += count
219 current_old += count
221 # 1 line of removal
222 count = 1
223 for i in range(count):
224 self.assertEqual(lines[line + i][0], current_old + i)
225 self.assertEqual(lines[line + i][1], parser.EMPTY)
226 line += count
227 current_old += count
229 # 2 lines of addition
230 count = 2
231 for i in range(count):
232 self.assertEqual(lines[line + i][0], parser.EMPTY)
233 self.assertEqual(lines[line + i][1], current_new + i)
234 line += count
235 current_new += count
237 # 3 more lines of context
238 count = 3
239 for i in range(count):
240 self.assertEqual(lines[line + i][0], current_old + i)
241 self.assertEqual(lines[line + i][1], current_new + i)
242 line += count
243 current_new += count
244 current_old += count
246 # 1 line of header
247 count = 1
248 for i in range(count):
249 self.assertEqual(lines[line + i][0], parser.DASH)
250 self.assertEqual(lines[line + i][1], parser.DASH)
251 line += count
253 # 3 more lines of context
254 current_old = 29
255 current_new = 40
256 count = 3
257 for i in range(count):
258 self.assertEqual(lines[line + i][0], current_old + i)
259 self.assertEqual(lines[line + i][1], current_new + i)
260 line += count
261 current_new += count
262 current_old += count
264 expect_max_old = 54
265 self.assertEqual(expect_max_old, parser.old.max_value)
267 expect_max_new = 62
268 self.assertEqual(expect_max_new, parser.new.max_value)
270 self.assertEqual(parser.digits(), 2)
272 def test_diff_line_for_merge(self):
273 """Verify the basic line counts"""
274 text = """@@@ -1,23 -1,33 +1,75 @@@
275 ++<<<<<<< upstream
279 parser = self.parser
280 lines = parser.parse(text)
281 self.assertEqual(len(lines), 4)
282 self.assertEqual(len(lines[0]), 3)
283 self.assertEqual(len(lines[1]), 3)
284 self.assertEqual(len(lines[2]), 3)
285 self.assertEqual(len(lines[3]), 3)
287 self.assertEqual(lines[0][0], parser.DASH)
288 self.assertEqual(lines[0][1], parser.DASH)
289 self.assertEqual(lines[0][2], parser.DASH)
291 self.assertEqual(lines[1][0], parser.EMPTY)
292 self.assertEqual(lines[1][1], parser.EMPTY)
293 self.assertEqual(lines[1][2], 1)
295 self.assertEqual(lines[2][0], 1)
296 self.assertEqual(lines[2][1], parser.EMPTY)
297 self.assertEqual(lines[2][2], 2)
299 self.assertEqual(lines[3][0], 2)
300 self.assertEqual(lines[3][1], parser.EMPTY)
301 self.assertEqual(lines[3][2], 3)
304 class FormatDiffLinesTestCase(unittest.TestCase):
305 def test_format_basic(self):
306 fmt = diffparse.FormatDigits()
307 fmt.set_digits(2)
309 expect = '01 99'
310 actual = fmt.value(1, 99)
311 self.assertEqual(expect, actual)
313 def test_format_reuse(self):
314 fmt = diffparse.FormatDigits()
316 fmt.set_digits(3)
317 expect = '001 099'
318 actual = fmt.value(1, 99)
319 self.assertEqual(expect, actual)
321 fmt.set_digits(4)
322 expect = '0001 0099'
323 actual = fmt.value(1, 99)
324 self.assertEqual(expect, actual)
326 def test_format_special_values(self):
327 fmt = diffparse.FormatDigits(dash='-')
328 fmt.set_digits(3)
330 expect = ' 099'
331 actual = fmt.value(fmt.EMPTY, 99)
332 self.assertEqual(expect, actual)
334 expect = '001 '
335 actual = fmt.value(1, fmt.EMPTY)
336 self.assertEqual(expect, actual)
338 expect = ' '
339 actual = fmt.value(fmt.EMPTY, fmt.EMPTY)
340 self.assertEqual(expect, actual)
342 expect = '--- 001'
343 actual = fmt.value(fmt.DASH, 1)
344 self.assertEqual(expect, actual)
346 expect = '099 ---'
347 actual = fmt.value(99, fmt.DASH)
348 self.assertEqual(expect, actual)
350 expect = '--- ---'
351 actual = fmt.value(fmt.DASH, fmt.DASH)
352 self.assertEqual(expect, actual)
354 expect = ' ---'
355 actual = fmt.value(fmt.EMPTY, fmt.DASH)
356 self.assertEqual(expect, actual)
358 expect = '--- '
359 actual = fmt.value(fmt.DASH, fmt.EMPTY)
360 self.assertEqual(expect, actual)
363 class ParseRangeStrTestCase(unittest.TestCase):
364 def test_parse_range_str(self):
365 start, count = diffparse.parse_range_str('1,2')
366 self.assertEqual(start, 1)
367 self.assertEqual(count, 2)
369 def test_parse_range_str_single_line(self):
370 start, count = diffparse.parse_range_str('2')
371 self.assertEqual(start, 2)
372 self.assertEqual(count, 1)
374 def test_parse_range_str_empty(self):
375 start, count = diffparse.parse_range_str('0,0')
376 self.assertEqual(start, 0)
377 self.assertEqual(count, 0)