Feature: Git worktree sandbox coverage boost As a developer I want to exercise uncovered edge cases in the git worktree sandbox So that code coverage is maximised for git_worktree.py # --- _sanitise_branch_name edge case --- Scenario: Sanitise branch name with all-special-chars falls back to sandbox When gwtcb _sanitise_branch_name is called with "!!!" Then gwtcb the result should be "sandbox" # --- create fails when path is not repo root --- Scenario: Create fails when path is not the repository root Given a gwtcb sandbox pointed at a non-root subdirectory When gwtcb create is called for plan "plan-001" Then a gwtcb SandboxCreationError should be raised And the gwtcb sandbox should be in the "errored" state # --- create times out --- Scenario: Create raises SandboxCreationError on timeout Given a gwtcb sandbox with mocked _run_git that times out When gwtcb create is called expecting a timeout error Then a gwtcb SandboxCreationError should be raised with message "timed out" And the gwtcb sandbox should be in the "errored" state # --- get_path with None worktree_path --- Scenario: get_path raises SandboxStateError when worktree_path is None Given a gwtcb sandbox in CREATED state with None worktree_path When gwtcb get_path is called with "some/file.py" Then a gwtcb SandboxStateError should be raised with message "Worktree path not set" # --- commit with uninitialised worktree --- Scenario: Commit raises SandboxStateError when worktree not initialised Given a gwtcb sandbox in ACTIVE state with no worktree or branch When gwtcb commit is called with message "should fail" Then a gwtcb SandboxStateError should be raised with message "Worktree not initialised" # --- commit with modified files in diff output --- Scenario: Commit parses modified files in diff output Given a gwtcb sandbox ready to commit with modified-file diff output When gwtcb commit is called with message "modify files" Then the gwtcb commit result should include changed file "src/modified.py" And the gwtcb commit result should include added file "src/new.py" And the gwtcb commit result should include deleted file "src/old.py" # --- commit timeout --- Scenario: Commit raises SandboxCommitError on timeout Given a gwtcb sandbox in ACTIVE state ready to commit And gwtcb _run_git is mocked to raise TimeoutExpired on commit When gwtcb commit is called expecting a timeout error Then a gwtcb SandboxCommitError should be raised with message "timed out" And the gwtcb sandbox should be in the "errored" state # --- commit CalledProcessError --- Scenario: Commit raises SandboxCommitError on CalledProcessError Given a gwtcb sandbox in ACTIVE state ready to commit And gwtcb _run_git is mocked to raise CalledProcessError on commit When gwtcb commit is called expecting a process error Then a gwtcb SandboxCommitError should be raised with message "Failed to commit" And the gwtcb sandbox should be in the "errored" state # --- rollback with uninitialised worktree --- Scenario: Rollback raises SandboxStateError when worktree not initialised Given a gwtcb sandbox in ACTIVE state with no worktree or base commit When gwtcb rollback is called expecting a state error Then a gwtcb SandboxStateError should be raised with message "Worktree not initialised" # --- rollback timeout --- Scenario: Rollback raises SandboxRollbackError on timeout Given a gwtcb sandbox in ACTIVE state ready to rollback And gwtcb _run_git is mocked to raise TimeoutExpired on rollback When gwtcb rollback is called expecting a timeout error Then a gwtcb SandboxRollbackError should be raised with message "timed out" And the gwtcb sandbox should be in the "errored" state # --- rollback CalledProcessError --- Scenario: Rollback raises SandboxRollbackError on CalledProcessError Given a gwtcb sandbox in ACTIVE state ready to rollback And gwtcb _run_git is mocked to raise CalledProcessError on rollback When gwtcb rollback is called expecting a process error Then a gwtcb SandboxRollbackError should be raised with message "Failed to rollback" And the gwtcb sandbox should be in the "errored" state # --- cleanup with worktree remove failure --- Scenario: Cleanup falls back to shutil when git worktree remove fails Given a gwtcb sandbox with a worktree directory that exists And gwtcb _run_git is mocked to fail on worktree remove When gwtcb cleanup is called Then the gwtcb sandbox should be in the "cleaned_up" state # --- cleanup with branch delete failure --- Scenario: Cleanup warns and continues when branch delete fails Given a gwtcb sandbox with a branch name set but no worktree directory And gwtcb _run_git is mocked to fail on branch delete When gwtcb cleanup is called Then the gwtcb sandbox should be in the "cleaned_up" state