def test_long_substring(self): a0 = '123' b0 = '....................................................123' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) #CASE004 self.assertEqual(a1, '~123') self.assertEqual(b1, '[....................................................]123')
def test_composite_index_problem(self): a0 = '.left {' b0 = '.left, .right {' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, '.left~ {') self.assertEqual(b1, '.left[, .right] {')
def test_surrounding_whitespace(self): a0 = '\t _ \t' b0 = ' _ ' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, '[\t] _ [\t]') self.assertEqual(b1, '[ ] _ [ ]')
def test_ignored_whitespace(self): a0 = '\t X \t' b0 = ' Y ' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, '\t [X] \t') self.assertEqual(b1, ' [Y] ')
def test_trailing_whitespace(self): a0 = '_\t' b0 = '_' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, '_[\t]') self.assertEqual(b1, '_~')
def test_leading_whitespace(self): a0 = ' _' b0 = ' _' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, ' ~_') self.assertEqual(b1, ' [ ]_')
def test_all_whitespace(self): a0 = ' ' b0 = ' ' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, ' ~') self.assertEqual(b1, ' [ ]')
def test_empty_strings(self): a0 = '' b0 = '' (a1, b1) = ChangeCompare.mark_change(a0, b0, self.MARKER_CONFIG) self.assertEqual(a1, a0) self.assertEqual(b1, b0)
def _render_side_by_side(self): '''Generates the html markup for the side-by-side diff.''' (html, ui, diff) = ([], self.ui, self.diff) noteA = ' (file created)' if not diff.existsA else '' noteB = ' (file deleted)' if not diff.existsB else '' # lines removed A, lines modified A, lines added B, lines modified B (removed, modifiedA, added, modifiedB) = (0, 0, 0, 0) for (chunkIndex, chunk) in enumerate(diff.chunks): count = len(chunk.A.lines) # A and B are the same length # add the appearance of a "clipped" row between subsequent chunks if (chunkIndex > 0): html.append(self.HTML_SIDE_BY_SIDE_BODY_SNIPPED_ROW) for (i, a, b) in izip(range(count), chunk.A.lines, chunk.B.lines): if a is None: (dataA, statA, lineA) = (self.NBSP, prettydiff.ADDED, self.NBSP) else: dataA = self._esc(a.data) statA = a.status lineA = self._anchor('a', a.line_num) # tally lines removed/modified if statA == prettydiff.REMOVED: removed += 1 elif statA == prettydiff.MODIFIED: modifiedA += 1 if b is None: (dataB, statB, lineB) = (self.NBSP, prettydiff.REMOVED, self.NBSP) else: dataB = self._esc(b.data) statB = b.status lineB = self._anchor('b', b.line_num) # tally lines added/modified if statB == prettydiff.ADDED: added += 1 elif statB == prettydiff.MODIFIED: modifiedB += 1 if statA == prettydiff.MODIFIED: # mark up the differences between a and b; it is very # important that the original (non-encoded) strings be # passed to mark_change otherwise entities get mangled (dataA, dataB) = ChangeCompare.mark_change(a.data, b.data) dataA = ChangeCompare.swap_markers(self._esc(dataA), self.CHANGE_DELIMITERS) dataB = ChangeCompare.swap_markers(self._esc(dataB), self.CHANGE_DELIMITERS) if i == 0: edge_row_class = ' class="first"' elif i == count - 1: edge_row_class = ' class="last"' else: edge_row_class = '' html.append( self.HTML_SIDE_BY_SIDE_BODY % (edge_row_class, lineA, statA, dataA, lineB, statB, dataB)) ui.append(self.HTML_SIDE_BY_SIDE_HEAD % (diff.revA, noteA, removed, modifiedA, diff.timestampA, diff.revB, noteB, added, modifiedB, diff.timestampB)) ui.append(''.join(html)) ui.append(self.HTML_SIDE_BY_SIDE_FOOT)
def _render_side_by_side(self): '''Generates the html markup for the side-by-side diff.''' (html, ui, diff) = ([], self.ui, self.diff) noteA = ' (file created)' if not diff.existsA else '' noteB = ' (file deleted)' if not diff.existsB else '' # lines removed A, lines modified A, lines added B, lines modified B (removed, modifiedA, added, modifiedB) = (0, 0, 0, 0) for (chunkIndex, chunk) in enumerate(diff.chunks): count = len(chunk.A.lines) # A and B are the same length # add the appearance of a "clipped" row between subsequent chunks if (chunkIndex > 0): html.append(self.HTML_SIDE_BY_SIDE_BODY_SNIPPED_ROW) for (i, a, b) in izip(range(count), chunk.A.lines, chunk.B.lines): if a is None: (dataA, statA, lineA) = (self.NBSP, prettydiff.ADDED, self.NBSP) else: dataA = self._esc(a.data) statA = a.status lineA = self._anchor('a', a.line_num) # tally lines removed/modified if statA == prettydiff.REMOVED: removed += 1 elif statA == prettydiff.MODIFIED: modifiedA += 1 if b is None: (dataB, statB, lineB) = (self.NBSP, prettydiff.REMOVED, self.NBSP) else: dataB = self._esc(b.data) statB = b.status lineB = self._anchor('b', b.line_num) # tally lines added/modified if statB == prettydiff.ADDED: added += 1 elif statB == prettydiff.MODIFIED: modifiedB += 1 if statA == prettydiff.MODIFIED: # mark up the differences between a and b; it is very # important that the original (non-encoded) strings be # passed to mark_change otherwise entities get mangled (dataA, dataB) = ChangeCompare.mark_change(a.data, b.data) dataA = ChangeCompare.swap_markers(self._esc(dataA), self.CHANGE_DELIMITERS) dataB = ChangeCompare.swap_markers(self._esc(dataB), self.CHANGE_DELIMITERS) if i==0: row_template = self.HTML_SIDE_BY_SIDE_BODY_FIRST_ROW elif i==count-1: row_template = self.HTML_SIDE_BY_SIDE_BODY_LAST_ROW else: row_template = self.HTML_SIDE_BY_SIDE_BODY_MIDDLE_ROW html.append(row_template % (lineA, statA, dataA, lineB, statB, dataB)) ui.append(self.HTML_SIDE_BY_SIDE_HEAD % (diff.revA, noteA, removed, modifiedA, diff.timestampA, diff.revB, noteB, added, modifiedB, diff.timestampB)) ui.append(''.join(html)) ui.append(self.HTML_SIDE_BY_SIDE_FOOT)