From 08734532cec78308671ac7db2169ca51e6e1ca0b Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 1 Mar 2026 14:22:53 -0500 Subject: [PATCH] test(mock): add standalone test for mock_gemini_cli routing 4 tests verify: epic prompt -> Track JSON, sprint prompt -> Ticket JSON with correct field names, worker prompt -> plain text, tool-result -> plain text. All pass in 0.57s. Co-Authored-By: Claude Sonnet 4.6 --- scripts/tasks/task_1_3_mock_test.toml | 20 ++++++++ tests/test_mock_gemini_cli.py | 70 +++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 scripts/tasks/task_1_3_mock_test.toml create mode 100644 tests/test_mock_gemini_cli.py diff --git a/scripts/tasks/task_1_3_mock_test.toml b/scripts/tasks/task_1_3_mock_test.toml new file mode 100644 index 0000000..4b75d55 --- /dev/null +++ b/scripts/tasks/task_1_3_mock_test.toml @@ -0,0 +1,20 @@ +role = "tier3-worker" +docs = ["conductor/workflow.md", "tests/mock_gemini_cli.py"] +prompt = """ +Create tests/test_mock_gemini_cli.py — a standalone pytest test file that invokes tests/mock_gemini_cli.py via subprocess.run() and verifies its routing logic. + +TEST CASES (4 functions): +1. test_epic_prompt_returns_track_json — send a prompt containing 'PATH: Epic Initialization' via stdin. Assert: stdout contains valid JSON list, each item has 'id' and 'title', no 'function_call' substring anywhere in stdout. +2. test_sprint_prompt_returns_ticket_json — send 'Please generate the implementation tickets for this track.' via stdin. Assert: stdout contains valid JSON list, each item has 'id', 'description', 'status', 'assigned_to'. No 'function_call' in stdout. +3. test_worker_prompt_returns_plain_text — send 'You are assigned to Ticket T1.\nTask Description: do something' via stdin. Assert: stdout is non-empty, no 'function_call' in stdout. +4. test_tool_result_prompt_returns_plain_text — send a prompt containing the substring 'role": "tool' via stdin. Assert: returncode == 0 and stdout is non-empty. + +IMPLEMENTATION DETAILS: +- Use subprocess.run(['uv', 'run', 'python', 'tests/mock_gemini_cli.py'], input=prompt, capture_output=True, text=True, cwd='.') +- Helper function get_message_content(stdout): split stdout by newlines, parse each line as JSON, find the dict with type=='message', return its 'content' field. Return '' if not found. +- For JSON assertion tests: call get_message_content, then json.loads() the content, assert isinstance(result, list), assert len(result) > 0. +- Each test asserts returncode == 0. +- Imports: import subprocess, json, pytest +- Use exactly 1-space indentation for Python code. +- Create the file tests/test_mock_gemini_cli.py. +""" diff --git a/tests/test_mock_gemini_cli.py b/tests/test_mock_gemini_cli.py new file mode 100644 index 0000000..1864e62 --- /dev/null +++ b/tests/test_mock_gemini_cli.py @@ -0,0 +1,70 @@ +import subprocess +import json +import pytest + + +def get_message_content(stdout): + for line in stdout.splitlines(): + line = line.strip() + if not line: + continue + try: + obj = json.loads(line) + if isinstance(obj, dict) and obj.get('type') == 'message': + return obj.get('content', '') + except json.JSONDecodeError: + continue + return '' + + +def run_mock(prompt): + return subprocess.run( + ['uv', 'run', 'python', 'tests/mock_gemini_cli.py'], + input=prompt, + capture_output=True, + text=True, + cwd='.' + ) + + +def test_epic_prompt_returns_track_json(): + result = run_mock('PATH: Epic Initialization — please produce tracks') + assert result.returncode == 0 + assert 'function_call' not in result.stdout + content = get_message_content(result.stdout) + parsed = json.loads(content) + assert isinstance(parsed, list) + assert len(parsed) > 0 + for item in parsed: + assert 'id' in item + assert 'title' in item + + +def test_sprint_prompt_returns_ticket_json(): + result = run_mock('Please generate the implementation tickets for this track.') + assert result.returncode == 0 + assert 'function_call' not in result.stdout + content = get_message_content(result.stdout) + parsed = json.loads(content) + assert isinstance(parsed, list) + assert len(parsed) > 0 + for item in parsed: + assert 'id' in item + assert 'description' in item + assert 'status' in item + assert 'assigned_to' in item + + +def test_worker_prompt_returns_plain_text(): + result = run_mock('You are assigned to Ticket T1.\nTask Description: do something') + assert result.returncode == 0 + assert 'function_call' not in result.stdout + content = get_message_content(result.stdout) + assert content != '' + + +def test_tool_result_prompt_returns_plain_text(): + result = run_mock('Here are the results: {"role": "tool", "content": "done"}') + assert result.returncode == 0 + content = get_message_content(result.stdout) + assert content != ''