151 lines
4.9 KiB
Python
151 lines
4.9 KiB
Python
"""Tests for task move-completed-tasks-to-complete-folder.
|
|
|
|
Covers R1-R5 from tasks/move-completed-tasks-to-complete-folder/SPEC.md.
|
|
"""
|
|
|
|
import json
|
|
import importlib.util
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
_STATUS_PATH = Path.home() / ".automaton" / "scripts" / "status.py"
|
|
_spec = importlib.util.spec_from_file_location("st", _STATUS_PATH)
|
|
st = importlib.util.module_from_spec(_spec)
|
|
_spec.loader.exec_module(st)
|
|
|
|
|
|
class TestTaskDirFallback:
|
|
def test_task_dir_returns_regular_path(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
task_dir = project / ".automaton" / "tasks" / "my-task"
|
|
task_dir.mkdir(parents=True)
|
|
assert st._task_dir("my-task", str(project)) == task_dir
|
|
|
|
def test_task_dir_fallback_to_completed(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
completed = project / ".automaton" / "tasks" / "complete" / "my-task"
|
|
completed.mkdir(parents=True)
|
|
result = st._task_dir("my-task", str(project))
|
|
assert result == completed
|
|
|
|
def test_task_dir_prefers_regular_over_completed(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
regular = project / ".automaton" / "tasks" / "my-task"
|
|
regular.mkdir(parents=True)
|
|
completed = project / ".automaton" / "tasks" / "complete" / "my-task"
|
|
completed.mkdir(parents=True)
|
|
result = st._task_dir("my-task", str(project))
|
|
assert result == regular
|
|
|
|
|
|
class TestAllTaskDirsExcludesCompleted:
|
|
def test_all_task_dirs_excludes_completed(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
base = project / ".automaton" / "tasks"
|
|
(base / "active-task").mkdir(parents=True)
|
|
(base / "complete" / "done-task").mkdir(parents=True)
|
|
tasks = st._all_task_dirs(str(project))
|
|
names = {t[0] for t in tasks}
|
|
assert "active-task" in names
|
|
assert "done-task" not in names
|
|
|
|
|
|
class TestCompleteMovesDir:
|
|
def _make_task(self, project, name, phase="referee"):
|
|
task_dir = project / ".automaton" / "tasks" / name
|
|
task_dir.mkdir(parents=True)
|
|
(task_dir / ".state").write_text(phase + "\n")
|
|
(task_dir / "IMPLEMENTATION.md").write_text("# impl")
|
|
(task_dir / "VERDICT.md").write_text("# passed")
|
|
(task_dir / "CODE_REVIEW.md").write_text("# review")
|
|
(task_dir / "DOC_REVIEW.md").write_text("# doc review")
|
|
(task_dir / ".state.approvals").write_text("")
|
|
return task_dir
|
|
|
|
def test_complete_moves_dir(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
task_dir = self._make_task(project, "done-task")
|
|
|
|
class A:
|
|
pass
|
|
a = A()
|
|
a.task = "done-task"
|
|
a.transition = "complete"
|
|
a.project = str(project)
|
|
|
|
rc = st.cmd_transition(a)
|
|
assert rc == 0
|
|
|
|
completed = project / ".automaton" / "tasks" / "complete" / "done-task"
|
|
assert completed.exists()
|
|
assert (completed / ".state").exists()
|
|
assert (completed / "IMPLEMENTATION.md").exists()
|
|
assert not task_dir.exists()
|
|
|
|
def test_complete_dir_created_on_first_move(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
self._make_task(project, "first-done")
|
|
|
|
class A:
|
|
pass
|
|
a = A()
|
|
a.task = "first-done"
|
|
a.transition = "complete"
|
|
a.project = str(project)
|
|
|
|
rc = st.cmd_transition(a)
|
|
assert rc == 0
|
|
|
|
complete_dir = project / ".automaton" / "tasks" / "complete"
|
|
assert complete_dir.exists()
|
|
assert (complete_dir / "first-done").exists()
|
|
|
|
def test_create_task_refuses_completed(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
self._make_task(project, "old-task")
|
|
(project / ".automaton" / "tasks" / "complete" / "old-task").mkdir(parents=True)
|
|
(project / ".automaton" / "tasks" / "complete" / "old-task" / ".state").write_text("complete\n")
|
|
|
|
class A:
|
|
pass
|
|
a = A()
|
|
a.create_task = "old-task"
|
|
a.project = str(project)
|
|
|
|
rc = st.cmd_create_task(a)
|
|
assert rc == 2
|
|
|
|
def test_transition_refuses_from_complete(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
task_dir = self._make_task(project, "done-task")
|
|
|
|
class A:
|
|
pass
|
|
a = A()
|
|
a.task = "done-task"
|
|
a.transition = "complete"
|
|
a.project = str(project)
|
|
assert st.cmd_transition(a) == 0
|
|
|
|
a.transition = "research"
|
|
rc = st.cmd_transition(a)
|
|
assert rc == 1
|
|
|
|
def test_state_reads_after_move(self, tmp_path):
|
|
project = tmp_path / "proj"
|
|
self._make_task(project, "moved-task")
|
|
|
|
class A:
|
|
pass
|
|
a = A()
|
|
a.task = "moved-task"
|
|
a.transition = "complete"
|
|
a.project = str(project)
|
|
assert st.cmd_transition(a) == 0
|
|
|
|
result = st._task_dir("moved-task", str(project))
|
|
assert result.exists()
|
|
phase = st._read_state(result)
|
|
assert phase == "complete"
|