# TDD Plan — Sprint 5b: Editor Exec + Save Scene

Mirrors the structure of `claude-plan.md`. Tests use pytest + AsyncMock following existing project patterns (see `tests/test_bridge/` for conventions).

---

## 1. Python: Modify `exec_code.py`

### Tests (test_exec_editor.py)

```python
# Test: default context is "game" (backward compatible) — sends "exec" to bridge
# Test: explicit context="editor" sends "exec_editor" to bridge
# Test: explicit context="game" sends "exec" to bridge
# Test: invalid context returns ERROR immediately without bridge call
# Test: empty code returns ERROR regardless of context
# Test: editor context passes timeout_ms in params
# Test: game context passes timeout_ms in params (unchanged behavior)
```

## 2. Python: Create `save_scene.py`

### Tests (test_save_scene.py)

```python
# Test: save_scene calls bridge.request("save_scene", params={}, timeout=5.0)
# Test: save_scene returns bridge response directly (saved, scene_path, scene_name)
# Test: bridge exception propagates (handled by registration layer)
```

## 3. Python: Update `bridge/__init__.py` Registration

### Tests (verify via import)

```python
# Test: godotiq_exec registration accepts context parameter
# Test: godotiq_save_scene is importable from godotiq.tools.bridge
# Test: smoke test — from godotiq.server import mcp succeeds
```

## 4. GDScript: `_handle_exec_editor()` in `godotiq_server.gd`

No Python unit tests for GDScript — verified by live Godot testing. GDScript audit:

```
# Audit: no Python ternaries in _handle_exec_editor
# Audit: no snapf() calls
# Audit: no f-string formatting
# Audit: code validation uses .find() not starts_with for func run():
# Audit: cleanup (remove_child + queue_free) is unconditional
# Audit: blocked patterns match spec: DirAccess.remove, OS.execute, OS.kill, OS.shell_open
# Audit: unique temp filenames in fallback (_temp_exec_%d.gd)
```

## 5. GDScript: `_handle_save_scene()` in `godotiq_server.gd`

```
# Audit: uses EditorInterface.save_scene() with no arguments
# Audit: checks scene_root for null before save
# Audit: defensive handling of save_scene() return value
```

## 6. Update MCP Prompt

```
# Verify: godot_development.md mentions context parameter for exec
# Verify: godot_development.md lists godotiq_save_scene
# Verify: Moving/Placing workflow includes save step
# Verify: exec_editor guidance says "prefer dedicated tools"
```

---

## Test Execution Order

1. Write `test_exec_editor.py` tests first (7 cases)
2. Modify `exec_code.py` to pass tests
3. Write `test_save_scene.py` tests (3 cases)
4. Create `save_scene.py` to pass tests
5. Update `bridge/__init__.py` registrations
6. Run full regression: `pytest tests/ -v` (622 + ~10 new = 632+)
7. GDScript implementation (no TDD — verified by audit + live testing)
8. Prompt update (verified by content checks)
