8Integration tests for ``oct git restore`` (L3).
12- Verify ``oct git restore <path>`` reverts unstaged working-tree
14- Verify ``oct git restore --staged <path>`` unstages from the index
15 without touching the working tree.
16- Verify ``--all`` enumerates in-scope paths.
17- Verify the confirmation prompt for ``--staged --all`` (and
19- Verify path-scope filtering (paths outside the project root are
20 skipped) and JSON output.
27 L3 -- assertion details
31- All tests use subprocess invocation against ``oct.cli``.
32- All tests use tmp_path fixtures so they are automatically cleaned up.
39from pathlib
import Path
43from tests.tests_git.conftest
import _git
47 return shutil.which(
"git")
is not None
51 root: Path, *extra_args: str,
52) -> subprocess.CompletedProcess:
53 return subprocess.run(
54 [sys.executable,
"-m",
"oct.cli",
"git",
"restore", *extra_args],
55 cwd=root, capture_output=
True, text=
True,
60 result = subprocess.run(
61 [
"git",
"diff",
"--cached",
"--name-only"],
62 cwd=repo, check=
True, capture_output=
True, text=
True,
65 line.strip()
for line
in result.stdout.splitlines()
if line.strip()
76 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
78 f = temp_git_project /
"src" /
"tracked.txt"
79 f.write_text(
"v1\n", encoding=
"utf-8")
80 _git(temp_git_project,
"add",
"src/tracked.txt")
81 _git(temp_git_project,
"commit",
"-m",
"init",
"--quiet")
84 f.write_text(
"v2\n", encoding=
"utf-8")
86 result =
_run_restore(temp_git_project,
"src/tracked.txt")
87 assert result.returncode == 0, result.stderr
89 assert f.read_text(encoding=
"utf-8") ==
"v1\n"
99 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
101 self, temp_git_project: Path,
103 f = temp_git_project /
"src" /
"tracked.txt"
104 f.write_text(
"v1\n", encoding=
"utf-8")
105 _git(temp_git_project,
"add",
"src/tracked.txt")
106 _git(temp_git_project,
"commit",
"-m",
"init",
"--quiet")
109 f.write_text(
"v2\n", encoding=
"utf-8")
110 _git(temp_git_project,
"add",
"src/tracked.txt")
114 temp_git_project,
"--staged",
"src/tracked.txt",
116 assert result.returncode == 0, result.stderr
118 assert "src/tracked.txt" not in _staged_names(temp_git_project)
120 assert f.read_text(encoding=
"utf-8") ==
"v2\n"
130 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
132 self, temp_git_project: Path,
134 a = temp_git_project /
"src" /
"a.txt"
135 b = temp_git_project /
"src" /
"b.txt"
136 a.write_text(
"v1\n", encoding=
"utf-8")
137 b.write_text(
"v1\n", encoding=
"utf-8")
138 _git(temp_git_project,
"add",
"src/a.txt",
"src/b.txt")
139 _git(temp_git_project,
"commit",
"-m",
"init",
"--quiet")
141 a.write_text(
"v2\n", encoding=
"utf-8")
142 b.write_text(
"v2\n", encoding=
"utf-8")
145 assert result.returncode == 0, result.stderr
146 assert a.read_text(encoding=
"utf-8") ==
"v1\n"
147 assert b.read_text(encoding=
"utf-8") ==
"v1\n"
149 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
151 self, temp_git_project: Path,
153 f = temp_git_project /
"src" /
"tracked.txt"
154 f.write_text(
"v1\n", encoding=
"utf-8")
155 _git(temp_git_project,
"add",
"src/tracked.txt")
156 _git(temp_git_project,
"commit",
"-m",
"init",
"--quiet")
157 f.write_text(
"v2\n", encoding=
"utf-8")
158 _git(temp_git_project,
"add",
"src/tracked.txt")
161 temp_git_project,
"--staged",
"--all",
"--yes",
163 assert result.returncode == 0, result.stderr
164 assert "src/tracked.txt" not in _staged_names(temp_git_project)
174 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
176 self, temp_git_project: Path,
179 assert result.returncode == 1
180 assert "provide PATHS" in result.stderr.lower() \
181 or "use --all" in result.stderr.lower()
191 @pytest.mark.skipif(not _git_available(), reason=
"git not on PATH")
193 f = temp_git_project /
"src" /
"tracked.txt"
194 f.write_text(
"v1\n", encoding=
"utf-8")
195 _git(temp_git_project,
"add",
"src/tracked.txt")
196 _git(temp_git_project,
"commit",
"-m",
"init",
"--quiet")
197 f.write_text(
"v2\n", encoding=
"utf-8")
200 temp_git_project,
"--json",
"src/tracked.txt",
202 assert result.returncode == 0, result.stderr
203 data = json.loads(result.stdout)
204 assert data[
"operation"] ==
"restore"
205 assert data[
"staged"]
is False
206 assert "src/tracked.txt" in data[
"paths_restored"]
207 assert data[
"exit_code"] == 0
None test_staged_all_with_yes_skips_prompt(self, Path temp_git_project)
None test_all_restores_every_modified(self, Path temp_git_project)
None test_no_paths_no_all_errors(self, Path temp_git_project)
None test_json_schema(self, Path temp_git_project)
None test_unstage_preserves_working_tree(self, Path temp_git_project)
None test_restore_single_file(self, Path temp_git_project)
list[str] _staged_names(Path repo)
subprocess.CompletedProcess _run_restore(Path root, *str extra_args)