Download tests/tools/test_patch_parser.py from lenson78/hermes: direct link, hf CLI and curl.
- Browser
- Download file 4.73 kB
-
https://huggingface.co/spaces/lenson78/hermes/resolve/main/tests/tools/test_patch_parser.py
- Command line
-
hf download hf://spaces/lenson78/hermes/tests/tools/test_patch_parser.py
-
curl -L -o test_patch_parser.py https://huggingface.co/spaces/lenson78/hermes/resolve/main/tests/tools/test_patch_parser.py
4.73 kB
| """Tests for the V4A patch format parser.""" | |
| from types import SimpleNamespace | |
| from tools.patch_parser import ( | |
| OperationType, | |
| apply_v4a_operations, | |
| parse_v4a_patch, | |
| ) | |
| class TestParseUpdateFile: | |
| def test_basic_update(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Update File: src/main.py | |
| @@ def greet @@ | |
| def greet(): | |
| - print("hello") | |
| + print("hi") | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| op = ops[0] | |
| assert op.operation == OperationType.UPDATE | |
| assert op.file_path == "src/main.py" | |
| assert len(op.hunks) == 1 | |
| hunk = op.hunks[0] | |
| assert hunk.context_hint == "def greet" | |
| prefixes = [l.prefix for l in hunk.lines] | |
| assert " " in prefixes | |
| assert "-" in prefixes | |
| assert "+" in prefixes | |
| def test_multiple_hunks(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Update File: f.py | |
| @@ first @@ | |
| a | |
| -b | |
| +c | |
| @@ second @@ | |
| x | |
| -y | |
| +z | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| assert len(ops[0].hunks) == 2 | |
| assert ops[0].hunks[0].context_hint == "first" | |
| assert ops[0].hunks[1].context_hint == "second" | |
| class TestParseAddFile: | |
| def test_add_file(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Add File: new/module.py | |
| +import os | |
| + | |
| +print("hello") | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| op = ops[0] | |
| assert op.operation == OperationType.ADD | |
| assert op.file_path == "new/module.py" | |
| assert len(op.hunks) == 1 | |
| contents = [l.content for l in op.hunks[0].lines if l.prefix == "+"] | |
| assert contents[0] == "import os" | |
| assert contents[2] == 'print("hello")' | |
| class TestParseDeleteFile: | |
| def test_delete_file(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Delete File: old/stuff.py | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| assert ops[0].operation == OperationType.DELETE | |
| assert ops[0].file_path == "old/stuff.py" | |
| class TestParseMoveFile: | |
| def test_move_file(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Move File: old/path.py -> new/path.py | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| assert ops[0].operation == OperationType.MOVE | |
| assert ops[0].file_path == "old/path.py" | |
| assert ops[0].new_path == "new/path.py" | |
| class TestParseInvalidPatch: | |
| def test_empty_patch_returns_empty_ops(self): | |
| ops, err = parse_v4a_patch("") | |
| assert err is None | |
| assert ops == [] | |
| def test_no_begin_marker_still_parses(self): | |
| patch = """\ | |
| *** Update File: f.py | |
| line1 | |
| -old | |
| +new | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 1 | |
| def test_multiple_operations(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Add File: a.py | |
| +content_a | |
| *** Delete File: b.py | |
| *** Update File: c.py | |
| keep | |
| -remove | |
| +add | |
| *** End Patch""" | |
| ops, err = parse_v4a_patch(patch) | |
| assert err is None | |
| assert len(ops) == 3 | |
| assert ops[0].operation == OperationType.ADD | |
| assert ops[1].operation == OperationType.DELETE | |
| assert ops[2].operation == OperationType.UPDATE | |
| class TestApplyUpdate: | |
| def test_preserves_non_prefix_pipe_characters_in_unmodified_lines(self): | |
| patch = """\ | |
| *** Begin Patch | |
| *** Update File: sample.py | |
| @@ result @@ | |
| result = 1 | |
| - return result | |
| + return result + 1 | |
| *** End Patch""" | |
| operations, err = parse_v4a_patch(patch) | |
| assert err is None | |
| class FakeFileOps: | |
| def __init__(self): | |
| self.written = None | |
| def read_file(self, path, offset=1, limit=500): | |
| return SimpleNamespace( | |
| content=( | |
| 'def run():\n' | |
| ' cmd = "echo a | sed s/a/b/"\n' | |
| ' result = 1\n' | |
| ' return result' | |
| ), | |
| error=None, | |
| ) | |
| def write_file(self, path, content): | |
| self.written = content | |
| return SimpleNamespace(error=None) | |
| file_ops = FakeFileOps() | |
| result = apply_v4a_operations(operations, file_ops) | |
| assert result.success is True | |
| assert file_ops.written == ( | |
| 'def run():\n' | |
| ' cmd = "echo a | sed s/a/b/"\n' | |
| ' result = 1\n' | |
| ' return result + 1' | |
| ) | |