diff --git a/conductor/tests/diag_subagent.py b/conductor/tests/diag_subagent.py deleted file mode 100644 index e4b290aa..00000000 --- a/conductor/tests/diag_subagent.py +++ /dev/null @@ -1,23 +0,0 @@ -import subprocess -import sys - -def run_diag(role: str, prompt: str) -> str: - print(f"--- Running Diag for {role} ---") - cmd = [sys.executable, "scripts/mma_exec.py", "--role", role, prompt] - try: - result = subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8') - print("STDOUT:") - print(result.stdout) - print("STDERR:") - print(result.stderr) - return result.stdout - except Exception as e: - print(f"FAILED: {e}") - return str(e) - -if __name__ == "__main__": -# Test 1: Simple read - print("TEST 1: read_file") - run_diag("tier3-worker", "Read the file 'pyproject.toml' and tell me the version of the project. ONLY the version string.") - print("\nTEST 2: run_shell_command") - run_diag("tier3-worker", "Use run_shell_command to execute 'echo HELLO_SUBAGENT' and return the output. ONLY the output.") diff --git a/conductor/tests/test_gui_markdown_table_width.py b/conductor/tests/test_gui_markdown_table_width.py deleted file mode 100644 index 8a458d71..00000000 --- a/conductor/tests/test_gui_markdown_table_width.py +++ /dev/null @@ -1,64 +0,0 @@ -import unittest -from unittest.mock import MagicMock, patch -import sys -import os - -# Ensure project root is in path so we can import src.gui_2 -project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -if project_root not in sys.path: - sys.path.insert(0, project_root) - -class TestMarkdownTableWidth(unittest.TestCase): - def test_render_discussion_entry_full_width(self): - """ - Verify that render_discussion_entry calls imgui.dummy with the full available width. - """ - # Mock all dependencies to avoid side effects and complex setup during import/execution - with patch('src.gui_2.imgui') as mock_imgui, \ - patch('src.gui_2.imscope') as mock_imscope, \ - patch('src.gui_2.theme') as mock_theme, \ - patch('src.gui_2.project_manager') as mock_pm, \ - patch('src.gui_2.render_thinking_trace') as mock_rtt, \ - patch('src.gui_2.render_discussion_entry_read_mode') as mock_rderm: - - # 1. Setup available width and coordinates - expected_width = 850.0 - mock_avail = MagicMock() - mock_avail.x = expected_width - mock_imgui.get_content_region_avail.return_value = mock_avail - - # Mock ImVec2 to return a simple tuple for easier assertion - mock_imgui.ImVec2.side_effect = lambda x, y: (x, y) - - # 3. Mock app and entry state - mock_app = MagicMock() - mock_app.disc_roles = ["User", "Assistant"] - - entry = { - "role": "User", - "content": "Hello world", - "collapsed": False, - "read_mode": False - } - - # Mock interactive elements - mock_imgui.begin_combo.return_value = False - mock_imgui.button.return_value = False - mock_imgui.input_text_multiline.return_value = (False, entry["content"]) - - # 4. Import the function within the patch context - from src.gui_2 import render_discussion_entry - - # 5. Execute the function - render_discussion_entry(mock_app, entry, 0) - - # 6. Verification - # The function should call imgui.dummy(imgui.ImVec2(full_width, 0)) - mock_imgui.dummy.assert_any_call((expected_width, 0.0)) - - # CRITICAL: Verify newline or spacing is called to prevent squashing - # We expect this to fail currently - assert mock_imgui.new_line.called or mock_imgui.spacing.called - -if __name__ == '__main__': - unittest.main() diff --git a/conductor/tests/test_gui_monolithic_restoration.py b/conductor/tests/test_gui_monolithic_restoration.py deleted file mode 100644 index ef680f76..00000000 --- a/conductor/tests/test_gui_monolithic_restoration.py +++ /dev/null @@ -1,33 +0,0 @@ -import inspect -import sys -import os -import pytest - -# Ensure project root is in path -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) - -def test_gui_monolithic_symbols(): - try: - from src.gui_2 import App, render_discussion_entry, render_thinking_trace - import src.gui_2 - except ImportError as e: - pytest.fail(f"FAILURE: Could not import from src.gui_2: {e}") - - # Verify App is importable - assert App is not None - - # Verify render_discussion_entry is in src.gui_2 - assert hasattr(src.gui_2, 'render_discussion_entry'), "render_discussion_entry missing from src.gui_2" - - # Verify it's defined in src.gui_2, not imported - mod = inspect.getmodule(render_discussion_entry) - assert mod is not None, "Could not determine module for render_discussion_entry" - assert mod.__name__ == 'src.gui_2', f"render_discussion_entry expected in src.gui_2, but found in {mod.__name__}" - - # Verify render_thinking_trace is in src.gui_2 - assert hasattr(src.gui_2, 'render_thinking_trace'), "render_thinking_trace missing from src.gui_2" - - # Verify it's defined in src.gui_2, not imported - mod = inspect.getmodule(render_thinking_trace) - assert mod is not None, "Could not determine module for render_thinking_trace" - assert mod.__name__ == 'src.gui_2', f"render_thinking_trace expected in src.gui_2, but found in {mod.__name__}" diff --git a/conductor/tests/test_imgui_scopes_id_stability.py b/conductor/tests/test_imgui_scopes_id_stability.py deleted file mode 100644 index 5bae1bd8..00000000 --- a/conductor/tests/test_imgui_scopes_id_stability.py +++ /dev/null @@ -1,29 +0,0 @@ -import pytest -from unittest.mock import patch, MagicMock -from src.imgui_scopes import _ScopeId -import src.imgui_scopes as imgui_scopes - -def test_scope_id_string(): - with patch('src.imgui_scopes.imgui') as mock_imgui: - sid = _ScopeId("test_id") - with sid: - pass - mock_imgui.push_id.assert_called_once_with("test_id") - mock_imgui.pop_id.assert_called_once() - -def test_scope_id_int(): - with patch('src.imgui_scopes.imgui') as mock_imgui: - # Python type hint is str, but we test runtime resilience - sid = _ScopeId(1234) - with sid: - pass - # Verify it was converted to string to prevent low-level crashes - mock_imgui.push_id.assert_called_once_with("1234") - mock_imgui.pop_id.assert_called_once() - -def test_id_helper_function(): - with patch('src.imgui_scopes.imgui') as mock_imgui: - with imgui_scopes.id(42): - pass - mock_imgui.push_id.assert_called_once_with("42") - mock_imgui.pop_id.assert_called_once() diff --git a/conductor/tests/test_infrastructure.py b/conductor/tests/test_infrastructure.py deleted file mode 100644 index 9423d25d..00000000 --- a/conductor/tests/test_infrastructure.py +++ /dev/null @@ -1,60 +0,0 @@ -import subprocess -from unittest.mock import patch, MagicMock - -def run_ps_script(role: str, prompt: str) -> subprocess.CompletedProcess: - """Helper to run the run_subagent.ps1 script.""" - # Using -File is safer and handles arguments better - cmd = [ - "powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", - "-File", "./scripts/run_subagent.ps1", - "-Role", role, - "-Prompt", prompt - ] - result = subprocess.run(cmd, capture_output=True, text=True) - if result.stdout: - print(f"\n[Sub-Agent {role} Output]:\n{result.stdout}") - if result.stderr: - print(f"\n[Sub-Agent {role} Error]:\n{result.stderr}") - return result - -@patch('subprocess.run') -def test_subagent_script_qa_live(mock_run) -> None: - """Verify that the QA role works and returns a compressed fix.""" - mock_run.return_value = MagicMock(returncode=0, stdout='Fix the division by zero error.', stderr='') - prompt = "Traceback (most recent call last): File 'test.py', line 1, in 1/0 ZeroDivisionError: division by zero" - result = run_ps_script("QA", prompt) - assert result.returncode == 0 - # Expected output should mention the fix for division by zero - assert "zero" in result.stdout.lower() - # It should be short (QA agents compress) - assert len(result.stdout.split()) < 40 - -@patch('subprocess.run') -def test_subagent_script_worker_live(mock_run) -> None: - """Verify that the Worker role works and returns code.""" - mock_run.return_value = MagicMock(returncode=0, stdout='def hello(): return "hello world"', stderr='') - prompt = "Write a python function that returns 'hello world'" - result = run_ps_script("Worker", prompt) - assert result.returncode == 0 - assert "def" in result.stdout.lower() - assert "hello" in result.stdout.lower() - -@patch('subprocess.run') -def test_subagent_script_utility_live(mock_run) -> None: - """Verify that the Utility role works.""" - mock_run.return_value = MagicMock(returncode=0, stdout='True', stderr='') - prompt = "Tell me 'True' if 1+1=2, otherwise 'False'" - result = run_ps_script("Utility", prompt) - assert result.returncode == 0 - assert "true" in result.stdout.lower() - -@patch('subprocess.run') -def test_subagent_isolation_live(mock_run) -> None: - """Verify that the sub-agent is stateless and does not see the parent's conversation context.""" - mock_run.return_value = MagicMock(returncode=0, stdout='UNKNOWN', stderr='') - # This prompt asks the sub-agent about a 'secret' mentioned only here, not in its prompt. - prompt = "What is the secret code I just told you? If I didn't tell you, say 'UNKNOWN'." - result = run_ps_script("Utility", prompt) - assert result.returncode == 0 - # A stateless agent should not know any previous context. - assert "unknown" in result.stdout.lower() diff --git a/conductor/tests/test_mma_exec.py b/conductor/tests/test_mma_exec.py deleted file mode 100644 index acb1b785..00000000 --- a/conductor/tests/test_mma_exec.py +++ /dev/null @@ -1,140 +0,0 @@ -import pytest -import os -from pathlib import Path -from unittest.mock import patch, MagicMock -from scripts.mma_exec import create_parser, get_role_documents, execute_agent, get_model_for_role, get_dependencies - -def test_parser_role_choices() -> None: - """Test that the parser accepts valid roles and the prompt argument.""" - parser = create_parser() - valid_roles = ['tier1', 'tier2', 'tier3', 'tier4'] - test_prompt = "Analyze the codebase for bottlenecks." - for role in valid_roles: - args = parser.parse_args(['--role', role, test_prompt]) - assert args.role == role - assert args.prompt == test_prompt - -def test_parser_invalid_role() -> None: - """Test that the parser rejects roles outside the specified choices.""" - parser = create_parser() - with pytest.raises(SystemExit): - parser.parse_args(['--role', 'tier5', 'Some prompt']) - -def test_parser_prompt_optional() -> None: - """Test that the prompt argument is optional if role is provided (or handled in main).""" - parser = create_parser() - # Prompt is now optional (nargs='?') - args = parser.parse_args(['--role', 'tier3']) - assert args.role == 'tier3' - assert args.prompt is None - -def test_parser_help() -> None: - """Test that the help flag works without raising errors (exits with 0).""" - parser = create_parser() - with pytest.raises(SystemExit) as excinfo: - parser.parse_args(['--help']) - assert excinfo.value.code == 0 - -def test_get_role_documents() -> None: - """Test that get_role_documents returns the correct documentation paths for each tier.""" - assert get_role_documents('tier1') == ['conductor/product.md', 'conductor/product-guidelines.md', 'docs/guide_architecture.md', 'docs/guide_mma.md'] - assert get_role_documents('tier2') == ['conductor/tech-stack.md', 'conductor/workflow.md', 'docs/guide_architecture.md', 'docs/guide_mma.md'] - assert get_role_documents('tier3') == ['docs/guide_architecture.md'] - assert get_role_documents('tier4') == ['docs/guide_architecture.md'] - -def test_get_model_for_role() -> None: - """Test that get_model_for_role returns the correct model for each role.""" - assert get_model_for_role('tier1-orchestrator') == 'gemini-3.1-pro-preview' - assert get_model_for_role('tier2-tech-lead') == 'gemini-3-flash-preview' - assert get_model_for_role('tier3-worker') == 'gemini-3-flash-preview' - assert get_model_for_role('tier4-qa') == 'gemini-2.5-flash-lite' - -def test_execute_agent() -> None: - """ - Test that execute_agent calls subprocess.run with powershell and the correct gemini CLI arguments - including the model specified for the role. - """ - role = "tier3-worker" - prompt = "Write a unit test." - docs = ["file1.py", "docs/spec.md"] - expected_model = "gemini-3-flash-preview" - mock_stdout = "Mocked AI Response" - with patch("subprocess.run") as mock_run: - mock_process = MagicMock() - mock_process.stdout = mock_stdout - mock_process.returncode = 0 - mock_run.return_value = mock_process - result = execute_agent(role, prompt, docs) - mock_run.assert_called_once() - args, kwargs = mock_run.call_args - cmd_list = args[0] - assert cmd_list[0] == "powershell.exe" - assert "-Command" in cmd_list - ps_cmd = cmd_list[cmd_list.index("-Command") + 1] - assert "gemini" in ps_cmd - assert f"--model {expected_model}" in ps_cmd - # Verify input contains the prompt and system directive - input_text = kwargs.get("input") - assert "STRICT SYSTEM DIRECTIVE" in input_text - assert "TASK: Write a unit test." in input_text - assert kwargs.get("capture_output") is True - assert kwargs.get("text") is True - assert result == mock_stdout - -def test_get_dependencies(tmp_path: Path) -> None: - content = ( - "import os\n" - "import sys\n" - "import file_cache\n" - "from mcp_client import something\n" - ) - filepath = tmp_path / "mock_script.py" - filepath.write_text(content) - dependencies = get_dependencies(str(filepath)) - assert dependencies == ['os', 'sys', 'file_cache', 'mcp_client'] - -import re - -def test_execute_agent_logging(tmp_path: Path) -> None: - log_file = tmp_path / "mma_delegation.log" - # mma_exec now uses logs/agents/ for individual logs and logs/mma_delegation.log for master - # We will patch LOG_FILE to point to our temp location - with patch("scripts.mma_exec.LOG_FILE", str(log_file)), \ - patch("subprocess.run") as mock_run: - mock_process = MagicMock() - mock_process.stdout = "" - mock_process.returncode = 0 - mock_run.return_value = mock_process - test_role = "tier1" - test_prompt = "Plan the next phase" - execute_agent(test_role, test_prompt, []) - assert log_file.exists() - log_content = log_file.read_text() - assert test_role in log_content - assert test_prompt in log_content # Master log should now have the summary prompt - assert re.search(r"\d{4}-\d{2}-\d{2}", log_content) - -def test_execute_agent_tier3_injection(tmp_path: Path) -> None: - main_content = "import dependency\n\ndef run():\n dependency.do_work()\n" - main_file = tmp_path / "main.py" - main_file.write_text(main_content) - dep_content = "def do_work():\n pass\n\ndef other_func():\n print('hello')\n" - dep_file = tmp_path / "dependency.py" - dep_file.write_text(dep_content) - # We need to ensure generate_skeleton is mockable or working - old_cwd = os.getcwd() - os.chdir(tmp_path) - try: - with patch("subprocess.run") as mock_run: - mock_process = MagicMock() - mock_process.stdout = "OK" - mock_process.returncode = 0 - mock_run.return_value = mock_process - execute_agent('tier3-worker', 'Modify main.py', ['main.py']) - assert mock_run.called - input_text = mock_run.call_args[1].get("input") - assert "DEPENDENCY SKELETON: dependency.py" in input_text - assert "def do_work():" in input_text - assert "Modify main.py" in input_text - finally: - os.chdir(old_cwd) diff --git a/conductor/tests/verify_phase_1.py b/conductor/tests/verify_phase_1.py deleted file mode 100644 index 74e1b623..00000000 --- a/conductor/tests/verify_phase_1.py +++ /dev/null @@ -1,40 +0,0 @@ -import sys -import os - -# Add src to path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) - -from src.history import HistoryManager - -def verify_phase_1(): - print("Verifying Phase 1: History Core Logic...") - hm = HistoryManager(max_capacity=10) - - # Test push - hm.push({"test": 1}, "initial") - if not hm.can_undo: - print("Error: can_undo should be true after push") - sys.exit(1) - - # Test undo - entry = hm.undo({"test": 2}, "current") - if entry.state != {"test": 1}: - print(f"Error: expected state {{'test': 1}}, got {entry.state}") - sys.exit(1) - if entry.description != "initial": - print(f"Error: expected description 'initial', got {entry.description}") - sys.exit(1) - - # Test redo - entry = hm.redo({"test": 1}, "back") - if entry.state != {"test": 2}: - print(f"Error: expected state {{'test': 2}}, got {entry.state}") - sys.exit(1) - if entry.description != "current": - print(f"Error: expected description 'current', got {entry.description}") - sys.exit(1) - - print("Phase 1 verification PASSED.") - -if __name__ == "__main__": - verify_phase_1() diff --git a/conductor/tests/verify_phase_2.py b/conductor/tests/verify_phase_2.py deleted file mode 100644 index 03189fbe..00000000 --- a/conductor/tests/verify_phase_2.py +++ /dev/null @@ -1,24 +0,0 @@ -import subprocess -import sys -import os - -def verify_phase_2(): - print("Verifying Phase 2: Text Input & Control Undo/Redo...") - - # Run the simulation test - result = subprocess.run( - ["uv", "run", "pytest", "tests/test_undo_redo_sim.py"], - capture_output=True, - text=True - ) - - if result.returncode == 0: - print("Phase 2 verification PASSED.") - else: - print("Phase 2 verification FAILED.") - print(result.stdout) - print(result.stderr) - sys.exit(1) - -if __name__ == "__main__": - verify_phase_2() diff --git a/conductor/tests/verify_phase_3.py b/conductor/tests/verify_phase_3.py deleted file mode 100644 index 01dbfb45..00000000 --- a/conductor/tests/verify_phase_3.py +++ /dev/null @@ -1,24 +0,0 @@ -import subprocess -import sys - -def verify_phase_3(): - print("Verifying Phase 3: GUI Menu Integration...") - - # We rely on the existing simulation test to verify the callback logic, - # which underpins the GUI menu integration. - result = subprocess.run( - ["uv", "run", "pytest", "tests/test_workspace_profiles_sim.py"], - capture_output=True, - text=True - ) - - if result.returncode == 0: - print("Phase 3 verification PASSED.") - else: - print("Phase 3 verification FAILED.") - print(result.stdout) - print(result.stderr) - sys.exit(1) - -if __name__ == "__main__": - verify_phase_3() diff --git a/conductor/tests/verify_phase_3_rag.py b/conductor/tests/verify_phase_3_rag.py deleted file mode 100644 index d5463499..00000000 --- a/conductor/tests/verify_phase_3_rag.py +++ /dev/null @@ -1,54 +0,0 @@ -import sys -import os -import time - -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src"))) - -from src import api_hook_client - -def verify_phase_3(): - print("[VERIFY] Starting Phase 3 Automated Verification...") - client = api_hook_client.ApiHookClient() - if not client.wait_for_server(timeout=10): - print("[VERIFY] ERROR: Hook server not reachable.") - sys.exit(1) - - try: - # Check RAG status - status = client.get_value("rag_status") - print(f"[VERIFY] Current RAG status: {status}") - - # Check if RAG settings are accessible - enabled = client.get_value("rag_enabled") - source = client.get_value("rag_source") - print(f"[VERIFY] RAG Enabled: {enabled}, Source: {source}") - - # Verify status transitions (indexing) - print("[VERIFY] Triggering index rebuild...") - client.click("btn_rebuild_rag_index") - - time.sleep(0.5) - status = client.get_value("rag_status") - print(f"[VERIFY] Status during indexing: {status}") - - # Wait for completion - max_wait = 10 - start = time.time() - while time.time() - start < max_wait: - status = client.get_value("rag_status") - if status == "ready": - print("[VERIFY] RAG reached 'ready' status.") - break - time.sleep(1) - else: - print(f"[VERIFY] WARNING: RAG status timeout. Final: {status}") - - print("[VERIFY] Phase 3 verification COMPLETED successfully.") - - except Exception as e: - print(f"[VERIFY] ERROR during verification: {e}") - sys.exit(1) - -if __name__ == "__main__": - verify_phase_3() diff --git a/conductor/tests/verify_phase_4.py b/conductor/tests/verify_phase_4.py deleted file mode 100644 index 8dcc7a34..00000000 --- a/conductor/tests/verify_phase_4.py +++ /dev/null @@ -1,23 +0,0 @@ -import subprocess -import sys -import os - -def verify_phase_4(): - print("Verifying Phase 4: Contextual Auto-Switch...") - - result = subprocess.run( - ["uv", "run", "pytest", "tests/test_auto_switch_sim.py"], - capture_output=True, - text=True - ) - - if result.returncode == 0: - print("Phase 4 verification PASSED.") - else: - print("Phase 4 verification FAILED.") - print(result.stdout) - print(result.stderr) - sys.exit(1) - -if __name__ == "__main__": - verify_phase_4()