def _test_move_detection(self, a, b, expected_i_moves, expected_r_moves): differ = MyersDiffer(a, b) opcode_generator = get_diff_opcode_generator(differ) r_moves = [] i_moves = [] for opcodes in opcode_generator: # Log the opcode so we can more easily debug unit test failures. print(opcodes) meta = opcodes[-1] try: r_moves.append(meta['moved-to']) except KeyError: pass try: i_moves.append(meta['moved-from']) except KeyError: pass self.assertEqual(i_moves, expected_i_moves) self.assertEqual(r_moves, expected_r_moves)
def get_opcode_generator(self): """Return the DiffOpcodeGenerator used to generate diff opcodes.""" diff = self.filediff.diff if self.interfilediff: interdiff = self.interfilediff.diff else: interdiff = None return get_diff_opcode_generator(self.differ, diff, interdiff)
def _test_move_detection(self, a, b, expected_i_moves, expected_r_moves): differ = MyersDiffer(a, b) opcode_generator = get_diff_opcode_generator(differ) r_moves = [] i_moves = [] for opcodes in opcode_generator: meta = opcodes[-1] if 'moved-to' in meta: r_moves.append(meta['moved-to']) if 'moved-from' in meta: i_moves.append(meta['moved-from']) self.assertEqual(i_moves, expected_i_moves) self.assertEqual(r_moves, expected_r_moves)
def _test_move_detection(self, a, b, expected_i_moves, expected_r_moves): differ = MyersDiffer(a, b) opcode_generator = get_diff_opcode_generator(differ) r_moves = [] i_moves = [] for opcodes in opcode_generator: tag = opcodes[0] meta = opcodes[-1] if 'moved-to' in meta: r_moves.append(meta['moved-to']) if 'moved-from' in meta: i_moves.append(meta['moved-from']) self.assertEqual(i_moves, expected_i_moves) self.assertEqual(r_moves, expected_r_moves)
def testMoveDetection(self): """Testing move detection""" # movetest1 has two blocks of code that would appear to be moves: # a function, and an empty comment block. Only the function should # be seen as a move, whereas the empty comment block is less useful # (since it's content-less) and shouldn't be seen as once. old = self._get_file('orig_src', 'movetest1.c') new = self._get_file('new_src', 'movetest1.c') differ = MyersDiffer(old.splitlines(), new.splitlines()) r_moves = [] i_moves = [] opcode_generator = get_diff_opcode_generator(differ) for opcodes in opcode_generator: tag = opcodes[0] meta = opcodes[-1] if tag == 'delete': if 'moved' in meta: r_moves.append(meta['moved']) elif tag == 'insert': if 'moved' in meta: i_moves.append(meta['moved']) self.assertEqual(len(r_moves), 1) self.assertEqual(len(i_moves), 1) moves = [ (15, 28), (16, 29), (17, 30), (18, 31), (19, 32) ] for i, j in moves: self.assertTrue(j in i_moves[0]) self.assertTrue(i in r_moves[0]) self.assertEqual(i_moves[0][j], i) self.assertEqual(r_moves[0][i], j)
def _get_chunks_uncached(self): """Returns the list of chunks, bypassing the cache.""" old = get_original_file(self.filediff, self.request) new = get_patched_file(old, self.filediff, self.request) if self.interfilediff: old = new interdiff_orig = get_original_file(self.interfilediff, self.request) new = get_patched_file(interdiff_orig, self.interfilediff, self.request) elif self.force_interdiff: # Basically, revert the change. old, new = new, old encoding = self.diffset.repository.encoding or 'iso-8859-15' old = self._convert_to_utf8(old, encoding) new = self._convert_to_utf8(new, encoding) # Normalize the input so that if there isn't a trailing newline, we add # it. if old and old[-1] != '\n': old += '\n' if new and new[-1] != '\n': new += '\n' a = self.NEWLINES_RE.split(old or '') b = self.NEWLINES_RE.split(new or '') # Remove the trailing newline, now that we've split this. This will # prevent a duplicate line number at the end of the diff. del a[-1] del b[-1] a_num_lines = len(a) b_num_lines = len(b) markup_a = markup_b = None if self._get_enable_syntax_highlighting(old, new, a, b): repository = self.filediff.diffset.repository tool = repository.get_scmtool() source_file = \ tool.normalize_path_for_display(self.filediff.source_file) dest_file = \ tool.normalize_path_for_display(self.filediff.dest_file) try: # TODO: Try to figure out the right lexer for these files # once instead of twice. markup_a = self._apply_pygments(old or '', source_file) markup_b = self._apply_pygments(new or '', dest_file) except: pass if not markup_a: markup_a = self.NEWLINES_RE.split(escape(old)) if not markup_b: markup_b = self.NEWLINES_RE.split(escape(new)) siteconfig = SiteConfiguration.objects.get_current() ignore_space = True for pattern in siteconfig.get('diffviewer_include_space_patterns'): if fnmatch.fnmatch(self.filename, pattern): ignore_space = False break self.differ = get_differ(a, b, ignore_space=ignore_space, compat_version=self.diffset.diffcompat) self.differ.add_interesting_lines_for_headers(self.filename) context_num_lines = siteconfig.get("diffviewer_context_num_lines") collapse_threshold = 2 * context_num_lines + 3 if self.interfilediff: log_timer = log_timed( "Generating diff chunks for interdiff ids %s-%s (%s)" % (self.filediff.id, self.interfilediff.id, self.filediff.source_file), request=self.request) else: log_timer = log_timed( "Generating diff chunks for self.filediff id %s (%s)" % (self.filediff.id, self.filediff.source_file), request=self.request) line_num = 1 opcodes_generator = get_diff_opcode_generator(self.differ, self.filediff, self.interfilediff) for tag, i1, i2, j1, j2, meta in opcodes_generator: old_lines = markup_a[i1:i2] new_lines = markup_b[j1:j2] num_lines = max(len(old_lines), len(new_lines)) self._cur_meta = meta lines = map(self._diff_line, range(line_num, line_num + num_lines), range(i1 + 1, i2 + 1), range(j1 + 1, j2 + 1), a[i1:i2], b[j1:j2], old_lines, new_lines) self._cur_meta = None if tag == 'equal' and num_lines > collapse_threshold: last_range_start = num_lines - context_num_lines if line_num == 1: yield self._new_chunk(lines, 0, last_range_start, True) yield self._new_chunk(lines, last_range_start, num_lines) else: yield self._new_chunk(lines, 0, context_num_lines) if i2 == a_num_lines and j2 == b_num_lines: yield self._new_chunk(lines, context_num_lines, num_lines, True) else: yield self._new_chunk(lines, context_num_lines, last_range_start, True) yield self._new_chunk(lines, last_range_start, num_lines) else: yield self._new_chunk(lines, 0, num_lines, False, tag, meta) line_num += num_lines log_timer.done()
def get_opcode_generator(self): """Return the DiffOpcodeGenerator used to generate diff opcodes.""" return get_diff_opcode_generator(self.differ)
def _get_chunks_uncached(self): """Returns the list of chunks, bypassing the cache.""" old = get_original_file(self.filediff, self.request) new = get_patched_file(old, self.filediff, self.request) if self.interfilediff: old = new interdiff_orig = get_original_file(self.interfilediff, self.request) new = get_patched_file(interdiff_orig, self.interfilediff, self.request) elif self.force_interdiff: # Basically, revert the change. old, new = new, old encoding = self.diffset.repository.encoding or 'iso-8859-15' old = self._convert_to_utf8(old, encoding) new = self._convert_to_utf8(new, encoding) # Normalize the input so that if there isn't a trailing newline, we add # it. if old and old[-1] != '\n': old += '\n' if new and new[-1] != '\n': new += '\n' a = self.NEWLINES_RE.split(old or '') b = self.NEWLINES_RE.split(new or '') # Remove the trailing newline, now that we've split this. This will # prevent a duplicate line number at the end of the diff. del a[-1] del b[-1] a_num_lines = len(a) b_num_lines = len(b) markup_a = markup_b = None if self._get_enable_syntax_highlighting(old, new, a, b): repository = self.filediff.diffset.repository tool = repository.get_scmtool() source_file = \ tool.normalize_path_for_display(self.filediff.source_file) dest_file = \ tool.normalize_path_for_display(self.filediff.dest_file) try: # TODO: Try to figure out the right lexer for these files # once instead of twice. markup_a = self._apply_pygments(old or '', source_file) markup_b = self._apply_pygments(new or '', dest_file) except: pass if not markup_a: markup_a = self.NEWLINES_RE.split(escape(old)) if not markup_b: markup_b = self.NEWLINES_RE.split(escape(new)) siteconfig = SiteConfiguration.objects.get_current() ignore_space = True for pattern in siteconfig.get('diffviewer_include_space_patterns'): if fnmatch.fnmatch(self.filename, pattern): ignore_space = False break self.differ = get_differ(a, b, ignore_space=ignore_space, compat_version=self.diffset.diffcompat) self.differ.add_interesting_lines_for_headers(self.filename) context_num_lines = siteconfig.get("diffviewer_context_num_lines") collapse_threshold = 2 * context_num_lines + 3 if self.interfilediff: log_timer = log_timed( "Generating diff chunks for interdiff ids %s-%s (%s)" % (self.filediff.id, self.interfilediff.id, self.filediff.source_file), request=self.request) else: log_timer = log_timed( "Generating diff chunks for self.filediff id %s (%s)" % (self.filediff.id, self.filediff.source_file), request=self.request) line_num = 1 opcodes_generator = get_diff_opcode_generator(self.differ, self.filediff, self.interfilediff) for tag, i1, i2, j1, j2, meta in opcodes_generator: old_lines = markup_a[i1:i2] new_lines = markup_b[j1:j2] num_lines = max(len(old_lines), len(new_lines)) self._cur_meta = meta lines = map(self._diff_line, xrange(line_num, line_num + num_lines), xrange(i1 + 1, i2 + 1), xrange(j1 + 1, j2 + 1), a[i1:i2], b[j1:j2], old_lines, new_lines) self._cur_meta = None if tag == 'equal' and num_lines > collapse_threshold: last_range_start = num_lines - context_num_lines if line_num == 1: yield self._new_chunk(lines, 0, last_range_start, True) yield self._new_chunk(lines, last_range_start, num_lines) else: yield self._new_chunk(lines, 0, context_num_lines) if i2 == a_num_lines and j2 == b_num_lines: yield self._new_chunk(lines, context_num_lines, num_lines, True) else: yield self._new_chunk(lines, context_num_lines, last_range_start, True) yield self._new_chunk(lines, last_range_start, num_lines) else: yield self._new_chunk(lines, 0, num_lines, False, tag, meta) line_num += num_lines log_timer.done()
def setUp(self): super(IndentationTests, self).setUp() self.generator = get_diff_opcode_generator(MyersDiffer('', ''))
def setUp(self): self.generator = get_diff_opcode_generator(MyersDiffer('', ''))