feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
101
tests/test_git.py
Normal file
101
tests/test_git.py
Normal file
@@ -0,0 +1,101 @@
|
||||
import asyncio
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from codexpi.commands import CommandResult
|
||||
from codexpi.git_service import commit, diff, ensure_identity, repository_tree, snapshot, suggest_commit_message
|
||||
|
||||
|
||||
def git(root: Path, *args: str):
|
||||
subprocess.run(["git", *args], cwd=root, check=True, capture_output=True)
|
||||
|
||||
|
||||
def test_git_snapshot_and_diff(tmp_path: Path):
|
||||
repo = tmp_path / "repo"
|
||||
repo.mkdir()
|
||||
git(repo, "init")
|
||||
git(repo, "config", "user.email", "test@example.invalid")
|
||||
git(repo, "config", "user.name", "CodexPi Test")
|
||||
target = repo / "hello.txt"
|
||||
target.write_text("hello\n")
|
||||
git(repo, "add", "hello.txt")
|
||||
git(repo, "commit", "-m", "initial")
|
||||
target.write_text("hello\nworld\n")
|
||||
state = asyncio.run(snapshot(repo))
|
||||
assert state["is_repository"] is True
|
||||
assert state["files"][0]["path"] == "hello.txt"
|
||||
assert state["history"][0]["subject"] == "initial"
|
||||
assert state["history"][0]["files"] == [{"status": "A", "path": "hello.txt", "old_path": None}]
|
||||
assert "+world" in asyncio.run(diff(repo))
|
||||
|
||||
|
||||
def test_git_snapshot_supports_repository_without_commits(tmp_path: Path):
|
||||
repo = tmp_path / "empty-repo"
|
||||
repo.mkdir()
|
||||
git(repo, "init")
|
||||
state = asyncio.run(snapshot(repo))
|
||||
assert state["is_repository"] is True
|
||||
assert state["history"] == []
|
||||
assert state["branch"] in {"main", "master"}
|
||||
|
||||
|
||||
def test_git_snapshot_reports_plain_directory_without_error(tmp_path: Path):
|
||||
state = asyncio.run(snapshot(tmp_path))
|
||||
assert state == {"is_repository": False, "branch": None, "files": [], "history": []}
|
||||
|
||||
|
||||
def test_repository_tree_includes_tracked_and_visible_untracked_files(tmp_path: Path):
|
||||
repo = tmp_path / "tree"
|
||||
repo.mkdir()
|
||||
git(repo, "init")
|
||||
(repo / "src").mkdir()
|
||||
(repo / "src" / "tracked.py").write_text("print('tracked')\n", encoding="utf-8")
|
||||
(repo / "README.md").write_text("read me\n", encoding="utf-8")
|
||||
(repo / "visible.txt").write_text("visible\n", encoding="utf-8")
|
||||
(repo / "secret.env").write_text("SECRET=value\n", encoding="utf-8")
|
||||
(repo / ".gitignore").write_text("secret.env\n", encoding="utf-8")
|
||||
git(repo, "add", "src/tracked.py", "README.md", ".gitignore")
|
||||
|
||||
tree = asyncio.run(repository_tree(repo))
|
||||
|
||||
assert tree == {
|
||||
"files": [".gitignore", "README.md", "src/tracked.py", "visible.txt"],
|
||||
"total": 4,
|
||||
"truncated": False,
|
||||
}
|
||||
|
||||
|
||||
def test_git_commit_configures_missing_identity_locally(tmp_path: Path):
|
||||
repo = tmp_path / "identity"
|
||||
repo.mkdir()
|
||||
git(repo, "init")
|
||||
(repo / "hello.txt").write_text("hello\n", encoding="utf-8")
|
||||
git(repo, "add", "hello.txt")
|
||||
asyncio.run(commit(repo, "Premier commit", "Example User"))
|
||||
name = subprocess.run(["git", "config", "--local", "user.name"], cwd=repo, check=True, capture_output=True, text=True).stdout.strip()
|
||||
email = subprocess.run(["git", "config", "--local", "user.email"], cwd=repo, check=True, capture_output=True, text=True).stdout.strip()
|
||||
assert name == "Example User"
|
||||
assert email == "example-user@codexpi.local"
|
||||
|
||||
|
||||
def test_git_identity_preserves_existing_repository_values(tmp_path: Path):
|
||||
repo = tmp_path / "existing-identity"
|
||||
repo.mkdir()
|
||||
git(repo, "init")
|
||||
git(repo, "config", "user.name", "Existing Author")
|
||||
git(repo, "config", "user.email", "existing@example.test")
|
||||
assert asyncio.run(ensure_identity(repo, "Other User")) == {"name": "Existing Author", "email": "existing@example.test"}
|
||||
|
||||
|
||||
def test_codex_suggests_a_single_line_commit_message(tmp_path: Path, monkeypatch):
|
||||
calls = 0
|
||||
|
||||
async def fake_command(argv, **_kwargs):
|
||||
nonlocal calls
|
||||
calls += 1
|
||||
if calls == 1:
|
||||
return CommandResult(argv, 0, " M app.py\n", "")
|
||||
return CommandResult(argv, 0, '{"type":"item.completed","item":{"type":"agent_message","text":"Améliore le flux de commit automatique"}}\n', "")
|
||||
|
||||
monkeypatch.setattr("codexpi.git_service.run_command", fake_command)
|
||||
assert asyncio.run(suggest_commit_message(tmp_path, "codex")) == "Améliore le flux de commit automatique"
|
||||
Reference in New Issue
Block a user