1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
from __future__ import annotations
from pathlib import Path
import pytest
from pygit2 import Repository, Signature, init_repository
from pygittools.tui.commit_draft import (
commit_editmsg_path,
load_commit_draft,
save_commit_draft,
)
SIG = Signature("alice", "alice@example.com")
@pytest.fixture
def repo(tmp_path: Path) -> Repository:
repo_path = tmp_path / "repo"
repo_path.mkdir()
return init_repository(str(repo_path), bare=False)
def test_load_returns_empty_when_missing(tmp_path: Path) -> None:
assert load_commit_draft(tmp_path) == ""
def test_roundtrip_single_line_message(tmp_path: Path) -> None:
save_commit_draft(tmp_path, "feat: add draft persistence")
assert load_commit_draft(tmp_path) == "feat: add draft persistence"
assert commit_editmsg_path(tmp_path).read_text(encoding="utf-8") == "feat: add draft persistence\n"
def test_load_ignores_git_comment_lines(tmp_path: Path) -> None:
commit_editmsg_path(tmp_path).write_text(
"feat: keep me\n\n# Please enter the commit message\n",
encoding="utf-8",
)
assert load_commit_draft(tmp_path) == "feat: keep me"
def test_save_empty_removes_existing_file(tmp_path: Path) -> None:
save_commit_draft(tmp_path, "wip")
path = commit_editmsg_path(tmp_path)
assert path.is_file()
save_commit_draft(tmp_path, "")
assert not path.exists()
def test_load_returns_empty_when_draft_matches_head(repo: Repository) -> None:
tree = repo.index.write_tree()
repo.create_commit("HEAD", SIG, SIG, "feat: shipped", tree, [])
save_commit_draft(Path(repo.path), "feat: shipped")
assert load_commit_draft(Path(repo.path), repo) == ""
def test_load_returns_draft_when_it_differs_from_head(repo: Repository) -> None:
tree = repo.index.write_tree()
repo.create_commit("HEAD", SIG, SIG, "feat: shipped", tree, [])
save_commit_draft(Path(repo.path), "feat: next change")
assert load_commit_draft(Path(repo.path), repo) == "feat: next change"
def test_read_draft_ignores_unreadable_file(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
path = commit_editmsg_path(tmp_path)
path.write_text("draft\n", encoding="utf-8")
def fail_read_text(self: Path, encoding: str = "utf-8") -> str:
raise OSError("nope")
monkeypatch.setattr(Path, "read_text", fail_read_text)
assert load_commit_draft(tmp_path) == ""
def test_load_returns_draft_when_head_unavailable(repo: Repository) -> None:
save_commit_draft(Path(repo.path), "wip")
assert load_commit_draft(Path(repo.path), repo) == "wip"
def test_save_commit_draft_ignores_os_error(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
def fail_write_text(self: Path, data: str, encoding: str = "utf-8") -> None:
raise OSError("disk full")
monkeypatch.setattr(Path, "write_text", fail_write_text)
save_commit_draft(tmp_path, "ignored")