def test_raises_ValueError_on_negative_context_width(self): with pytest.raises(ValueError): make_anchor(file_path=pathlib.Path("/source.py"), handle=StringIO("contents"), offset=0, width=1, context_width=-1, metadata={})
def test_raises_ValueError_if_path_is_not_absolute(self): with pytest.raises(ValueError): make_anchor(file_path=pathlib.Path("source.py"), handle=StringIO('contents'), offset=0, width=1, context_width=1, metadata={})
def test_raises_ValueError_if_anchor_past_end_of_file(self, args): text, offset, width = args with pytest.raises(ValueError): make_anchor(file_path=pathlib.Path("/source.py"), handle=StringIO(text), offset=offset, width=width, context_width=4, metadata={})
def test_raises_AlignmentError_if_empty_alignment(self): anchor = make_anchor(file_path=Path('/source.py'), offset=2, width=1, context_width=2, metadata={}, handle=StringIO("aabcc")) with pytest.raises(AlignmentError): update(anchor, StringIO("aacc"))
def test_acceptance(self, pre, post): offset, width, context_width, text = pre anchor = make_anchor(file_path=Path('/source.py'), offset=offset, width=width, context_width=context_width, metadata={}, handle=StringIO(text)) offset, width, context_width, text = post updated_anchor = update(anchor, StringIO(text)) expected_anchor = make_anchor(file_path=Path('/source.py'), offset=offset, width=width, context_width=context_width, metadata={}, handle=StringIO(text)) assert updated_anchor == expected_anchor
def test_make_anchor(repo): source = pathlib.Path('source.py') with source.open(mode='wt') as handle: handle.write('\n'.join('abcde')) anchor = make_anchor(2, repo.root / source, 3, {}) assert anchor.file_path == source assert anchor.line_number == 3 assert anchor.columns is None assert anchor.metadata == {} assert anchor.context.before == ('a\n', 'b\n') assert anchor.context.line == 'c\n' assert anchor.context.after == ('d\n', 'e\n')
def test_get_anchor_by_id(repo): source_path = repo.root / "source.py" metadata = {"1": 2} anchor_id = repo.add( make_anchor(metadata=metadata, file_path=source_path, handle=StringIO('# nothing'), offset=3, width=3, context_width=2)) repo[anchor_id]
def test_success(self): anchor = make_anchor(file_path=pathlib.Path('/source.py'), handle=StringIO('\n'.join('abcde')), offset=4, width=2, context_width=4, metadata={}) assert anchor.file_path == pathlib.Path('/source.py') assert anchor.context.before == 'a\nb\n' assert anchor.context.offset == 4 assert anchor.context.topic == 'c\n' assert anchor.context.after == 'd\ne' assert anchor.metadata == {}
def update(anchor, handle=None): """Update an anchor based on the current contents of its source file. Args: anchor: The `Anchor` to be updated. handle: File-like object containing contents of the anchor's file. If `None`, then this function will open the file and read it. Returns: A new `Anchor`, possibly identical to the input. Raises: ValueError: No alignments could be found between old anchor and new text. AlignmentError: If no anchor could be created. The message of the exception will say what the problem is. """ if handle is None: with anchor.file_path.open(mode='rt') as fp: source_text = fp.read() else: source_text = handle.read() handle.seek(0) ctxt = anchor.context a_score, alignments = align(ctxt.full_text, source_text, score, gap_penalty) # max_score = len(ctxt.full_text) * 3 try: alignment = next(alignments) except StopIteration: raise AlignmentError('No alignments for anchor: {}'.format(anchor)) anchor_offset = ctxt.offset - len(ctxt.before) source_indices = tuple(s_idx for (a_idx, s_idx) in alignment if a_idx is not None if s_idx is not None if _index_in_topic(a_idx + anchor_offset, anchor)) if not source_indices: raise AlignmentError( "Best alignment does not map topic to updated source.") return make_anchor(file_path=anchor.file_path, offset=source_indices[0], width=len(source_indices), context_width=anchor.context.width, metadata=anchor.metadata, handle=handle)
def _test_delete_removes_anchor(repo): source_path = repo.root / "source.py" with source_path.open(mode='wt') as handle: handle.write('# nothing') anchor_id = repo.add( make_anchor(metadata={}, file_path=source_path, offset=3, width=3, context_width=2)) assert anchor_id in repo del repo[anchor_id] assert anchor_id not in repo
def test_make_anchor(repo): source = pathlib.Path('source.py') with source.open(mode='wt') as handle: handle.write('\n'.join('abcde')) anchor = make_anchor(file_path=repo.root / source, offset=4, width=2, context_width=4, metadata={}) assert anchor.file_path == source assert anchor.context.before.offset == 0 assert anchor.context.before.text == 'a\nb\n' assert anchor.context.topic.offset == 4 assert anchor.context.topic.text == 'c\n' assert anchor.context.after.offset == 6 assert anchor.context.after.text == 'd\ne' assert anchor.metadata == {}
def test_update_updates_metadata(repo): source_path = repo.root / "source.py" anchor_id = repo.add( make_anchor(metadata={}, file_path=source_path, handle=StringIO("# nothing"), offset=3, width=3, context_width=2)) new_metadata = {"3": 4} anchor = repo[anchor_id] anchor.metadata = new_metadata repo[anchor_id] = anchor anchor = repo[anchor_id] assert anchor.metadata == new_metadata
def test_add_anchor_generates_correct_anchor(repo): source_path = repo.root / "source.py" metadata = {"1": 2} anchor_id = repo.add( make_anchor(file_path=source_path, handle=StringIO('abcdefgh'), offset=3, width=3, context_width=2, metadata=metadata)) anchor = repo[anchor_id] assert anchor.file_path == source_path assert anchor.metadata == metadata assert anchor.context.width == 2 assert anchor.context.before == 'bc' assert anchor.context.topic == 'def' assert anchor.context.offset == 3 assert anchor.context.after == 'gh'