🚧 WIP
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
"""Unit tests for porcelain parsing and ChangeType mapping (Section 6)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from git_auto_tracker.changes.models import ChangeType
|
||||
from git_auto_tracker.errors import GitError
|
||||
from git_auto_tracker.git.status import RawStatusEntry, parse_porcelain_z
|
||||
|
||||
|
||||
def _build(entries: list[tuple[str, str, str | None]]) -> bytes:
|
||||
"""Serialize porcelain -z records: 'XY path' + optional origin path."""
|
||||
parts: list[bytes] = []
|
||||
for xy, path, previous in entries:
|
||||
parts.append(f"{xy} {path}".encode())
|
||||
if previous:
|
||||
parts.append(previous.encode())
|
||||
return b"\x00".join(parts) + b"\x00"
|
||||
|
||||
|
||||
class TestParsePorcelainZ:
|
||||
def test_modified(self) -> None:
|
||||
raw = _build([(" M", "config.xml", None)])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.path == "config.xml"
|
||||
assert entry.change_type is ChangeType.MODIFIED
|
||||
|
||||
def test_untracked_is_added(self) -> None:
|
||||
raw = _build([("??", "new.xml", None)])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.change_type is ChangeType.ADDED
|
||||
|
||||
def test_deleted(self) -> None:
|
||||
raw = _build([(" D", "gone.xml", None)])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.change_type is ChangeType.DELETED
|
||||
|
||||
def test_staged_deletion(self) -> None:
|
||||
raw = _build([("D ", "gone.xml", None)])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.change_type is ChangeType.DELETED
|
||||
|
||||
def test_rename_with_previous(self) -> None:
|
||||
raw = _build([("R ", "new.xml", "old.xml")])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.change_type is ChangeType.RENAMED
|
||||
assert entry.previous_path == "old.xml"
|
||||
|
||||
def test_filenames_with_spaces_and_unicode(self) -> None:
|
||||
raw = _build([(" M", "Station PS101/räumliche Datei.xml", None)])
|
||||
(entry,) = parse_porcelain_z(raw)
|
||||
assert entry.path == "Station PS101/räumliche Datei.xml"
|
||||
|
||||
def test_trailing_empty_chunks_ignored(self) -> None:
|
||||
raw = b"\x00\x00 M a.xml\x00\x00"
|
||||
entries = parse_porcelain_z(raw)
|
||||
assert len(entries) == 1
|
||||
|
||||
def test_invalid_xy_rejected(self) -> None:
|
||||
with pytest.raises(GitError):
|
||||
parse_porcelain_z(b"XX path.xml\x00")
|
||||
|
||||
|
||||
class TestChangeTypeMapping:
|
||||
def test_staged_addition(self) -> None:
|
||||
entry = RawStatusEntry.from_zy_pair("A ", "a.xml", None)
|
||||
assert entry.change_type is ChangeType.ADDED
|
||||
|
||||
def test_staged_rename(self) -> None:
|
||||
entry = RawStatusEntry.from_zy_pair("R ", "a.xml", "b.xml")
|
||||
assert entry.change_type is ChangeType.RENAMED
|
||||
Reference in New Issue
Block a user