Пример #1
0
 def test_merge_poem(self):
     """Test case from diff3 manual"""
     m3 = merge3.Merge3(TZU, LAO, TAO)
     ml = list(m3.merge_lines('LAO', 'TAO'))
     self.log('merge result:')
     self.log(''.join(ml))
     self.assertEqual(ml, MERGED_RESULT)
Пример #2
0
    def test_null_insert(self):
        m3 = merge3.Merge3([], ['aaa', 'bbb'], [])
        # todo: should use a sentinal at end as from get_matching_blocks
        # to match without zz
        self.assertEqual(list(m3.find_sync_regions()), [(0, 0, 2, 2, 0, 0)])

        self.assertEqual(list(m3.merge_regions()), [('a', 0, 2)])

        self.assertEqual(list(m3.merge_lines()), ['aaa', 'bbb'])
Пример #3
0
    def test_insert_agreement(self):
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'], ['aaa\n', '222\n', 'bbb\n'],
                           ['aaa\n', '222\n', 'bbb\n'])

        ml = m3.merge_lines(name_a='a',
                            name_b='b',
                            start_marker='<<',
                            mid_marker='--',
                            end_marker='>>')
        self.assertEqual(''.join(ml), 'aaa\n222\nbbb\n')
Пример #4
0
 def test_reprocess_and_base(self):
     """Reprocessing and showing base breaks correctly"""
     base_text = ("a\n" * 20).splitlines(True)
     this_text = ("a\n" * 10 + "b\n" * 10).splitlines(True)
     other_text = ("a\n" * 10 + "c\n" + "b\n" * 8 + "c\n").splitlines(True)
     m3 = merge3.Merge3(base_text, other_text, this_text)
     m_lines = m3.merge_lines('OTHER',
                              'THIS',
                              reprocess=True,
                              base_marker='|||||||')
     self.assertRaises(CantReprocessAndShowBase, list, m_lines)
Пример #5
0
 def test_mac_text(self):
     base_text = 'a\r'
     this_text = 'b\r'
     other_text = 'c\r'
     m3 = merge3.Merge3(base_text.splitlines(True),
                        other_text.splitlines(True),
                        this_text.splitlines(True))
     m_lines = m3.merge_lines('OTHER', 'THIS')
     self.assertEqual(
         '<<<<<<< OTHER\rc\r=======\rb\r'
         '>>>>>>> THIS\r'.splitlines(True), list(m_lines))
Пример #6
0
 def test_minimal_conflicts_common(self):
     """Reprocessing"""
     base_text = ("a\n" * 20).splitlines(True)
     this_text = ("a\n" * 10 + "b\n" * 10).splitlines(True)
     other_text = ("a\n" * 10 + "c\n" + "b\n" * 8 + "c\n").splitlines(True)
     m3 = merge3.Merge3(base_text, other_text, this_text)
     m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
     merged_text = "".join(list(m_lines))
     optimal_text = ("a\n" * 10 + "<<<<<<< OTHER\nc\n" + 8 * "b\n" +
                     "c\n=======\n" + 10 * "b\n" + ">>>>>>> THIS\n")
     self.assertEqualDiff(optimal_text, merged_text)
Пример #7
0
    def test_replace_clash(self):
        """Both try to insert lines in the same place."""
        m3 = merge3.Merge3(['aaa', '000', 'bbb'], ['aaa', '111', 'bbb'],
                           ['aaa', '222', 'bbb'])

        self.assertEqual(m3.find_unconflicted(), [(0, 1), (2, 3)])

        self.assertEqual(list(m3.find_sync_regions()), [
            (0, 1, 0, 1, 0, 1),
            (2, 3, 2, 3, 2, 3),
            (3, 3, 3, 3, 3, 3),
        ])
Пример #8
0
    def test_merge3_cherrypick(self):
        base_text = "a\nb\n"
        this_text = "a\n"
        other_text = "a\nb\nc\n"
        # When cherrypicking, lines in base are not part of the conflict
        m3 = merge3.Merge3(base_text.splitlines(True),
                           this_text.splitlines(True),
                           other_text.splitlines(True),
                           is_cherrypick=True)
        m_lines = m3.merge_lines()
        self.assertEqualDiff('a\n<<<<<<<\n=======\nc\n>>>>>>>\n',
                             ''.join(m_lines))

        # This is not symmetric
        m3 = merge3.Merge3(base_text.splitlines(True),
                           other_text.splitlines(True),
                           this_text.splitlines(True),
                           is_cherrypick=True)
        m_lines = m3.merge_lines()
        self.assertEqualDiff('a\n<<<<<<<\nb\nc\n=======\n>>>>>>>\n',
                             ''.join(m_lines))
Пример #9
0
    def test_replace_multi(self):
        """Replacement with regions of different size."""
        m3 = merge3.Merge3(['aaa', '000', '000', 'bbb'],
                           ['aaa', '111', '111', '111', 'bbb'],
                           ['aaa', '222', '222', '222', '222', 'bbb'])

        self.assertEqual(m3.find_unconflicted(), [(0, 1), (3, 4)])

        self.assertEqual(list(m3.find_sync_regions()), [
            (0, 1, 0, 1, 0, 1),
            (3, 4, 4, 5, 5, 6),
            (4, 4, 5, 5, 6, 6),
        ])
Пример #10
0
    def test_no_changes(self):
        """No conflicts because nothing changed"""
        m3 = merge3.Merge3(['aaa', 'bbb'], ['aaa', 'bbb'], ['aaa', 'bbb'])

        self.assertEqual(m3.find_unconflicted(), [(0, 2)])

        self.assertEqual(list(m3.find_sync_regions()), [(0, 2, 0, 2, 0, 2),
                                                        (2, 2, 2, 2, 2, 2)])

        self.assertEqual(list(m3.merge_regions()), [('unchanged', 0, 2)])

        self.assertEqual(list(m3.merge_groups()),
                         [('unchanged', ['aaa', 'bbb'])])
Пример #11
0
    def test_front_insert(self):
        m3 = merge3.Merge3(['zz'], ['aaa', 'bbb', 'zz'], ['zz'])

        # todo: should use a sentinal at end as from get_matching_blocks
        # to match without zz
        self.assertEqual(list(m3.find_sync_regions()), [
            (0, 1, 2, 3, 0, 1),
            (1, 1, 3, 3, 1, 1),
        ])

        self.assertEqual(list(m3.merge_regions()), [('a', 0, 2),
                                                    ('unchanged', 0, 1)])

        self.assertEqual(list(m3.merge_groups()), [('a', ['aaa', 'bbb']),
                                                   ('unchanged', ['zz'])])
Пример #12
0
 def test_allow_objects(self):
     """Objects other than strs may be used with Merge3 when
     allow_objects=True.
     
     merge_groups and merge_regions work with non-str input.  Methods that
     return lines like merge_lines fail.
     """
     base = [(x, x) for x in 'abcde']
     a = [(x, x) for x in 'abcdef']
     b = [(x, x) for x in 'Zabcde']
     m3 = merge3.Merge3(base, a, b, allow_objects=True)
     self.assertEqual([('b', 0, 1), ('unchanged', 0, 5), ('a', 5, 6)],
                      list(m3.merge_regions()))
     self.assertEqual([('b', [('Z', 'Z')]),
                       ('unchanged', [(x, x) for x in 'abcde']),
                       ('a', [('f', 'f')])], list(m3.merge_groups()))
Пример #13
0
    def test_minimal_conflicts_nonunique(self):
        def add_newline(s):
            """Add a newline to each entry in the string"""
            return [(x + '\n') for x in s]

        base_text = add_newline("abacddefgghij")
        this_text = add_newline("abacddefgghijkalmontfprz")
        other_text = add_newline("abacddefgghijknlmontfprd")
        m3 = merge3.Merge3(base_text, other_text, this_text)
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
        merged_text = "".join(list(m_lines))
        optimal_text = ''.join(
            add_newline("abacddefgghijk") +
            ["<<<<<<< OTHER\nn\n=======\na\n>>>>>>> THIS\n"] +
            add_newline('lmontfpr') +
            ["<<<<<<< OTHER\nd\n=======\nz\n>>>>>>> THIS\n"])
        self.assertEqualDiff(optimal_text, merged_text)
Пример #14
0
    def test_minimal_conflicts_unique(self):
        def add_newline(s):
            """Add a newline to each entry in the string"""
            return [(x + '\n') for x in s]

        base_text = add_newline("abcdefghijklm")
        this_text = add_newline("abcdefghijklmNOPQRSTUVWXYZ")
        other_text = add_newline("abcdefghijklm1OPQRSTUVWXY2")
        m3 = merge3.Merge3(base_text, other_text, this_text)
        m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
        merged_text = "".join(list(m_lines))
        optimal_text = ''.join(
            add_newline("abcdefghijklm") +
            ["<<<<<<< OTHER\n1\n=======\nN\n>>>>>>> THIS\n"] +
            add_newline('OPQRSTUVWXY') +
            ["<<<<<<< OTHER\n2\n=======\nZ\n>>>>>>> THIS\n"])
        self.assertEqualDiff(optimal_text, merged_text)
Пример #15
0
    def test_no_conflicts(self):
        """No conflicts because only one side changed"""
        m3 = merge3.Merge3(['aaa', 'bbb'], ['aaa', '111', 'bbb'],
                           ['aaa', 'bbb'])

        self.assertEqual(m3.find_unconflicted(), [(0, 1), (1, 2)])

        self.assertEqual(list(m3.find_sync_regions()), [
            (0, 1, 0, 1, 0, 1),
            (1, 2, 2, 3, 1, 2),
            (2, 2, 3, 3, 2, 2),
        ])

        self.assertEqual(list(m3.merge_regions()), [
            ('unchanged', 0, 1),
            ('a', 1, 2),
            ('unchanged', 1, 2),
        ])
Пример #16
0
    def test_append_clash(self):
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'], ['aaa\n', 'bbb\n', '222\n'],
                           ['aaa\n', 'bbb\n', '333\n'])

        ml = m3.merge_lines(name_a='a',
                            name_b='b',
                            start_marker='<<',
                            mid_marker='--',
                            end_marker='>>')
        self.assertEqual(''.join(ml), '''\
aaa
bbb
<< a
222
--
333
>> b
''')
Пример #17
0
    def merge_text(self, params):
        """Perform a simple 3-way merge of a bzr NEWS file.

        Each section of a bzr NEWS file is essentially an ordered set of bullet
        points, so we can simply take a set of bullet points, determine which
        bullets to add and which to remove, sort, and reserialize.
        """
        # Transform the different versions of the NEWS file into a bunch of
        # text lines where each line matches one part of the overall
        # structure, e.g. a heading or bullet.
        this_lines = list(simple_parse_lines(params.this_lines))
        other_lines = list(simple_parse_lines(params.other_lines))
        base_lines = list(simple_parse_lines(params.base_lines))
        m3 = merge3.Merge3(base_lines, this_lines, other_lines,
            allow_objects=True)
        result_chunks = []
        for group in m3.merge_groups():
            if group[0] == 'conflict':
                _, base, a, b = group
                # Are all the conflicting lines bullets?  If so, we can merge
                # this.
                for line_set in [base, a, b]:
                    for line in line_set:
                        if line[0] != 'bullet':
                            # Something else :(
                            # Maybe the default merge can cope.
                            return 'not_applicable', None
                # Calculate additions and deletions.
                new_in_a = set(a).difference(base)
                new_in_b = set(b).difference(base)
                all_new = new_in_a.union(new_in_b)
                deleted_in_a = set(base).difference(a)
                deleted_in_b = set(base).difference(b)
                # Combine into the final set of bullet points.
                final = all_new.difference(deleted_in_a).difference(
                    deleted_in_b)
                # Sort, and emit.
                final = sorted(final, key=sort_key)
                result_chunks.extend(final)
            else:
                result_chunks.extend(group[1])
        # Transform the merged elements back into real blocks of lines.
        result_lines = '\n\n'.join(chunk[1] for chunk in result_chunks)
        return 'success', result_lines
Пример #18
0
 def test_merge3_cherrypick_w_mixed(self):
     base_text = 'a\nb\nc\nd\ne\n'
     this_text = 'a\nb\nq\n'
     other_text = 'a\nb\nc\nd\nf\ne\ng\n'
     # When cherrypicking, lines in base are not part of the conflict
     m3 = merge3.Merge3(base_text.splitlines(True),
                        this_text.splitlines(True),
                        other_text.splitlines(True),
                        is_cherrypick=True)
     m_lines = m3.merge_lines()
     self.assertEqualDiff(
         'a\n'
         'b\n'
         '<<<<<<<\n'
         'q\n'
         '=======\n'
         'f\n'
         '>>>>>>>\n'
         '<<<<<<<\n'
         '=======\n'
         'g\n'
         '>>>>>>>\n', ''.join(m_lines))
Пример #19
0
    def test_insert_clash(self):
        """Both try to insert lines in the same place."""
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'], ['aaa\n', '111\n', 'bbb\n'],
                           ['aaa\n', '222\n', 'bbb\n'])

        self.assertEqual(m3.find_unconflicted(), [(0, 1), (1, 2)])

        self.assertEqual(list(m3.find_sync_regions()), [
            (0, 1, 0, 1, 0, 1),
            (1, 2, 2, 3, 2, 3),
            (2, 2, 3, 3, 3, 3),
        ])

        self.assertEqual(list(m3.merge_regions()),
                         [('unchanged', 0, 1), ('conflict', 1, 1, 1, 2, 1, 2),
                          ('unchanged', 1, 2)])

        self.assertEqual(list(m3.merge_groups()), [
            ('unchanged', ['aaa\n']),
            ('conflict', [], ['111\n'], ['222\n']),
            ('unchanged', ['bbb\n']),
        ])

        ml = m3.merge_lines(name_a='a',
                            name_b='b',
                            start_marker='<<',
                            mid_marker='--',
                            end_marker='>>')
        self.assertEqual(''.join(ml), '''aaa
<< a
111
--
222
>> b
bbb
''')
Пример #20
0
    def test_append_agreement(self):
        m3 = merge3.Merge3(['aaa\n', 'bbb\n'], ['aaa\n', 'bbb\n', '222\n'],
                           ['aaa\n', 'bbb\n', '222\n'])

        self.assertEqual(''.join(m3.merge_lines()), 'aaa\nbbb\n222\n')