Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions cvise/passes/lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,18 @@ def generate_hints(self, test_case: Path, process_event_notifier: ProcessEventNo
def _generate_hints_for_text_lines(self, input_path: Path, path_id: int | None, hints: list[Hint]) -> None:
"""Generate a hint per each line in the input as written."""
with open(input_path, 'rb') as in_file:
lines = in_file.readlines()
file_pos = 0
for line in in_file:
for i, line in enumerate(lines):
end_pos = file_pos + len(line)
hints.append(Hint(patches=(Patch(left=file_pos, right=end_pos, path=path_id),)))
file_pos = end_pos

# Do not consume the file-terminating newline.
if i == len(lines) - 1 and line.endswith(b'\n'):
end_pos -= 1

if end_pos > file_pos:
hints.append(Hint(patches=(Patch(left=file_pos, right=end_pos, path=path_id),)))
file_pos += len(line)

def _generate_topformflat_hints(
self,
Expand Down
19 changes: 16 additions & 3 deletions cvise/tests/test_lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ def is_valid_brace_sequence(s: bytes) -> bool:
return balance == 0


def test_trailing_newline_preserved(tmp_path: Path, input_path: Path):
"""Test that removing the last line doesn't eat the trailing newline."""
input_path.write_bytes(b'int x = 2;\nint main() {\n}\n')
p, state = init_pass('None', tmp_path, input_path)
all_transforms = collect_all_transforms(p, state, input_path)

for transform in all_transforms:
assert transform.endswith(b'\n')

# Deleting the last line `}\n` now leaves the `\n` behind.
assert b'int x = 2;\nint main() {\n\n' in all_transforms


def test_func_namespace_level0(tmp_path: Path, input_path: Path):
"""Test that arg=0 deletes top-level functions and namespaces."""
input_path.write_text(
Expand Down Expand Up @@ -808,10 +821,10 @@ def test_multi_file_arg_none(tmp_path: Path):
all_transforms = collect_all_transforms_dir(p, state, input_dir)

assert (('bar.h', b'x = 1;\n'), ('foo.cc', b'char\nbar() {}\n')) in all_transforms
assert (('bar.h', b'int\n'), ('foo.cc', b'char\nbar() {}\n')) in all_transforms
assert (('bar.h', b'int\n\n'), ('foo.cc', b'char\nbar() {}\n')) in all_transforms
assert (('bar.h', b'int\nx = 1;\n'), ('foo.cc', b'bar() {}\n')) in all_transforms
assert (('bar.h', b'int\nx = 1;\n'), ('foo.cc', b'char\n')) in all_transforms
assert (('bar.h', b''), ('foo.cc', b'')) in all_transforms
assert (('bar.h', b'int\nx = 1;\n'), ('foo.cc', b'char\n\n')) in all_transforms
assert (('bar.h', b'\n'), ('foo.cc', b'\n')) in all_transforms


def test_multi_file_arg_0(tmp_path: Path):
Expand Down
Loading