def test_from_unified_diff_multiple_additions_different_orderings(self): source = ['A', 'B', 'C'] target = ['A', 'Y', 'Z', 'B', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,5 @@', ' A', '+Y', '+Z', ' B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A', 'B', 'C'] target = ['A', 'Y', 'Z', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,5 @@', ' A', '+Y', '+Z', '-B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A', 'B', 'C'] target = ['Y', 'Z', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,5 @@', '-A', '+Y', '+Z', '-B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A', 'B', 'C'] target = ['A', 'B', 'C', 'Y', 'Z'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -3 +3,3 @@', ' C', '+Y', '+Z'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def process_output_unified_diff(self, output, filename, file, diff_severity=RESULT_SEVERITY.NORMAL, result_message='Inconsistency found.', diff_distance=1): """ Processes the executable's output as a unified diff. :param output: The output of the program as a string containing the unified diff for correction. :param filename: The filename of the file currently being corrected. :param file: The contents of the file currently being corrected. :param diff_severity: The severity to use for generating results. :param result_message: The message-string to use for generating results. :param diff_distance: Number of unchanged lines that are allowed in between two changed lines so they get yielded as one diff. If a negative distance is given, every change will be yielded as an own diff, even if they are right beneath each other. :return: An iterator returning results containing patches for the file to correct. """ return self.process_diff(Diff.from_unified_diff(output, file), filename, diff_severity, result_message, diff_distance)
def test_from_unified_diff_no_changes_empty_diff(self): source = ['first\n', 'second'] target = ['first\n', 'second'] diff_string = '' self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_unmatched_context_line(self): source = ['first', 'second'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' context_line_is_not_same', ' second' ] diff_string = '\n'.join(diff) error_message = ('Context lines do not match. ' 'Line from unified diff: {!r}, ' 'Original line #{!r}: {!r}') with self.assertRaisesRegex( RuntimeError, error_message.format('context_line_is_not_same', 1, 'first')): Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_no_changes_empty_diff(self): source = ['first', 'second'] target = ['first', 'second'] diff_string = '' self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_unmatched_line_to_delete(self): source = ['first', 'second'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', '-line_to_be_deleted_is_not_same', '+only_first_changed', ' second' ] diff_string = '\n'.join(diff) error_message = ('The line to delete does not match with ' 'the line in the original file. ' 'Line to delete: {!r}, ' 'Original line #{!r}: {!r}') with self.assertRaisesRegex( RuntimeError, error_message.format('line_to_be_deleted_is_not_same', 1, 'first')): Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_invalid_line_type_character(self): source = ['first', 'invalid starting character'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' first', '*invalid_starting_character' ] diff_string = '\n'.join(diff) with self.assertRaises(UnidiffParseError): self.uut = Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_invalid_hunk(self): source = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,7 +1,5 @@', ' A', ' B', '-C', '+Z', '@@ -6,2 +5,2 @@', ' F', '-G', '+K' ] diff_string = '\n'.join(diff) with self.assertRaises(UnidiffParseError): self.uut = Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_multiple_additions_different_orderings(self): source = ['A\n', 'B\n', 'C'] target = ['A\n', 'Y\n', 'Z\n', 'B\n', 'C'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,5 @@', ' A', '+Y', '+Z', ' B', ' C' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A\n', 'B\n', 'C'] target = ['A\n', 'Y\n', 'Z\n', 'C'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,4 @@', ' A', '+Y', '+Z', '-B', ' C' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A\n', 'B\n', 'C'] target = ['Y\n', 'Z\n', 'C'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,3 @@', '-A', '+Y', '+Z', '-B', ' C' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A\n', 'B\n', 'C'] target = ['A\n', 'B\n', 'C\n', 'Y\n', 'Z'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -3 +3,3 @@', ' C', '+Y', '+Z' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_invalid_line_type_character(self): source = ['first', 'invalid starting character'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' first', '*invalid_starting_character'] diff_string = '\n'.join(diff) with self.assertRaises(UnidiffParseError): self.uut = Diff.from_unified_diff(diff_string, source)
def test_process_output_unified_diff_incomplete_hunk(self): uut = (linter(sys.executable, output_format='unified-diff') (self.EmptyTestLinter) (self.section, None)) original = ['void main() {', '// This comment is missing', '// in the unified diff', 'return 09;', '}'] diff = ['--- a/some-file.c', '+++ b/some-file.c', '@@ -1,1 +1,2 @@', '-void main() {', '+void main()', '+{', '@@ -4,2 +5,2 @@', '-return 09;', '+ return 9;', ' }'] diff_string = '\n'.join(diff) results = list(uut.process_output(diff_string, 'some-file.c', original)) diffs = list(Diff.from_unified_diff(diff_string, original).split_diff()) expected = [Result.from_values(uut, 'Inconsistency found.', 'some-file.c', 1, None, 1, None, RESULT_SEVERITY.NORMAL, diffs={'some-file.c': diffs[0]}), Result.from_values(uut, 'Inconsistency found.', 'some-file.c', 4, None, 4, None, RESULT_SEVERITY.NORMAL, diffs={'some-file.c': diffs[1]})] self.assertEqual(results, expected) uut = (linter(sys.executable, output_format='unified-diff', diff_distance=-1) (self.EmptyTestLinter) (self.section, None)) results = list(uut.process_output(diff_string, 'some-file.c', original)) self.assertEqual(len(results), 2)
def test_from_unified_diff_unmatched_context_line(self): source = ['first', 'second'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' context_line_is_not_same', ' second'] diff_string = '\n'.join(diff) error_message = ('Context lines do not match. ' 'Line from unified diff: {!r}, ' 'Original line #{!r}: {!r}') with self.assertRaisesRegex( RuntimeError, error_message.format( 'context_line_is_not_same', 1, 'first')): Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_incomplete_hunks_multiple_additions(self): source = ['A', 'C', 'D', 'E', 'G'] target = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,1 +1,2 @@', ' A', '+B', '@@ -4,2 +5,3 @@', ' E', '+F', ' G' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_process_output_unified_diff_incomplete_hunk(self): uut = (linter(sys.executable, output_format='unified-diff')( self.EmptyTestLinter)(self.section, None)) original = [ 'void main() {', '// This comment is missing', '// in the unified diff', 'return 09;', '}' ] diff = [ '--- a/some-file.c', '+++ b/some-file.c', '@@ -1,1 +1,2 @@', '-void main() {', '+void main()', '+{', '@@ -4,2 +5,2 @@', '-return 09;', '+ return 9;', ' }' ] diff_string = '\n'.join(diff) results = list(uut.process_output(diff_string, 'some-file.c', original)) diffs = list( Diff.from_unified_diff(diff_string, original).split_diff()) expected = [ Result.from_values(uut, 'Inconsistency found.', 'some-file.c', 1, None, 1, None, RESULT_SEVERITY.NORMAL, diffs={'some-file.c': diffs[0]}), Result.from_values(uut, 'Inconsistency found.', 'some-file.c', 4, None, 4, None, RESULT_SEVERITY.NORMAL, diffs={'some-file.c': diffs[1]}) ] self.assertEqual(results, expected) uut = (linter(sys.executable, output_format='unified-diff', diff_distance=-1)(self.EmptyTestLinter)(self.section, None)) results = list(uut.process_output(diff_string, 'some-file.c', original)) self.assertEqual(len(results), 2)
def test_from_unified_diff_no_changes(self): source = ['first\n', 'second'] target = ['first\n', 'second'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' first', ' second' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_incomplete_hunks_multiple_modifications(self): source = ['A\n', 'B\n', 'C\n', 'D\n', 'E\n', 'F\n', 'G'] target = ['A\n', 'B\n', 'Z\n', 'D\n', 'E\n', 'F\n', 'K'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,3 @@', ' A', ' B', '-C', '+Z', '@@ -6,2 +5,2 @@', ' F', '-G', '+K' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_single_addition(self): source = ['single line'] target = ['single line\n', 'another line added'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1 +1,2 @@', ' single line', '+another line added' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_multiple_hunks(self): source = ['A\n', 'B\n', 'C\n', 'D\n', 'E\n', 'F\n', 'G'] target = ['A\n', 'C\n', 'D\n', 'E\n', 'F\n'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,1 @@', ' A', '-B', '@@ -3,5 +2,4 @@', ' C', ' D', ' E', ' F', '-G' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_single_deletion(self): source = ['two lines\n', 'to be removed'] target = ['two lines\n'] diff = [ '--- a/testfile', '+++ b/testfile', '@@ -1,2 +1 @@', ' two lines', '-to be removed' ] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_single_addition(self): source = ['single line'] target = ['single line', 'another line added'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1 +1,2 @@', ' single line', '+another line added'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_single_deletion(self): source = ['two lines', 'to be removed'] target = ['two lines'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1 @@', ' two lines', '-to be removed'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_no_changes(self): source = ['first', 'second'] target = ['first', 'second'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', ' first', ' second'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diffrent_beginning_line_types(self): source = ['A\n', 'B\n', 'C'] target = ['A\n', 'Y\n', 'B\n', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,4 @@', ' A', '+Y', ' B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A\n', 'B\n', 'C'] target = ['B\n', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,2 @@', '-A', ' B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A\n', 'B\n', 'C'] target = ['Z\n', 'A\n', 'B\n', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,3 @@', '+Z', ' A', ' B'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diffrent_beginning_line_types(self): source = ['A', 'B', 'C'] target = ['A', 'Y', 'B', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,4 @@', ' A', '+Y', ' B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A', 'B', 'C'] target = ['B', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,3 +1,2 @@', '-A', ' B', ' C'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target) source = ['A', 'B', 'C'] target = ['Z', 'A', 'B', 'C'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,3 @@', '+Z', ' A', ' B'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_single_modification(self): source = ['first\n', 'second'] target = ['only_first_changed\n', 'second'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', '-first', '+only_first_changed', ' second'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_unmatched_line_to_delete(self): source = ['first', 'second'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', '-line_to_be_deleted_is_not_same', '+only_first_changed', ' second'] diff_string = '\n'.join(diff) error_message = ('The line to delete does not match with ' 'the line in the original file. ' 'Line to delete: {!r}, ' 'Original line #{!r}: {!r}') with self.assertRaisesRegex( RuntimeError, error_message.format( 'line_to_be_deleted_is_not_same', 1, 'first')): Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_incomplete_hunks_multiple_additions(self): source = ['A', 'C', 'D', 'E', 'G'] target = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,1 +1,2 @@', ' A', '+B', '@@ -4,2 +5,3 @@', ' E', '+F', ' G'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_invalid_hunk(self): source = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,7 +1,5 @@', ' A', ' B', '-C', '+Z', '@@ -6,2 +5,2 @@', ' F', '-G', '+K'] diff_string = '\n'.join(diff) with self.assertRaises(UnidiffParseError): self.uut = Diff.from_unified_diff(diff_string, source)
def test_from_unified_diff_incomplete_hunks_multiple_deletions(self): source = ['A\n', 'B\n', 'C\n', 'D\n', 'E\n', 'F\n', 'G'] target = ['A\n', 'C\n', 'D\n', 'E\n', 'F\n'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,1 @@', ' A', '-B', '@@ -5,3 +4,2 @@', ' E', ' F', '-G'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)
def test_from_unified_diff_multiple_hunks(self): source = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] target = ['A', 'C', 'D', 'E', 'F'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,1 @@', ' A', '-B', '@@ -3,5 +2,4 @@', ' C', ' D', ' E', ' F', '-G'] diff_string = '\n'.join(diff) self.uut = Diff.from_unified_diff(diff_string, source) self.assertEqual(self.uut.original, source) self.assertEqual(self.uut.modified, target)