Пример #1
0
    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)
Пример #2
0
    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
Пример #3
0
    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)
Пример #4
0
    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)
Пример #5
0
    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))
Пример #7
0
    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)))
Пример #8
0
    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
Пример #9
0
    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
""",
                )
Пример #10
0
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}
Пример #11
0
    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)
Пример #12
0
    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)
Пример #13
0
    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
Пример #14
0
    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)
Пример #15
0
    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)
Пример #16
0
    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
Пример #17
0
    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
Пример #18
0
    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
Пример #19
0
    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)
Пример #20
0
    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)
Пример #21
0
    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)
Пример #22
0
 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"')
Пример #23
0
    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)
Пример #24
0
    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())
Пример #25
0
    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())
Пример #26
0
 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())
Пример #28
0
 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)
Пример #29
0
 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"')
Пример #30
0
    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)
Пример #31
0
 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"')
Пример #32
0
    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)
Пример #33
0
    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)
Пример #34
0
    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)
Пример #35
0
    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)
Пример #36
0
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)
Пример #38
0
    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)
Пример #39
0
    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)
Пример #40
0
    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)
Пример #41
0
    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)))
Пример #42
0
    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)
Пример #43
0
    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))
Пример #45
0
    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)
Пример #46
0
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"')
Пример #47
0
    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)
Пример #48
0
 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, {}, {}))
Пример #49
0
    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)
Пример #50
0
 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, {}, {}))
Пример #51
0
 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, {}, {}))
Пример #52
0
 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, {}, {}))
Пример #53
0
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([]), [])
Пример #54
0
    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)
Пример #55
0
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
Пример #56
0
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