def test_add(self): file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"], "f_c": ["1", "2", "3"] } expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3_changed"], "f_c": ["1", "2", "3"] } diff = Diff() diff.delete_line(2) uut1 = PatchResult("origin", "msg", {"f_a": diff}) diff = Diff() diff.change_line(3, "3", "3_changed") uut2 = PatchResult("origin", "msg", {"f_a": diff}) diff = Diff() diff.change_line(3, "3", "3_changed") uut3 = PatchResult("origin", "msg", {"f_b": diff}) uut1 += uut2 + uut3 uut1.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_print_result(self): self.uut.print = lambda x: x self.assertEqual("| | | [{normal}] {bear}:".format(normal=RESULT_SEVERITY.__str__(RESULT_SEVERITY.NORMAL), bear="origin") + "\n| | | message", self.uut._print_result(Result("origin", "message"))) builtins.__dict__["input"] = lambda x: 0 self.uut.print_result(PatchResult("origin", "msg", {}), {}) (testfile, testfile_path) = tempfile.mkstemp() os.close(testfile) file_dict = { testfile_path: ["1\n", "2\n", "3\n"], "f_b": ["1", "2", "3"] } diff = Diff() diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") builtins.__dict__["input"] = self.generate_input # To assure user can rechose if he didn't chose wisely self.uut.print_result(PatchResult("origin", "msg", {testfile_path: diff}), file_dict) self.assertEqual(self.curr, 1) self.uut.finalize(file_dict) with open(testfile_path) as f: self.assertEqual(f.readlines(), ["1\n", "3_changed\n"]) os.remove(testfile_path) name, section = self.uut._get_action_info(TestAction().get_metadata()) self.assertEqual(str(section), " {param : 3}") self.assertEqual(name, "TestAction") builtins.__dict__["input"] = lambda x: x
def test_apply(self): uut = ApplyPatchAction() file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"], "f_c": ["1", "2", "3"] } expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3_changed"], "f_c": ["1", "2", "3"] } file_diff_dict = {} diff = Diff() diff.delete_line(2) uut.apply_from_section(PatchResult("origin", "msg", {"f_a": diff}), file_dict, file_diff_dict, Section("t")) diff = Diff() diff.change_line(3, "3", "3_changed") uut.apply_from_section(PatchResult("origin", "msg", {"f_a": diff}), file_dict, file_diff_dict, Section("t")) diff = Diff() diff.change_line(3, "3", "3_changed") uut.apply(PatchResult("origin", "msg", {"f_b": diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].apply( file_dict[filename]) self.assertEqual(file_dict, expected_file_dict)
def test_apply(self): uut = ApplyPatchAction() file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"], "f_c": ["1", "2", "3"] } expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3_changed"], "f_c": ["1", "2", "3"] } file_diff_dict = {} diff = Diff() diff.delete_line(2) uut.apply_from_section(PatchResult("origin", "msg", {"f_a": diff}), file_dict, file_diff_dict, Section("t")) diff = Diff() diff.change_line(3, "3", "3_changed") uut.apply_from_section(PatchResult("origin", "msg", {"f_a": diff}), file_dict, file_diff_dict, Section("t")) diff = Diff() diff.change_line(3, "3", "3_changed") uut.apply(PatchResult("origin", "msg", {"f_b": diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].apply(file_dict[filename]) self.assertEqual(file_dict, expected_file_dict)
def test_add(self): file_dict = { 'f_a': ['1', '2', '3'], 'f_b': ['1', '2', '3'], 'f_c': ['1', '2', '3'] } expected_file_dict = { 'f_a': ['1\n', '3_changed'], 'f_b': ['1\n', '2\n', '3_changed'], 'f_c': ['1', '2', '3'] } diff = Diff(file_dict['f_a']) diff.delete_line(2) uut1 = Result('origin', 'msg', diffs={'f_a': diff}) diff = Diff(file_dict['f_a']) diff.modify_line(3, '3_changed') uut2 = Result('origin', 'msg', diffs={'f_a': diff}) diff = Diff(file_dict['f_b']) diff.modify_line(3, '3_changed') uut3 = Result('origin', 'msg', diffs={'f_b': diff}) uut1 += uut2 + uut3 uut1.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_apply(self): uut = ShowAppliedPatchesAction() with make_temp() as f_a, make_temp() as f_b, make_temp() as f_c: file_dict = { f_a: ['1\n', '2\n', '3\n'], f_b: ['1\n', '2\n', '3\n'], f_c: ['1\n', '2\n', '3\n'] } expected_file_dict = { f_a: ['1\n', '3_changed\n'], f_b: ['1\n', '2\n', '3_changed\n'], f_c: ['1\n', '2\n', '3\n'] } with make_temp() as testfile_path: file_diff_dict = {} file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') result = Result('origin', 'msg', diffs={f_a: diff}, applied_actions={'ApplyPatchAction': [Result( 'origin', 'message', diffs={testfile_path: diff}), file_dict, file_diff_dict, Section('')]}) self.assertTrue(uut.apply(result, file_dict, file_diff_dict))
def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs(1, 2, 3) as generator, \ retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_results_no_input(self.log_printer, Section('someSection'), [Result('origin', 'message', diffs={ testfile_path: diff})], file_dict, self.file_diff_dict, self.console_printer) self.assertEqual(generator.last_input, -1) self.assertEqual(stdout.getvalue(), """ Project wide: **** origin [Section: someSection] **** ! ! [Severity: NORMAL] ! ! {}\n""".format(highlight_text(self.no_color, 'message', style=BackgroundMessageStyle)))
def test_finalize_backup_fail(self): def raise_error(file, mode=""): raise PermissionException _open = builtins.open _copy2 = shutil.copy2 try: builtins.open = raise_error builtins.__dict__["open"] = raise_error shutil.copy2 = lambda src, dst: self.assertEqual(src+".orig", dst) diff = Diff() diff.delete_line(2) # Should catch the backup permission error during write-back. finalize({"f": diff}, {"f": ["1", "2", "3"]}) # Test logging output. finalize({"f": diff}, {"f": ["1", "2"]}, log_printer=None) logger = LogPrinter(StringPrinter()) finalize({"f": diff}, {"f": ["1"]}, log_printer=logger) self.assertIn("Can't backup, writing patch to file f failed.", logger.printer.string) finally: builtins.open = _open shutil.copy2 = _copy2
def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 2, 3) as generator, retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) print_results_no_input( self.log_printer, Section("someSection"), [Result("origin", "message", diffs={testfile_path: diff})], file_dict, self.file_diff_dict, color=False, ) self.assertEqual(generator.last_input, -1) self.assertEqual( stdout.getvalue(), """ Project wide: | | [NORMAL] origin: | | message """, )
def generate_diff(comments, file, filename, line, line_number, pos): todo_source_range = SourceRange.from_values(filename, line_number, pos + 1) affected_comment_sourcerange = [ c for c in comments if todo_source_range in c ] affected_len = len(affected_comment_sourcerange) if affected_len == 0: return {} assert affected_len == 1, 'More than 1 affected comment source ranges' comment_sourcerange = affected_comment_sourcerange[0] comment_start = comment_sourcerange.start.column comment_end = comment_sourcerange.end.column in_multi_line_comment = (comment_sourcerange.start.line != comment_sourcerange.end.line) line_before_todo_comment = line[:comment_start - 1].rstrip() line_behind_todo_comment = line[comment_end:].rstrip() line_replacement = line_before_todo_comment + line_behind_todo_comment diff = Diff(file) if line_replacement and not in_multi_line_comment: diff.change_line(line_number, line, line_replacement + '\n') elif line_replacement and in_multi_line_comment: text_replacement = line[pos:] diff.change_line(line_number, line, line.replace(text_replacement, '').rstrip() + '\n') else: diff.delete_line(line_number) return {filename: diff}
def test_add(self): file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"], "f_c": ["1", "2", "3"] } expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3_changed"], "f_c": ["1", "2", "3"] } diff = Diff() diff.delete_line(2) uut1 = PatchResult("origin", "msg", {"f_a": diff}) diff = Diff() diff.change_line(3, "3", "3_changed") uut2 = PatchResult("origin", "msg", {"f_a": diff}) diff = Diff() diff.change_line(3, "3", "3_changed") uut3 = PatchResult("origin", "msg", {"f_b": diff}) uut1 += uut2 + uut3 uut1.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_apply(self): uut = ApplyPatchAction() fh_a, f_a = mkstemp() fh_b, f_b = mkstemp() fh_c, f_c = mkstemp() os.close(fh_a) os.close(fh_b) os.close(fh_c) file_dict = { f_a: ["1\n", "2\n", "3\n"], f_b: ["1\n", "2\n", "3\n"], f_c: ["1\n", "2\n", "3\n"] } expected_file_dict = { f_a: ["1\n", "3_changed\n"], f_b: ["1\n", "2\n", "3_changed\n"], f_c: ["1\n", "2\n", "3\n"] } file_diff_dict = {} diff = Diff(file_dict[f_a]) diff.delete_line(2) uut.apply_from_section(Result("origin", "msg", diffs={f_a: diff}), file_dict, file_diff_dict, Section("t")) diff = Diff(file_dict[f_a]) diff.change_line(3, "3\n", "3_changed\n") uut.apply_from_section(Result("origin", "msg", diffs={f_a: diff}), file_dict, file_diff_dict, Section("t")) diff = Diff(file_dict[f_b]) diff.change_line(3, "3\n", "3_changed\n") uut.apply(Result("origin", "msg", diffs={f_b: diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].modified self.assertEqual(file_dict, expected_file_dict) with open(f_a) as fa: self.assertEqual(file_dict[f_a], fa.readlines()) with open(f_b) as fb: self.assertEqual(file_dict[f_b], fb.readlines()) with open(f_c) as fc: # File c is unchanged and should be untouched self.assertEqual([], fc.readlines()) os.remove(f_a) os.remove(f_b) os.remove(f_c)
def test_acquire_actions_and_apply_single(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs('a', 'n') as generator: with retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result( 'origin', 'message', diffs={testfile_path: diff}), file_dict, apply_single=True) self.assertEqual(generator.last_input, -1) self.assertIn('', sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: 'ApplyPatchAction cannot be applied.') old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs('a') as generator: with retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result( 'origin', 'message', diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions, apply_single=True) self.assertEqual(generator.last_input, -1) action_fail = 'Failed to execute the action' self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 0) ApplyPatchAction.is_applicable = old_applypatch_is_applicable
def test_apply(self): file_dict = {"f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"]} expected_file_dict = {"f_a": ["1", "3_changed"], "f_b": ["1", "2", "3"]} diff = Diff(file_dict["f_a"]) diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = Result("origin", "msg", diffs={"f_a": diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_apply(self): uut = ApplyPatchAction() fh_a, f_a = mkstemp() fh_b, f_b = mkstemp() fh_c, f_c = mkstemp() os.close(fh_a) os.close(fh_b) os.close(fh_c) file_dict = { f_a: ["1\n", "2\n", "3\n"], f_b: ["1\n", "2\n", "3\n"], f_c: ["1\n", "2\n", "3\n"] } expected_file_dict = { f_a: ["1\n", "3_changed\n"], f_b: ["1\n", "2\n", "3_changed\n"], f_c: ["1\n", "2\n", "3\n"] } file_diff_dict = {} diff = Diff(file_dict[f_a]) diff.delete_line(2) uut.apply_from_section(Result("origin", "msg", diffs={f_a: diff}), file_dict, file_diff_dict, Section("t")) diff = Diff(file_dict[f_a]) diff.change_line(3, "3\n", "3_changed\n") uut.apply_from_section(Result("origin", "msg", diffs={f_a: diff}), file_dict, file_diff_dict, Section("t")) diff = Diff(file_dict[f_b]) diff.change_line(3, "3\n", "3_changed\n") uut.apply(Result("origin", "msg", diffs={f_b: diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].modified self.assertEqual(file_dict, expected_file_dict) with open(f_a) as fa: self.assertEqual(file_dict[f_a], fa.readlines()) with open(f_b) as fb: self.assertEqual(file_dict[f_b], fb.readlines()) with open(f_c) as fc: # File c is unchanged and should be untouched self.assertEqual([], fc.readlines()) os.remove(f_a) os.remove(f_b) os.remove(f_c)
def test_acquire_actions_and_apply_single(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs('a', 'n') as generator: with retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result( 'origin', 'message', diffs={testfile_path: diff}), file_dict, apply_single=True) self.assertEqual(generator.last_input, -1) self.assertIn('', sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: 'ApplyPatchAction cannot be applied.') old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs('a') as generator: with retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, Section(''), self.file_diff_dict, Result( 'origin', 'message', diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions, apply_single=True) self.assertEqual(generator.last_input, -1) action_fail = 'Failed to execute the action' self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 0) ApplyPatchAction.is_applicable = old_applypatch_is_applicable
def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 0) as generator, \ retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={ testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1) self.assertIn(ApplyPatchAction.success_message, sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: False) old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs(2, 1, 0) as generator, \ retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions) self.assertEqual(generator.last_input, 2) action_fail = "Failed to execute the action" self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 1) ApplyPatchAction.is_applicable = old_applypatch_is_applicable
def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 0) as generator, \ retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={ testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1) self.assertIn(ApplyPatchAction.SUCCESS_MESSAGE, sio.getvalue()) class InvalidateTestAction(ResultAction): is_applicable = staticmethod(lambda *args: True) def apply(*args, **kwargs): ApplyPatchAction.is_applicable = staticmethod( lambda *args: False) old_applypatch_is_applicable = ApplyPatchAction.is_applicable ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) cli_actions = [ApplyPatchAction(), InvalidateTestAction()] with simulate_console_inputs(2, 1, 0) as generator, \ retrieve_stdout() as sio: acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={testfile_path: diff}), file_dict, cli_actions=cli_actions) self.assertEqual(generator.last_input, 2) action_fail = "Failed to execute the action" self.assertNotIn(action_fail, sio.getvalue()) apply_path_desc = ApplyPatchAction().get_metadata().desc self.assertEqual(sio.getvalue().count(apply_path_desc), 1) ApplyPatchAction.is_applicable = old_applypatch_is_applicable
def test_apply(self): file_dict = {'f_a': ['1', '2', '3'], 'f_b': ['1', '2', '3']} expected_file_dict = { 'f_a': ['1', '3_changed'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, '3', '3_changed') uut = Result('origin', 'msg', diffs={'f_a': diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_apply(self): file_dict = {"f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"]} expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3"] } diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = Result("origin", "msg", diffs={"f_a": diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_bool(self): self.assertFalse(self.uut) self.uut.add_line(4, '4') self.assertTrue(self.uut) self.uut.delete_line(4) self.assertFalse(self.uut) # test if it works with tuples. uutuple = Diff(('1', '2', '3', '4')) self.assertFalse(uutuple) uutuple.add_line(4, '4') self.assertTrue(uutuple) uutuple.delete_line(4) self.assertFalse(uutuple)
def test_json_diff(self): file_dict = {'f_a': ['1', '2', '3'], 'f_b': ['1', '2', '3']} diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, '3', '3_changed') uut = Result('origin', 'msg', diffs={'f_a': diff}).__json__(True) self.assertEqual( uut['diffs']['f_a'].__json__(), '--- \n' '+++ \n' '@@ -1,3 +1,2 @@\n' ' 1-2-3+3_changed') JSONEncoder = create_json_encoder(use_relpath=True) json_dump = json.dumps(diff, cls=JSONEncoder, sort_keys=True) self.assertEqual(json_dump, '"--- \\n+++ \\n@@ -1,3 +1,2 @@\\n 1-2-3+3_changed"')
def test_bool(self): self.assertFalse(self.uut) self.uut.add_line(4, '4') self.assertTrue(self.uut) self.uut.delete_line(4) self.assertFalse(self.uut) # test if it works with tuples. uutuple = Diff(('1', '2', '3', '4')) self.assertFalse(uutuple) uutuple.add_line(4, '4') self.assertTrue(uutuple) uutuple.delete_line(4) self.assertFalse(uutuple)
def test_apply(self): uut = ApplyPatchAction() with make_temp() as f_a, make_temp() as f_b, make_temp() as f_c: file_dict = { f_a: ['1\n', '2\n', '3\n'], f_b: ['1\n', '2\n', '3\n'], f_c: ['1\n', '2\n', '3\n'] } expected_file_dict = { f_a: ['1\n', '3_changed\n'], f_b: ['1\n', '2\n', '3_changed\n'], f_c: ['1\n', '2\n', '3\n'] } file_diff_dict = {} diff = Diff(file_dict[f_a]) diff.delete_line(2) uut.apply_from_section(Result('origin', 'msg', diffs={f_a: diff}), file_dict, file_diff_dict, Section('t')) diff = Diff(file_dict[f_a]) diff.change_line(3, '3\n', '3_changed\n') uut.apply_from_section(Result('origin', 'msg', diffs={f_a: diff}), file_dict, file_diff_dict, Section('t')) diff = Diff(file_dict[f_b]) diff.change_line(3, '3\n', '3_changed\n') uut.apply(Result('origin', 'msg', diffs={f_b: diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].modified self.assertEqual(file_dict, expected_file_dict) with open(f_a) as fa: self.assertEqual(file_dict[f_a], fa.readlines()) with open(f_b) as fb: self.assertEqual(file_dict[f_b], fb.readlines()) with open(f_c) as fc: # File c is unchanged and should be untouched self.assertEqual([], fc.readlines())
def test_apply(self): uut = ApplyPatchAction() with make_temp() as f_a, make_temp() as f_b, make_temp() as f_c: file_dict = { f_a: ['1\n', '2\n', '3\n'], f_b: ['1\n', '2\n', '3\n'], f_c: ['1\n', '2\n', '3\n'] } expected_file_dict = { f_a: ['1\n', '3_changed\n'], f_b: ['1\n', '2\n', '3_changed\n'], f_c: ['1\n', '2\n', '3\n'] } file_diff_dict = {} diff = Diff(file_dict[f_a]) diff.delete_line(2) uut.apply_from_section(Result('origin', 'msg', diffs={f_a: diff}), file_dict, file_diff_dict, Section('t')) diff = Diff(file_dict[f_a]) diff.change_line(3, '3\n', '3_changed\n') uut.apply_from_section(Result('origin', 'msg', diffs={f_a: diff}), file_dict, file_diff_dict, Section('t')) diff = Diff(file_dict[f_b]) diff.change_line(3, '3\n', '3_changed\n') uut.apply(Result('origin', 'msg', diffs={f_b: diff}), file_dict, file_diff_dict) for filename in file_diff_dict: file_dict[filename] = file_diff_dict[filename].modified self.assertEqual(file_dict, expected_file_dict) with open(f_a) as fa: self.assertEqual(file_dict[f_a], fa.readlines()) with open(f_b) as fb: self.assertEqual(file_dict[f_b], fb.readlines()) with open(f_c) as fc: # File c is unchanged and should be untouched self.assertEqual([], fc.readlines())
def test_json_diff(self): file_dict = {"f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"]} expected_file = {"f_a": ["1", "3_changed"], "f_b": ["1", "2", "3"]} diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = Result("origin", "msg", diffs={"f_a": diff}).__json__(True) self.assertEqual( uut["diffs"]['f_a'].__json__(), "--- \n" "+++ \n" "@@ -1,3 +1,2 @@\n" " 1-2-3+3_changed") JSONEncoder = create_json_encoder(use_relpath=True) json_dump = json.dumps(diff, cls=JSONEncoder, sort_keys=True) self.assertEqual(json_dump, '"--- \\n+++ \\n@@ -1,3 +1,2 @@\\n 1-2-3+3_changed"')
def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 0) as generator, \ retrieve_stdout() as sio: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply( self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1) self.assertIn(ApplyPatchAction.success_message, sio.getvalue())
def test_acquire_actions_and_apply(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 0) as generator: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) acquire_actions_and_apply(self.console_printer, self.log_printer, Section(""), self.file_diff_dict, Result("origin", "message", diffs={ testfile_path: diff}), file_dict) self.assertEqual(generator.last_input, 1)
def test_json_diff(self): file_dict = { 'f_a': ['1', '2', '3'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, '3', '3_changed') uut = Result('origin', 'msg', diffs={'f_a': diff}).__json__(True) self.assertEqual(uut['diffs']['f_a'].__json__(), '--- \n' '+++ \n' '@@ -1,3 +1,2 @@\n' ' 1-2-3+3_changed') JSONEncoder = create_json_encoder(use_relpath=True) json_dump = json.dumps(diff, cls=JSONEncoder, sort_keys=True) self.assertEqual( json_dump, '"--- \\n+++ \\n@@ -1,3 +1,2 @@\\n 1-2-3+3_changed"')
def test_apply(self): file_dict = { 'f_a': ['1', '2', '3'], 'f_b': ['1', '2', '3'] } expected_file_dict = { 'f_a': ['1', '3_changed'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, '3', '3_changed') uut = Result('origin', 'msg', diffs={'f_a': diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict)
def test_json_diff(self): file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"] } diff = Diff(file_dict['f_a']) diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = Result("origin", "msg", diffs={"f_a": diff}).__json__(True) self.assertEqual(uut["diffs"]['f_a'].__json__(), "--- \n" "+++ \n" "@@ -1,3 +1,2 @@\n" " 1-2-3+3_changed") JSONEncoder = create_json_encoder(use_relpath=True) json_dump = json.dumps(diff, cls=JSONEncoder, sort_keys=True) self.assertEqual( json_dump, '"--- \\n+++ \\n@@ -1,3 +1,2 @@\\n 1-2-3+3_changed"')
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ["1", "2", "2"] other = Diff(self.file) other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file)
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) file = ["1", "1", "3", "4"] result_file = ["1", "2", "2"] other = Diff() other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") self.uut += other self.assertEqual(self.uut.apply(file), result_file)
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ['1\n', '2\n', '2'] other = Diff(self.file) other.delete_line(1) other.modify_line(2, '2') other.add_lines(0, ['1']) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.modify_line(4, '2') result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file)
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ["1", "2", "2"] other = Diff(self.file) other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file)
def generate_diff(comments, file, filename, line, line_number, pos): todo_source_range = SourceRange.from_values(filename, line_number, pos + 1) affected_comment_sourcerange = [ c for c in comments if todo_source_range in c] affected_len = len(affected_comment_sourcerange) if affected_len == 0: return {} assert affected_len == 1, 'More than 1 affected comment source ranges' comment_sourcerange = affected_comment_sourcerange[0] comment_start = comment_sourcerange.start.column comment_end = comment_sourcerange.end.column in_multi_line_comment = ( comment_sourcerange.start.line != comment_sourcerange.end.line ) line_before_todo_comment = line[:comment_start - 1].rstrip() line_behind_todo_comment = line[comment_end:].rstrip() line_replacement = line_before_todo_comment + line_behind_todo_comment diff = Diff(file) if line_replacement and not in_multi_line_comment: diff.change_line( line_number, line, line_replacement + '\n') elif line_replacement and in_multi_line_comment: text_replacement = line[pos:] diff.change_line( line_number, line, line.replace(text_replacement, '').rstrip() + '\n') else: diff.delete_line(line_number) return {filename: diff}
def test_multiline_compound_imports(self): file_text = ['from __future__ import nested_scopes, \\\n', ' generators;' 'from __future__ import absolute_import;' 'x = 2\n'] diff = Diff(file_text) diff.modify_line(2, 'x = 2\n') diff.delete_line(1) self.check_results( self.uut, file_text, [Result.from_values('NoFutureImportBear', 'Future import(s) found', file=self.filename, line=1, diffs={self.filename: diff}, end_line=1)], filename=self.filename)
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ['1\n', '2\n', '2'] other = Diff(self.file) other.delete_line(1) other.modify_line(2, '2') other.add_lines(0, ['1']) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.modify_line(4, '2') result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file)
def test_apply(self): file_dict = {"f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"]} expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3"] } diff = Diff() diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = PatchResult("origin", "msg", {"f_a": diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict) uut = PatchResult("origin", "msg", {}) for action in uut.get_actions(): action.apply( uut, {}, {}) # All those actions should be able to apply this result self.assertEqual(len(uut.get_actions()), 1)
def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) file = ["1", "1", "3", "4"] result_file = ["1", "2", "2"] other = Diff() other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") self.uut += other self.assertEqual(self.uut.apply(file), result_file)
def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ["1\n", "2\n", "3\n"]} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1, 2, 3) as generator, \ retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_results_no_input( self.log_printer, Section("someSection"), [Result("origin", "message", diffs={testfile_path: diff})], file_dict, self.file_diff_dict, color=False) self.assertEqual(generator.last_input, -1) self.assertEqual( stdout.getvalue(), """ Project wide: | | [NORMAL] origin: | | {}\n""".format(highlight_text("message", style=BackgroundMessageStyle)))
def test_apply(self): file_dict = { "f_a": ["1", "2", "3"], "f_b": ["1", "2", "3"] } expected_file_dict = { "f_a": ["1", "3_changed"], "f_b": ["1", "2", "3"] } diff = Diff() diff.delete_line(2) diff.change_line(3, "3", "3_changed") uut = PatchResult("origin", "msg", {"f_a": diff}) uut.apply(file_dict) self.assertEqual(file_dict, expected_file_dict) uut = PatchResult("origin", "msg", {}) for action in uut.get_actions(): action.apply(uut, {}, {}) # All those actions should be able to apply this result self.assertEqual(len(uut.get_actions()), 1)
def test_print_result_no_input(self): with make_temp() as testfile_path: file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') with simulate_console_inputs(1, 2, 3) as generator, \ retrieve_stdout() as stdout: ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_results_no_input(self.log_printer, Section('someSection'), [Result('origin', 'message', diffs={ testfile_path: diff})], file_dict, self.file_diff_dict, self.console_printer) self.assertEqual(generator.last_input, -1) self.assertEqual(stdout.getvalue(), """ Project wide: | | [NORMAL] origin: | | {}\n""".format(highlight_text(self.no_color, 'message', style=BackgroundMessageStyle)))
def test_apply(self): uut = ShowAppliedPatchesAction() with make_temp() as f_a, make_temp() as f_b, make_temp() as f_c: file_dict = { f_a: ['1\n', '2\n', '3\n'], f_b: ['1\n', '2\n', '3\n'], f_c: ['1\n', '2\n', '3\n'] } expected_file_dict = { f_a: ['1\n', '3_changed\n'], f_b: ['1\n', '2\n', '3_changed\n'], f_c: ['1\n', '2\n', '3\n'] } with make_temp() as testfile_path: file_diff_dict = {} file_dict = {testfile_path: ['1\n', '2\n', '3\n']} diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') result = Result('origin', 'msg', diffs={f_a: diff}, applied_actions={ 'ApplyPatchAction': [ Result('origin', 'message', diffs={testfile_path: diff}), file_dict, file_diff_dict, Section('') ] }) self.assertTrue(uut.apply(result, file_dict, file_diff_dict))
def test_print_result(self): print_result(self.console_printer, self.log_printer, None, self.file_diff_dict, "illegal value", {}) with simulate_console_inputs(0): print_result(self.console_printer, self.log_printer, self.section, self.file_diff_dict, Result("origin", "msg", diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ["1\n", "2\n", "3\n"], "f_b": ["1", "2", "3"] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs("INVALID", -1, 1, 0, 3) as input_generator: curr_section = Section("") print_section_beginning(self.console_printer, curr_section) print_result( self.console_printer, self.log_printer, curr_section, self.file_diff_dict, Result("origin", "msg", diffs={testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ["1\n", "3_changed\n"]) os.remove(testfile_path + ".orig") name, section = get_action_info(curr_section, TestAction().get_metadata(), failed_actions=set()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : '3'}") self.assertEqual(name, "TestAction") # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs(1, "test_editor", 0, 1, 0) as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result("origin", "msg", diffs={testfile_path: diff}) patch_result.file = "f_b" print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4)
class DiffTest(unittest.TestCase): def setUp(self): self.file = ["1", "2", "3", "4"] self.uut = Diff(self.file) def test_add_lines(self): self.uut.add_lines(0, []) self.uut.add_lines(0, ["t"]) self.uut.add_lines(0, []) # No double addition allowed self.assertRaises(ConflictError, self.uut.add_lines, 0, ["t"]) self.assertRaises(ValueError, self.uut.add_lines, -1, ["t"]) self.assertRaises(TypeError, self.uut.add_lines, "str", ["t"]) def test_delete_line(self): self.uut.delete_line(1) self.uut.delete_line(1) # Double deletion possible without conflict self.assertRaises(ValueError, self.uut.delete_line, 0) def test_change_line(self): self.assertEqual(len(self.uut), 0) self.uut.change_line(2, "1", "2") self.assertEqual(len(self.uut), 1) self.assertRaises(ConflictError, self.uut.change_line, 2, "1", "3") self.assertRaises(ValueError, self.uut.change_line, 0, "1", "2") self.uut.delete_line(1) # Line was deleted, unchangeable self.assertRaises(AssertionError, self.uut.change_line, 1, "1", "2") def test_affected_code(self): self.assertEqual(self.uut.affected_code("file"), []) self.uut.add_lines(0, ["test"]) affected_code = [ SourceRange.from_values("file", start_line=1)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(2) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(3) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2, end_line=3)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(6) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2, end_line=3), SourceRange.from_values('file', start_line=6)] self.assertEqual(self.uut.affected_code("file"), affected_code) def test_modified(self): result_file = ["0.1", "0.2", "1", "1.1", "3.changed", "4"] self.uut.delete_line(2) self.uut.add_lines(0, ["0.1", "0.2"]) self.uut.add_lines(1, ["1.1"]) self.uut.change_line(3, "3", "3.changed") self.assertEqual(self.uut.modified, result_file) self.assertEqual(self.uut.original, self.file) self.uut.delete_line(len(self.file)) del result_file[len(result_file) - 1] self.assertEqual(self.uut.modified, result_file) self.uut.delete_line(1) del result_file[2] self.assertEqual(self.uut.modified, result_file) def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ["1", "2", "2"] other = Diff(self.file) other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file) def test_from_string_arrays(self): a = ["q", "a", "b", "x", "c", "d"] b = ["a", "b", "y", "c", "d", "f"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "fourth"] b = ["first", "second", "third", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "fourth"] b = ["first_changed", "second", "third", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "second", "third", "fourth"] b = ["first", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "second", "third", "fourth"] b = ["first_changed", "second_changed", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) @skip_if_no_clang() def test_from_clang_fixit(self): joined_file = 'struct { int f0; }\nx = { f0 :1 };\n' file = joined_file.splitlines(True) fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n'] tu = Index.create().parse('t.c', unsaved_files=[ ('t.c', joined_file)]) fixit = tu.diagnostics[0].fixits[0] clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified self.assertEqual(fixed_file, clang_fixed_file) def test_equality(self): a = ["first", "second", "third"] b = ["first", "third"] diff_1 = Diff.from_string_arrays(a, b) a[1] = "else" diff_2 = Diff.from_string_arrays(a, b) self.assertEqual(diff_1, diff_2) diff_1.add_lines(1, ["1"]) self.assertNotEqual(diff_1, diff_2) def test_json_export(self): a = ["first\n", "second\n", "third\n"] b = ["first\n", "third\n"] diff = Diff.from_string_arrays(a, b) self.assertEqual( json.dumps(diff, cls=JSONEncoder, sort_keys=True), '"--- \\n' '+++ \\n' '@@ -1,3 +1,2 @@\\n' ' first\\n' '-second\\n' ' third\\n"')
def test_print_result(self): print_result(self.console_printer, None, self.file_diff_dict, 'illegal value', {}) with simulate_console_inputs(0): print_result(self.console_printer, self.section, self.file_diff_dict, Result('origin', 'msg', diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ['1\n', '2\n', '3\n'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs('INVALID', -1, 1, 0, 3) as input_generator: curr_section = Section('') print_section_beginning(self.console_printer, curr_section) print_result(self.console_printer, curr_section, self.file_diff_dict, Result('origin', 'msg', diffs={ testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ['1\n', '3_changed\n']) os.remove(testfile_path + '.orig') name, section = get_action_info(curr_section, TestAction().get_metadata(), failed_actions=set()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : '3'}") self.assertEqual(name, 'TestAction') # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs(1, 'test_editor', 0, 1, 0) as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result('origin', 'msg', diffs={testfile_path: diff}) patch_result.file = 'f_b' print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4)
def test_is_applicable(self): diff = Diff(['1\n', '2\n', '3\n']) diff.delete_line(2) patch_result = Result('', '', diffs={'f': diff}) self.assertTrue(ApplyPatchAction.is_applicable(patch_result, {}, {}))
def test_print_result(self): print_result(self.console_printer, None, self.file_diff_dict, 'illegal value', {}) with simulate_console_inputs('n'): print_result(self.console_printer, self.section, self.file_diff_dict, Result('origin', 'msg', diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ['1\n', '2\n', '3\n'], 'f_b': ['1', '2', '3'] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, '3\n', '3_changed\n') ApplyPatchAction.is_applicable = staticmethod(lambda *args: True) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs('INVALID', -1, 'a', 'n', 'm') as input_generator: curr_section = Section('') print_section_beginning(self.console_printer, curr_section) print_result( self.console_printer, curr_section, self.file_diff_dict, Result('origin', 'msg', diffs={testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ['1\n', '3_changed\n']) os.remove(testfile_path + '.orig') name, section = get_action_info(curr_section, TestAction().get_metadata(), failed_actions=set()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : 'm'}") self.assertEqual(name, 'TestAction') # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs('o', 'test_editor', 'n', 'o', 'n') as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result('origin', 'msg', diffs={testfile_path: diff}) patch_result.file = 'f_b' print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4)
def test_is_applicable(self): diff = Diff(["1\n", "2\n", "3\n"]) diff.delete_line(2) patch_result = Result("", "", diffs={'f': diff}) self.assertTrue( ApplyPatchAction.is_applicable(patch_result, {}, {}))
def test_is_applicable(self): diff = Diff(['1\n', '2\n', '3\n']) diff.delete_line(2) patch_result = Result('', '', diffs={'f': diff}) self.assertTrue( ApplyPatchAction.is_applicable(patch_result, {}, {}))
def test_is_applicable(self): diff = Diff(["1\n", "2\n", "3\n"]) diff.delete_line(2) patch_result = Result("", "", diffs={'f': diff}) self.assertTrue( ApplyPatchAction.is_applicable(patch_result, {}, {}))
class DiffTest(unittest.TestCase): def setUp(self): self.file = ['1', '2', '3', '4'] self.uut = Diff(self.file) def test_add_lines(self): self.uut.add_lines(0, []) self.uut.add_lines(0, ['t']) self.uut.add_lines(0, []) def test_add_line(self): self.uut.add_line(0, 't') self.assertRaises(ConflictError, self.uut.add_line, 0, 't') self.assertEqual(self.uut.modified, ['t\n', '1\n', '2\n', '3\n', '4']) def test_double_addition(self): self.uut.add_lines(0, ['t']) # No double addition allowed self.assertRaises(ConflictError, self.uut.add_lines, 0, ['t']) self.assertRaises(IndexError, self.uut.add_lines, -1, ['t']) self.assertRaises(TypeError, self.uut.add_lines, 'str', ['t']) def test_delete_line(self): self.uut.delete_line(1) self.uut.delete_line(1) # Double deletion possible without conflict additions, deletions = self.uut.stats() self.assertEqual(deletions, 1) self.assertRaises(IndexError, self.uut.delete_line, 0) self.assertRaises(IndexError, self.uut.delete_line, 10) def test_delete_lines(self): self.uut.delete_lines(1, 2) self.uut.delete_lines(2, 3) additions, deletions = self.uut.stats() self.assertEqual(deletions, 3) self.assertRaises(IndexError, self.uut.delete_lines, 0, 2) self.assertRaises(IndexError, self.uut.delete_lines, 1, 6) def test_change_line(self): self.assertEqual(len(self.uut), 0) self.uut.change_line(2, '1', '2') self.assertEqual(len(self.uut), 2) self.assertRaises(ConflictError, self.uut.change_line, 2, '1', '3') self.assertRaises(IndexError, self.uut.change_line, 0, '1', '2') self.uut.delete_line(1) # Line was deleted, unchangeable self.assertRaises(ConflictError, self.uut.change_line, 1, '1', '2') def test_capture_warnings(self): """ Since this addresses the deprecated method, this testcase is temporary (until the old API is fully removed). """ logger = logging.getLogger() with self.assertLogs(logger, 'DEBUG') as log: self.assertEqual(len(self.uut), 0) self.uut.change_line(2, '1', '2') self.assertEqual(log.output, [ 'DEBUG:root:Use of change_line method is deprecated. Instead ' 'use modify_line method, without the original_line argument']) def test_double_changes_with_same_diff(self): self.uut.modify_line(2, '2') # Double addition when diff is equal is allowed try: self.uut.modify_line(2, '2') except Exception: self.fail('We should not have a conflict on same diff!') def test_affected_code(self): self.assertEqual(self.uut.affected_code('file'), []) self.uut.add_lines(0, ['test']) affected_code = [ SourceRange.from_values('file', start_line=1)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(2) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(3) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2, end_line=3)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(4) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2, end_line=4)] self.assertEqual(self.uut.affected_code('file'), affected_code) def test_len(self): self.uut.delete_line(2) self.assertEqual(len(self.uut), 1) self.uut.add_lines(2, ['2.3', '2.5', '2.6']) self.assertEqual(len(self.uut), 4) self.uut.modify_line(1, '1.1') self.assertEqual(len(self.uut), 6) def test_stats(self): self.uut.delete_line(2) self.assertEqual(self.uut.stats(), (0, 1)) self.uut.add_lines(2, ['2.3', '2.5', '2.6']) self.assertEqual(self.uut.stats(), (3, 1)) self.uut.modify_line(1, '1.1') self.assertEqual(self.uut.stats(), (4, 2)) def test_modified(self): result_file = ['0.1\n', '0.2\n', '1\n', '1.1\n', '3.changed\n', '4'] self.uut.delete_line(2) self.uut.add_lines(0, ['0.1', '0.2']) self.uut.add_lines(1, ['1.1']) self.uut.modify_line(3, '3.changed') self.assertEqual(self.uut.modified, result_file) self.uut.delete_line(len(self.file)) del result_file[-1] result_file[-1] = result_file[-1].rstrip('\n') self.assertEqual(self.uut.modified, result_file) self.uut.delete_line(1) del result_file[2] self.assertEqual(self.uut.modified, result_file) def test_bool(self): self.assertFalse(self.uut) self.uut.add_line(4, '4') self.assertTrue(self.uut) self.uut.delete_line(4) self.assertFalse(self.uut) self.uut.modify_line(1, '1\n') self.assertFalse(self.uut) # test if it works with tuples. uutuple = Diff(('1', '2', '3', '4')) self.assertFalse(uutuple) uutuple.add_line(4, '4') self.assertTrue(uutuple) uutuple.delete_line(4) self.assertFalse(uutuple) uutuple.modify_line(1, '1\n') self.assertFalse(uutuple) def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ['1\n', '2\n', '2'] other = Diff(self.file) other.delete_line(1) other.modify_line(2, '2') other.add_lines(0, ['1']) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.modify_line(4, '2') result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file) def test_addition_rename(self): uut = Diff(self.file, rename=False) other = Diff(self.file, rename=False) self.assertEqual((other + uut).rename, False) other.rename = 'some.py' self.assertEqual((other + uut).rename, 'some.py') uut.rename = 'some.py' self.assertEqual((other + uut).rename, 'some.py') uut.rename = 'other.py' self.assertRaises(ConflictError, other.__add__, uut) def test_from_string_arrays(self): a = ['q\n', 'a\n', 'b\n', 'x\n', 'c\n', 'd\n'] b = ['a\n', 'b\n', 'y\n', 'c\n', 'd\n', 'f\n'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first\n', 'fourth\n'] b = ['first\n', 'second\n', 'third\n', 'fourth\n'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first\n', 'fourth\n'] b = ['first_changed\n', 'second\n', 'third\n', 'fourth\n'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first\n', 'second\n', 'third\n', 'fourth\n'] b = ['first\n', 'fourth\n'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first\n', 'second\n', 'third\n', 'fourth\n'] b = ['first_changed\n', 'second_changed\n', 'fourth\n'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) 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_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_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_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_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_diff_multiple_modifications(self): source = ['first\n', 'second'] target = ['first_changed\n', 'second_changed'] diff = ['--- a/testfile', '+++ b/testfile', '@@ -1,2 +1,2 @@', '-first', '-second', '+first_changed', '+second_changed'] 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_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_incomplete_hunks_multiple_additions(self): source = ['A\n', 'C\n', 'D\n', 'E\n', 'G'] target = ['A\n', 'B\n', 'C\n', 'D\n', 'E\n', 'F\n', '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_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_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_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(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_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_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_clang_fixit(self): # try: # from clang.cindex import Index, LibclangError # except ImportError as err: # raise unittest.case.SkipTest(str(err)) # # joined_file = 'struct { int f0; }\nx = { f0 :1 };\n' # file = joined_file.splitlines(True) # fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n'] # try: # tu = Index.create().parse('t.c', unsaved_files=[ # ('t.c', joined_file)]) # except LibclangError as err: # raise unittest.case.SkipTest(str(err)) # # fixit = tu.diagnostics[0].fixits[0] # clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified # self.assertEqual(fixed_file, clang_fixed_file) def test_equality(self): a = ['first', 'second', 'third'] b = ['first', 'third'] diff_1 = Diff.from_string_arrays(a, b) c = ['first', 'second', 'third'] d = ['first', 'third'] diff_2 = Diff.from_string_arrays(c, d) self.assertEqual(diff_1, diff_2) # changing the original array should not influence # the diff a[1] = 'else' self.assertEqual(diff_1, diff_2) diff_1.rename = 'abcd' self.assertNotEqual(diff_1, diff_2) diff_1.rename = False diff_1.delete = True self.assertNotEqual(diff_1, diff_2) diff_1.delete = False diff_1.add_lines(1, ['1']) self.assertNotEqual(diff_1, diff_2) def test_json_export(self): JSONEncoder = create_json_encoder() a = ['first\n', 'second\n', 'third\n'] b = ['first\n', 'third\n'] diff = Diff.from_string_arrays(a, b) self.assertEqual( json.dumps(diff, cls=JSONEncoder, sort_keys=True), '"--- \\n' '+++ \\n' '@@ -1,3 +1,2 @@\\n' ' first\\n' '-second\\n' ' third\\n"') def test_rename(self): self.uut.rename = False self.uut.rename = '1234' with self.assertRaises(TypeError): self.uut.rename = True with self.assertRaises(TypeError): self.uut.rename = 1234 def test_delete(self): self.uut.delete = True self.uut.delete = False # Double deletion is allowed self.uut.delete = False with self.assertRaises(TypeError): self.uut.delete = 'abcd' # If delete is True then modified returns an empty list self.uut.delete = True self.assertEqual(self.uut.modified, []) self.uut.delete = False def test_add_linebreaks(self): expected = ['1\n', '2\n', '3\n'] self.assertEqual( Diff._add_linebreaks(['1', '2', '3']), expected) self.assertEqual( Diff._add_linebreaks(['1', '2\n', '3']), expected) self.assertEqual( Diff._add_linebreaks(expected), expected) self.assertEqual(Diff._add_linebreaks([]), []) def test_generate_linebreaks(self): eof_ln = ['1\n', '2\n', '3\n'] no_eof_ln = ['1\n', '2\n', '3'] self.assertEqual( Diff._generate_linebreaks(['1', '2', '3']), no_eof_ln) self.assertEqual( Diff._generate_linebreaks(['1', '2', '3\n']), eof_ln) self.assertEqual( Diff._generate_linebreaks(['1', '2\n', '3']), no_eof_ln) self.assertEqual( Diff._generate_linebreaks(no_eof_ln), no_eof_ln) self.assertEqual( Diff._generate_linebreaks(eof_ln), eof_ln) self.assertEqual(Diff._generate_linebreaks([]), [])
def test_print_result(self): print_result(self.console_printer, self.log_printer, None, self.file_diff_dict, "illegal value", {}) with simulate_console_inputs(0): print_result(self.console_printer, self.log_printer, None, self.file_diff_dict, Result("origin", "msg", diffs={}), {}) with make_temp() as testfile_path: file_dict = { testfile_path: ["1\n", "2\n", "3\n"], "f_b": ["1", "2", "3"] } diff = Diff(file_dict[testfile_path]) diff.delete_line(2) diff.change_line(3, "3\n", "3_changed\n") with simulate_console_inputs(1), self.assertRaises(ValueError): ApplyPatchAction.is_applicable = staticmethod( lambda *args: True) print_result(self.console_printer, self.log_printer, None, self.file_diff_dict, Result("origin", "msg", diffs={ testfile_path: diff}), file_dict) # Interaction must be closed by the user with `0` if it's not a # param with simulate_console_inputs("INVALID", -1, 1, 0, 3) as input_generator: curr_section = Section("") print_section_beginning(self.console_printer, curr_section) print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, Result("origin", "msg", diffs={ testfile_path: diff}), file_dict) self.assertEqual(input_generator.last_input, 3) self.file_diff_dict.clear() with open(testfile_path) as f: self.assertEqual(f.readlines(), ["1\n", "3_changed\n"]) os.remove(testfile_path + ".orig") name, section = get_action_info(curr_section, TestAction().get_metadata()) self.assertEqual(input_generator.last_input, 4) self.assertEqual(str(section), " {param : '3'}") self.assertEqual(name, "TestAction") # Check if the user is asked for the parameter only the first time. # Use OpenEditorAction that needs this parameter (editor command). with simulate_console_inputs(1, "test_editor", 0, 1, 0) as generator: OpenEditorAction.is_applicable = staticmethod(lambda *args: True) patch_result = Result("origin", "msg", diffs={testfile_path: diff}) patch_result.file = "f_b" print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) # choose action, choose editor, choose no action (-1 -> 2) self.assertEqual(generator.last_input, 2) # It shoudn't ask for parameter again print_result(self.console_printer, self.log_printer, curr_section, self.file_diff_dict, patch_result, file_dict) self.assertEqual(generator.last_input, 4)
class DiffTest(unittest.TestCase): def setUp(self): self.file = ["1", "2", "3", "4"] self.uut = Diff(self.file) def test_add_lines(self): self.uut.add_lines(0, []) self.uut.add_lines(0, ["t"]) self.uut.add_lines(0, []) # No double addition allowed self.assertRaises(ConflictError, self.uut.add_lines, 0, ["t"]) self.assertRaises(ValueError, self.uut.add_lines, -1, ["t"]) self.assertRaises(TypeError, self.uut.add_lines, "str", ["t"]) def test_delete_line(self): self.uut.delete_line(1) self.uut.delete_line(1) # Double deletion possible without conflict self.assertRaises(ValueError, self.uut.delete_line, 0) def test_change_line(self): self.assertEqual(len(self.uut), 0) self.uut.change_line(2, "1", "2") self.assertEqual(len(self.uut), 2) self.assertRaises(ConflictError, self.uut.change_line, 2, "1", "3") self.assertRaises(ValueError, self.uut.change_line, 0, "1", "2") self.uut.delete_line(1) # Line was deleted, unchangeable self.assertRaises(ConflictError, self.uut.change_line, 1, "1", "2") def test_affected_code(self): self.assertEqual(self.uut.affected_code("file"), []) self.uut.add_lines(0, ["test"]) affected_code = [ SourceRange.from_values("file", start_line=1)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(2) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(3) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2, end_line=3)] self.assertEqual(self.uut.affected_code("file"), affected_code) self.uut.delete_line(6) affected_code = [ SourceRange.from_values("file", start_line=1), SourceRange.from_values("file", start_line=2, end_line=3), SourceRange.from_values('file', start_line=6)] self.assertEqual(self.uut.affected_code("file"), affected_code) def test_len(self): self.uut.delete_line(2) self.assertEqual(len(self.uut), 1) self.uut.add_lines(2, ["2.3", "2.5", "2.6"]) self.assertEqual(len(self.uut), 4) self.uut.change_line(1, "1", "1.1") self.assertEqual(len(self.uut), 6) def test_stats(self): self.uut.delete_line(2) self.assertEqual(self.uut.stats(), (0, 1)) self.uut.add_lines(2, ["2.3", "2.5", "2.6"]) self.assertEqual(self.uut.stats(), (3, 1)) self.uut.change_line(1, "1", "1.1") self.assertEqual(self.uut.stats(), (4, 2)) def test_modified(self): result_file = ["0.1", "0.2", "1", "1.1", "3.changed", "4"] self.uut.delete_line(2) self.uut.add_lines(0, ["0.1", "0.2"]) self.uut.add_lines(1, ["1.1"]) self.uut.change_line(3, "3", "3.changed") self.assertEqual(self.uut.modified, result_file) self.assertEqual(self.uut.original, self.file) self.uut.delete_line(len(self.file)) del result_file[len(result_file) - 1] self.assertEqual(self.uut.modified, result_file) self.uut.delete_line(1) del result_file[2] self.assertEqual(self.uut.modified, result_file) def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ["1", "2", "2"] other = Diff(self.file) other.delete_line(1) other.change_line(2, "1", "2") other.add_lines(0, ["1"]) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, "4", "2") result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file) def test_addition_rename(self): uut = Diff(self.file, rename=False) other = Diff(self.file, rename=False) self.assertEqual((other + uut).rename, False) other.rename = "some.py" self.assertEqual((other + uut).rename, "some.py") uut.rename = "some.py" self.assertEqual((other + uut).rename, "some.py") uut.rename = "other.py" self.assertRaises(ConflictError, other.__add__, uut) def test_from_string_arrays(self): a = ["q", "a", "b", "x", "c", "d"] b = ["a", "b", "y", "c", "d", "f"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "fourth"] b = ["first", "second", "third", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "fourth"] b = ["first_changed", "second", "third", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "second", "third", "fourth"] b = ["first", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ["first", "second", "third", "fourth"] b = ["first_changed", "second_changed", "fourth"] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) def test_from_clang_fixit(self): try: from clang.cindex import Index, LibclangError except ImportError as err: raise SkipTest(str(err)) joined_file = 'struct { int f0; }\nx = { f0 :1 };\n' file = joined_file.splitlines(True) fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n'] try: tu = Index.create().parse('t.c', unsaved_files=[ ('t.c', joined_file)]) except LibclangError as err: raise SkipTest(str(err)) fixit = tu.diagnostics[0].fixits[0] clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified self.assertEqual(fixed_file, clang_fixed_file) def test_equality(self): a = ["first", "second", "third"] b = ["first", "third"] diff_1 = Diff.from_string_arrays(a, b) a[1] = "else" diff_2 = Diff.from_string_arrays(a, b) self.assertEqual(diff_1, diff_2) diff_1.rename = "abcd" self.assertNotEqual(diff_1, diff_2) diff_1.rename = False diff_1.delete = True self.assertNotEqual(diff_1, diff_2) diff_1.delete = False diff_1.add_lines(1, ["1"]) self.assertNotEqual(diff_1, diff_2) def test_json_export(self): JSONEncoder = create_json_encoder() a = ["first\n", "second\n", "third\n"] b = ["first\n", "third\n"] diff = Diff.from_string_arrays(a, b) self.assertEqual( json.dumps(diff, cls=JSONEncoder, sort_keys=True), '"--- \\n' '+++ \\n' '@@ -1,3 +1,2 @@\\n' ' first\\n' '-second\\n' ' third\\n"') def test_rename(self): self.uut.rename = False self.uut.rename = "1234" with self.assertRaises(TypeError): self.uut.rename = True with self.assertRaises(TypeError): self.uut.rename = 1234 def test_delete(self): self.uut.delete = True self.uut.delete = False # Double deletion is allowed self.uut.delete = False with self.assertRaises(TypeError): self.uut.delete = "abcd" # If delete is True then modified returns an empty list self.uut.delete = True self.assertEqual(self.uut.modified, []) self.uut.delete = False
class DiffTest(unittest.TestCase): def setUp(self): self.file = ['1', '2', '3', '4'] self.uut = Diff(self.file) def test_add_lines(self): self.uut.add_lines(0, []) self.uut.add_lines(0, ['t']) self.uut.add_lines(0, []) def test_add_line(self): self.uut.add_line(0, 't') self.assertRaises(ConflictError, self.uut.add_line, 0, 't') self.assertEqual(self.uut.modified, ['t', '1', '2', '3', '4']) def test_double_addition(self): self.uut.add_lines(0, ['t']) # No double addition allowed self.assertRaises(ConflictError, self.uut.add_lines, 0, ['t']) self.assertRaises(ValueError, self.uut.add_lines, -1, ['t']) self.assertRaises(TypeError, self.uut.add_lines, 'str', ['t']) def test_delete_line(self): self.uut.delete_line(1) self.uut.delete_line(1) # Double deletion possible without conflict additions, deletions = self.uut.stats() self.assertEqual(deletions, 1) self.assertRaises(ValueError, self.uut.delete_line, 0) def test_delete_lines(self): self.uut.delete_lines(1, 10) self.uut.delete_lines(10, 20) additions, deletions = self.uut.stats() self.assertEqual(deletions, 20) self.assertRaises(ValueError, self.uut.delete_lines, 0, 10) def test_change_line(self): self.assertEqual(len(self.uut), 0) self.uut.change_line(2, '1', '2') self.assertEqual(len(self.uut), 2) self.assertRaises(ConflictError, self.uut.change_line, 2, '1', '3') self.assertRaises(ValueError, self.uut.change_line, 0, '1', '2') self.uut.delete_line(1) # Line was deleted, unchangeable self.assertRaises(ConflictError, self.uut.change_line, 1, '1', '2') def test_capture_warnings(self): """ Since this addresses the deprecated method, this testcase is temporary (until the old API is fully removed). """ logger = logging.getLogger() with self.assertLogs(logger, 'DEBUG') as log: self.assertEqual(len(self.uut), 0) self.uut.change_line(2, '1', '2') self.assertEqual(log.output, [ 'DEBUG:root:Use of change_line method is deprecated. Instead ' 'use modify_line method, without the original_line argument']) def test_double_changes_with_same_diff(self): self.uut.change_line(2, '1', '2') # Double addition when diff is equal is allowed try: self.uut.change_line(2, '1', '2') except Exception: self.fail('We should not have a conflict on same diff!') def test_affected_code(self): self.assertEqual(self.uut.affected_code('file'), []) self.uut.add_lines(0, ['test']) affected_code = [ SourceRange.from_values('file', start_line=1)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(2) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(3) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2, end_line=3)] self.assertEqual(self.uut.affected_code('file'), affected_code) self.uut.delete_line(6) affected_code = [ SourceRange.from_values('file', start_line=1), SourceRange.from_values('file', start_line=2, end_line=3), SourceRange.from_values('file', start_line=6)] self.assertEqual(self.uut.affected_code('file'), affected_code) def test_len(self): self.uut.delete_line(2) self.assertEqual(len(self.uut), 1) self.uut.add_lines(2, ['2.3', '2.5', '2.6']) self.assertEqual(len(self.uut), 4) self.uut.change_line(1, '1', '1.1') self.assertEqual(len(self.uut), 6) def test_stats(self): self.uut.delete_line(2) self.assertEqual(self.uut.stats(), (0, 1)) self.uut.add_lines(2, ['2.3', '2.5', '2.6']) self.assertEqual(self.uut.stats(), (3, 1)) self.uut.change_line(1, '1', '1.1') self.assertEqual(self.uut.stats(), (4, 2)) def test_modified(self): result_file = ['0.1', '0.2', '1', '1.1', '3.changed', '4'] self.uut.delete_line(2) self.uut.add_lines(0, ['0.1', '0.2']) self.uut.add_lines(1, ['1.1']) self.uut.change_line(3, '3', '3.changed') self.assertEqual(self.uut.modified, result_file) self.assertEqual(self.uut.original, self.file) self.uut.delete_line(len(self.file)) del result_file[len(result_file) - 1] self.assertEqual(self.uut.modified, result_file) self.uut.delete_line(1) del result_file[2] self.assertEqual(self.uut.modified, result_file) def test_addition(self): self.assertRaises(TypeError, self.uut.__add__, 5) result_file = ['1', '2', '2'] other = Diff(self.file) other.delete_line(1) other.change_line(2, '1', '2') other.add_lines(0, ['1']) self.uut.delete_line(1) self.uut.delete_line(3) self.uut.change_line(4, '4', '2') result = self.uut + other self.assertEqual(result.modified, result_file) # Make sure it didn't happen in place! self.assertNotEqual(self.uut.modified, result_file) def test_addition_rename(self): uut = Diff(self.file, rename=False) other = Diff(self.file, rename=False) self.assertEqual((other + uut).rename, False) other.rename = 'some.py' self.assertEqual((other + uut).rename, 'some.py') uut.rename = 'some.py' self.assertEqual((other + uut).rename, 'some.py') uut.rename = 'other.py' self.assertRaises(ConflictError, other.__add__, uut) def test_from_string_arrays(self): a = ['q', 'a', 'b', 'x', 'c', 'd'] b = ['a', 'b', 'y', 'c', 'd', 'f'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first', 'fourth'] b = ['first', 'second', 'third', 'fourth'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first', 'fourth'] b = ['first_changed', 'second', 'third', 'fourth'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first', 'second', 'third', 'fourth'] b = ['first', 'fourth'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) a = ['first', 'second', 'third', 'fourth'] b = ['first_changed', 'second_changed', 'fourth'] self.uut = Diff.from_string_arrays(a, b) self.assertEqual(self.uut.modified, b) def test_from_clang_fixit(self): try: from clang.cindex import Index, LibclangError except ImportError as err: raise SkipTest(str(err)) joined_file = 'struct { int f0; }\nx = { f0 :1 };\n' file = joined_file.splitlines(True) fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n'] try: tu = Index.create().parse('t.c', unsaved_files=[ ('t.c', joined_file)]) except LibclangError as err: raise SkipTest(str(err)) fixit = tu.diagnostics[0].fixits[0] clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified self.assertEqual(fixed_file, clang_fixed_file) def test_equality(self): a = ['first', 'second', 'third'] b = ['first', 'third'] diff_1 = Diff.from_string_arrays(a, b) a[1] = 'else' diff_2 = Diff.from_string_arrays(a, b) self.assertEqual(diff_1, diff_2) diff_1.rename = 'abcd' self.assertNotEqual(diff_1, diff_2) diff_1.rename = False diff_1.delete = True self.assertNotEqual(diff_1, diff_2) diff_1.delete = False diff_1.add_lines(1, ['1']) self.assertNotEqual(diff_1, diff_2) def test_json_export(self): JSONEncoder = create_json_encoder() a = ['first\n', 'second\n', 'third\n'] b = ['first\n', 'third\n'] diff = Diff.from_string_arrays(a, b) self.assertEqual( json.dumps(diff, cls=JSONEncoder, sort_keys=True), '"--- \\n' '+++ \\n' '@@ -1,3 +1,2 @@\\n' ' first\\n' '-second\\n' ' third\\n"') def test_rename(self): self.uut.rename = False self.uut.rename = '1234' with self.assertRaises(TypeError): self.uut.rename = True with self.assertRaises(TypeError): self.uut.rename = 1234 def test_delete(self): self.uut.delete = True self.uut.delete = False # Double deletion is allowed self.uut.delete = False with self.assertRaises(TypeError): self.uut.delete = 'abcd' # If delete is True then modified returns an empty list self.uut.delete = True self.assertEqual(self.uut.modified, []) self.uut.delete = False