def test_overlap_on_right(self): older = self.make_spans([(7,9)]) newer = self.make_spans([(8,11)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['merge'], [{'new': [Span(8,11)], 'old': [Span(7,9)]}]) self.assertNull(delta, ['include', 'exclude', 'same', 'split', 'diff'])
def test_exclude_between(self): older = self.make_spans([(5,6)]) newer = self.make_spans([(1,4),(7,9)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['include'], [Span(1,4), Span(7,9)]) self.assertEqual(delta['exclude'], [Span(5,6)]) self.assertNull(delta, ['same', 'merge', 'split', 'diff'])
def test_change_middle_others_same(self): older = self.make_spans([(54,62),(103,111),(144,160)]) newer = self.make_spans([(54,62),(103,117),(144,160)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['merge'], [{'new': [Span(103,117)], 'old': [Span(103,111)]}]) self.assertEqual(delta['same'], [Span(54,62), Span(144,160)]) self.assertNull(delta, ['include', 'exclude', 'split', 'diff'])
def test_two_merges(self): older = self.make_spans([(61,69),(76,84),(92,100),(107,115)]) newer = self.make_spans([(64,84),(92,112)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['merge'], [{'new': [Span(64,84)], 'old': [Span(61,69),Span(76,84)]}, {'new': [Span(92,112)], 'old': [Span(92,100),Span(107,115)]}]) self.assertNull(delta, ['include', 'exclude', 'same', 'split', 'diff'])
def test_overlap_multiple_old(self): older = self.make_spans([(1,4),(5,8),(10,12),(14,19),(24,26)]) newer = self.make_spans([(7,16)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['merge'], [{'new': [Span(7,16)], 'old': [Span(5,8), Span(10,12), Span(14,19)]}]) self.assertEqual(delta['exclude'], [Span(1,4), Span(24,26)]) self.assertNull(delta, ['include', 'same', 'split', 'diff'])
def make_spans(self, elems): return [Span(left, right) for (left, right) in elems]
def test_same_one(self): older = self.make_spans([(1,4)]) newer = self.make_spans([(1,4)]) delta = span_list_delta.get_delta(newer, older) self.assertEqual(delta['same'], [Span(1,4)]) self.assertNull(delta, ['include', 'exclude', 'merge', 'split', 'diff'])
def do_contents(self, height, width, markings, number_width, trial=False): # For linked items, colour them to indicate it # For labels, colour them always, and add beginning / end # For freeform text, include it at the bottom # Row and column indicate the position on the screen, while line and # token indicate the position in the text. first_span = None last_span = None row = -1 for line_no, line in enumerate(self.datum.doc.tokens): # If this line is above the top of what we are shwoing, skip it if line_no < self.top: continue if row >= height: break if first_span is None: first_span = Span('character', self.datum.doc, (line_no, 0, 0)) # Set row += 1 column = number_width if (not trial) and column > 0: self.window.addstr(row, 0, str(line_no), curses.color_pair(LINE_NUMBER_COLOR)) for token_no, token in enumerate(line): # Check if we are going on to the next line and adjust # accordingly. space_before = 1 if column > number_width else 0 wide_token = False if column + len(token) + space_before > width: if token_no != 0: column = 0 row += 1 space_before = 0 else: wide_token = True # If this takes us off the screen, stop if row >= height: break end_pos = len(token) - 1 if wide_token: end_pos = width - column - space_before - 1 last_span = Span('character', self.datum.doc, (line_no, token_no, end_pos)) for char_no, char in enumerate(token): if column >= width: column = 0 row += 1 if row >= height: break # Allow multiple layers of color, with the more specific # domainating if space_before > 0: if not trial: mark = [] if () in markings: mark = markings[()] if (line_no, ) in markings: mark = markings[(line_no, )] if (line_no, token_no, -1) in markings: mark = markings[line_no, token_no, -1] color = self.marking_to_color(mark) self.window.addstr(row, column, ' ', color) column += 1 space_before = 0 color = self.marking_to_color([]) if not trial: mark = [] if () in markings: mark = markings[()] if (line_no, ) in markings: mark = markings[(line_no, )] if (line_no, token_no) in markings: mark = markings[line_no, token_no] if (line_no, token_no, char_no) in markings: mark = markings[line_no, token_no, char_no] color = self.marking_to_color(mark) self.window.addstr(row, column, char, color) column += 1 if row >= height: break # Tracks if we can see where we moved to seen_last_moved_pos = True if first_span is not None and last_span is not None: if self.last_moved_pos is not None: cmp_first = self.last_moved_pos.compare(first_span) cmp_last = self.last_moved_pos.compare(last_span) seen_last_moved_pos = cmp_first in span_compare_ge and \ cmp_last in span_compare_le return seen_last_moved_pos