| """Tests for diff_utils.""" |
| |
| from __future__ import absolute_import |
| import difflib |
| import os |
| import sys |
| import unittest |
| |
| # Allow imports from cq/scripts folder |
| sys.path.insert( |
| 0, |
| os.path.realpath( |
| os.path.join(os.path.dirname(__file__), os.pardir))) |
| from helpers import diff_utils |
| |
| FROM_FILE = 'FROM_FILE' |
| TO_FILE = 'TO_FILE' |
| |
| |
| class DiffUtilsTest(unittest.TestCase): |
| |
| # pylint: disable=invalid-name |
| def diff_strings(self, from_string, to_string, from_name, to_name): |
| return difflib.unified_diff(from_string.splitlines(True), |
| to_string.splitlines(True), |
| fromfile=from_name, |
| tofile=to_name, |
| n=0) |
| |
| def testEmptyDiff(self): |
| """Tests creating comments from an empty diff.""" |
| empty = '' |
| |
| diff = self.diff_strings(empty, empty, FROM_FILE, TO_FILE) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEquals(comments, {}) |
| |
| def testSingleLineSingleDiff(self): |
| """Tests creating a comment from a diff made form a single line.""" |
| from_lines = 'This line is foo.' |
| to_lines = 'This line is bar.' |
| |
| diff = self.diff_strings(from_lines, to_lines, FROM_FILE, TO_FILE) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEqual(len(comments), 1) |
| self.assertIn(TO_FILE, comments) |
| self.assertEqual(len(comments[TO_FILE]), 1) |
| |
| expected_range = {'start_line': '1', |
| 'start_character': '0', |
| 'end_line': '1', |
| 'end_character': '16'} |
| comment_range = comments[TO_FILE][0]['range'] |
| self.assertEqual(expected_range, comment_range) |
| |
| message = comments[TO_FILE][0]['message'] |
| self.assertIn('-' + from_lines, message) |
| self.assertIn('+' + to_lines, message) |
| self.assertEqual(len(message.splitlines()), 2) |
| |
| def testMultipleLineSingleDiff(self): |
| """Tests creating comments from a diff made of multiple lines.""" |
| from_lines = ('This line is the same.\n' |
| 'This line is foo.\n' |
| 'This line is foo also.\n' |
| 'This line is the same.') |
| to_lines = ('This line is the same.\n' |
| 'This line is bar.\n' |
| 'This line is bar also.\n' |
| 'This line is the same.') |
| |
| diff = self.diff_strings(from_lines, to_lines, FROM_FILE, TO_FILE) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEqual(len(comments), 1) |
| self.assertIn(TO_FILE, comments) |
| self.assertEqual(len(comments[TO_FILE]), 1) |
| |
| expected_range = {'start_line': '2', |
| 'start_character': '0', |
| 'end_line': '3', |
| 'end_character': '21'} |
| comment_range = comments[TO_FILE][0]['range'] |
| self.assertEqual(expected_range, comment_range) |
| |
| message = comments[TO_FILE][0]['message'] |
| self.assertEqual(message.count('-'), 2) |
| self.assertEqual(message.count('+'), 2) |
| self.assertEqual(len(message.splitlines()), 4) |
| |
| def testMultipleLineMultipleDiff(self): |
| """Tests creating multiple comments from a multi-part diff.""" |
| from_lines = ('This line is the same.\n' |
| 'This line is foo.\n' |
| 'This line is the same.\n' |
| 'This line is foo.\n' |
| 'This line is foo.') |
| to_lines = ('This line is the same.\n' |
| 'This line is bar.\n' |
| 'This line is the same.\n' |
| 'This line is bar.\n' |
| 'This line is bar.') |
| |
| diff = self.diff_strings(from_lines, to_lines, FROM_FILE, TO_FILE) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEqual(len(comments), 1) |
| self.assertIn(TO_FILE, comments) |
| self.assertEqual(len(comments[TO_FILE]), 2) |
| |
| # First diff |
| expected_range = {'start_line': '2', |
| 'start_character': '0', |
| 'end_line': '2', |
| 'end_character': '16'} |
| comment_range = comments[TO_FILE][0]['range'] |
| self.assertEqual(expected_range, comment_range) |
| |
| message = comments[TO_FILE][0]['message'] |
| self.assertEqual(message.count('-'), 1) |
| self.assertEqual(message.count('+'), 1) |
| self.assertEqual(len(message.splitlines()), 2) |
| |
| # Second diff |
| expected_range = {'start_line': '4', |
| 'start_character': '0', |
| 'end_line': '5', |
| 'end_character': '16'} |
| comment_range = comments[TO_FILE][1]['range'] |
| self.assertEqual(expected_range, comment_range) |
| |
| message = comments[TO_FILE][1]['message'] |
| self.assertEqual(message.count('-'), 2) |
| self.assertEqual(message.count('+'), 2) |
| self.assertEqual(len(message.splitlines()), 4) |
| |
| def testNoFileName(self): |
| """Tests creating a comment when tofile is not passed to unified_diff().""" |
| from_lines = 'This line is foo.' |
| to_lines = 'This line is bar.' |
| |
| diff = difflib.unified_diff(from_lines, to_lines) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEqual(len(comments), 1) |
| self.assertIn('', comments) |
| self.assertEqual(len(comments['']), 1) |
| |
| def testSpacesForGerritFormatting(self): |
| """Tests that each line of a file level comment starts with a space.""" |
| from_lines = ('This line is the same.\n' |
| 'This line is foo.\n' |
| 'This line is foo also.\n' |
| 'This line is the same.') |
| to_lines = ('This line is the same.\n' |
| 'This line is bar.\n' |
| 'This line is bar also.\n' |
| 'This line is the same.') |
| |
| diff = self.diff_strings(from_lines, to_lines, FROM_FILE, TO_FILE) |
| comments = diff_utils.diff_to_comments(diff) |
| |
| message = comments[TO_FILE][0]['message'] |
| for line in message.splitlines(): |
| self.assertTrue(line.startswith(' ')) |
| |
| def testDiffWithMultipleFiles(self): |
| """Tests that a multifile diff puts comments with the proper file.""" |
| diff = ['--- foo1.cc\n', |
| '+++ foo1.cc\n', |
| '@@ -123,1 +123,1 @@\n', |
| 'message1.0\n', |
| '--- foo2.cc\n', |
| '+++ foo2.cc\n', |
| '@@ -456,1 +456,1 @@\n', |
| 'message2.0\n', |
| '@@ -456,1 +456,1 @@\n', |
| 'message2.1\n', |
| '--- foo3.cc\n', |
| '+++ foo3.cc\n', |
| '@@ -789,1 +789,1 @@\n', |
| 'message3.0\n',] |
| comments = diff_utils.diff_to_comments(diff) |
| |
| self.assertEqual(len(comments), 3) |
| self.assertIn('foo1.cc', comments) |
| self.assertIn('foo2.cc', comments) |
| self.assertIn('foo3.cc', comments) |
| |
| self.assertEqual(len(comments['foo1.cc']), 1) |
| self.assertEqual(len(comments['foo2.cc']), 2) |
| self.assertEqual(len(comments['foo3.cc']), 1) |
| |
| self.assertIn('message1.0', comments['foo1.cc'][0]['message']) |
| self.assertIn('message2.0', comments['foo2.cc'][0]['message']) |
| self.assertIn('message2.1', comments['foo2.cc'][1]['message']) |
| self.assertIn('message3.0', comments['foo3.cc'][0]['message']) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |