def test_side_by_side8(self):
     display_lines = [
         logging.red(logging.red_diff('1') + ' 0 2' + ' ' * (self.max_chars - 5)) + '|' + logging.green(logging.green_diff('2') + ' 0 2'),
         logging.red('1 ' + logging.red_diff('0') + ' 2' + ' ' * (self.max_chars - 5)) + '|' + logging.green('1 ' + logging.green_diff('1') + ' 2'),
         logging.red('1 0 ' + logging.red_diff('2') + ' ' * (self.max_chars - 5)) + '|' + logging.green('1 0 ' + logging.green_diff('3')),
     ]
     self.snippet_call_test('1 0 2\n1 0 2\n1 0 2', '2 0 2\n1 1 2\n1 0 3', display_lines)
 def test_side_by_side7(self):
     display_lines = [
         logging.red(logging.red_diff('0 2') + ' ' * (self.max_chars - 3)) + '|' + logging.green(''),
         logging.red(logging.red_diff('1 2') + ' ' * (self.max_chars - 3)) + '|' + logging.green(''),
         '2 2' + ' ' * (self.max_chars - 3) + '|2 2',
         '3 2' + ' ' * (self.max_chars - 3) + '|3 2',
         '4 2' + ' ' * (self.max_chars - 3) + '|4 2',
         logging.red(' ' * (self.max_chars)) + '|' + logging.green(logging.green_diff('5 2')),
         logging.red(' ' * (self.max_chars)) + '|' + logging.green(logging.green_diff('6 2')),
     ]
     self.snippet_call_test('0 2\n1 2\n2 2\n3 2\n4 2', '2 2\n3 2\n4 2\n5 2\n6 2', display_lines)
 def test_side_by_side2(self):
     display_lines = [
         '98 |Alice' + ' ' * (self.max_chars - 9) + '|Alice',
         '99 |Bob' + ' ' * (self.max_chars - 7) + '|Bob',
         '100|Alice' + ' ' * (self.max_chars - 9) + '|Alice',
         '101|' + logging.red(logging.red_diff('Bob') + ' ' * (self.max_chars - 7)) + '|' + logging.green(logging.green_diff('John')),
         '102|' + logging.red(logging.red_diff('Alice') + ' ' * (self.max_chars - 9)) + '|' + logging.green(logging.green_diff('John')),
         '103|Bob' + ' ' * (self.max_chars - 7) + '|Bob',
         '104|Alice' + ' ' * (self.max_chars - 9) + '|Alice',
         '... (1 lines) ...',
     ]
     output = ('\n' * 97 + 'Alice\nBob\nAlice\nBob\nAlice\nBob\nAlice\nBob').replace('\n', os.linesep)
     expect = ('\n' * 97 + 'Alice\nBob\nAlice\nJohn\nJohn\nBob\nAlice\nBob').replace('\n', os.linesep)
     self.snippet_call_test(output, expect, display_lines, 3)
 def test_side_by_side1(self):
     display_lines = [
         '41|Alice' + ' ' * (self.max_chars - 8) + '|Alice',
         '42|Bob' + ' ' * (self.max_chars - 6) + '|Bob',
         '43|Alice' + ' ' * (self.max_chars - 8) + '|Alice',
         '44|' + logging.red(logging.red_diff('Bob') + ' ' * (self.max_chars - 6)) + '|' + logging.green(logging.green_diff('John')),
         '45|' + logging.red(logging.red_diff('Alice') + ' ' * (self.max_chars - 8)) + '|' + logging.green(logging.green_diff('John')),
         '46|Bob' + ' ' * (self.max_chars - 6) + '|Bob',
         '47|Alice' + ' ' * (self.max_chars - 8) + '|Alice',
         '... (1 lines) ...',
     ]
     output = ('\n' * 40 + 'Alice\nBob\nAlice\nBob\nAlice\nBob\nAlice\nBob').replace('\n', os.linesep)
     expect = ('\n' * 40 + 'Alice\nBob\nAlice\nJohn\nJohn\nBob\nAlice\nBob').replace('\n', os.linesep)
     self.snippet_call_test(output, expect, display_lines, 2)
 def test_side_by_side4(self):
     display_lines = [
         'Alice' + ' ' * (self.max_chars - 5) + '|Alice',
         logging.red('B' + logging.red_diff('0') + 'b' + ' ' * (self.max_chars - 3)) + '|' + logging.green('B' + logging.green_diff('o') + 'b'),
         'Alice' + ' ' * (self.max_chars - 5) + '|Alice',
     ]
     self.snippet_call_test('Alice\nB0b\nAlice', 'Alice\nBob\nAlice', display_lines)
示例#6
0
def side_by_side_diff(
        old_text: str, new_text: str
) -> Generator[Tuple[bool, str, str, int, int], None, None]:
    """
    Calculates a side-by-side line-based difference view.
    """
    line_split = re.compile(r'(?:\r?\n)')
    dmp = diff_match_patch.diff_match_patch()

    diff = dmp.diff_main(old_text, new_text)
    dmp.diff_cleanupSemantic(diff)

    open_entry = ([''], [''], [0], [0])
    for change_type, entry in diff:
        assert change_type in [-1, 0, 1]

        entry = (entry.replace('&',
                               '&amp;').replace('<',
                                                '&lt;').replace('>', '&gt;'))
        lines = line_split.split(entry)

        # Merge with previous entry if still open
        ls, rs, lnums, rnums = open_entry

        line = lines[0]
        if line:
            if change_type == 0:
                ls[-1] += line
                rs[-1] += line
                lnums[-1] += len(line)
                rnums[-1] += len(line)
            elif change_type == 1:
                rs[-1] = rs[-1] or ''
                rs[-1] += log.green_diff(line) if line else ''
                rnums[-1] += len(line)
            elif change_type == -1:
                ls[-1] = ls[-1] or ''
                ls[-1] += log.red_diff(line) if line else ''
                lnums[-1] += len(line)

        lines = lines[1:]

        if lines:
            if change_type == 0:
                # Push out open entry
                for entry in yield_open_entry(open_entry):
                    yield entry

                # Directly push out lines until last
                for line in lines[:-1]:
                    yield (False, line, line, len(line), len(line))

                # Keep last line open
                open_entry = ([lines[-1]], [lines[-1]], [len(lines[-1])],
                              [len(lines[-1])])
            elif change_type == 1:
                ls, rs, lnums, rnums = open_entry
                for line in lines:
                    rs.append(log.green_diff(line) if line else '')
                    rnums.append(len(line))
            elif change_type == -1:
                ls, rs, lnums, rnums = open_entry
                for line in lines:
                    ls.append(log.red_diff(line) if line else '')
                    lnums.append(len(line))

    # Push out open entry
    for entry in yield_open_entry(open_entry):
        yield entry
 def test_side_by_side2(self):
     self.snippet_call_test('kmy', 'kmv', (logging.red('km' + logging.red_diff('y') + ' ' * (self.max_chars - 3)) + '|' + logging.green('km' + logging.green_diff('v')), ))