Deskaid

#!/usr/bin/env python3 """Tests for the RunCommand with test.""" import os import sys import unittest from codemcp.testing import MCPEndToEndTestCase class RunCommandTestTest(MCPEndToEndTestCase): """Test the RunCommand with test subtool.""" async def test_run_tests_with_run_subtool(self): """Test the RunCommand with test command.""" # Create a test directory for testing test_dir = os.path.join(self.temp_dir.name, "test_directory") os.makedirs(test_dir, exist_ok=True) # Create a test.py file with a simple test test_file_path = os.path.join(test_dir, "test_simple.py") with open(test_file_path, "w") as f: f.write(""" import unittest class SimpleTestCase(unittest.TestCase): def test_success(self): self.assertEqual(1 + 1, 2) def test_another_success(self): self.assertTrue(True) """) # Create a second test file with another test test_file_path2 = os.path.join(test_dir, "test_another.py") with open(test_file_path2, "w") as f: f.write(""" import unittest class AnotherTestCase(unittest.TestCase): def test_success(self): self.assertEqual(2 + 2, 4) """) # Create a run_test.sh script to mimic the real one # Get the current Python executable path current_python = os.path.abspath(sys.executable) # Create run_test.sh script using the current Python executable runner_script_path = os.path.join(self.temp_dir.name, "run_test.sh") with open(runner_script_path, "w") as f: f.write(f"""#!/bin/bash set -e cd "$(dirname "$0")" {current_python} -m pytest $@ """) os.chmod(runner_script_path, 0o755) # Make it executable # Update codemcp.toml to include the test subtool config_path = os.path.join(self.temp_dir.name, "codemcp.toml") with open(config_path, "w") as f: f.write(""" [project] name = "test-project" [commands] test = ["./run_test.sh"] """) # Add files to git await self.git_run(["add", "."]) await self.git_run(["commit", "-m", "Add test files"]) async with self.create_client_session() as session: # First initialize project to get chat_id init_result_text = await self.call_tool_assert_success( session, "codemcp", { "subtool": "InitProject", "path": self.temp_dir.name, "user_prompt": "Test initialization for run tests test", "subject_line": "test: initialize for run tests test", "reuse_head_chat_id": False, }, ) # Extract chat_id from the init result chat_id = self.extract_chat_id_from_text(init_result_text) # Call the RunCommand tool with test command and chat_id result_text = await self.call_tool_assert_success( session, "codemcp", { "subtool": "RunCommand", "path": self.temp_dir.name, "command": "test", "chat_id": chat_id, }, ) # Verify the success message self.assertIn("Code test successful", result_text) # Call the RunCommand tool with test command and arguments selector_result_text = await self.call_tool_assert_success( session, "codemcp", { "subtool": "RunCommand", "path": self.temp_dir.name, "command": "test", "arguments": "test_directory/test_another.py", "chat_id": chat_id, }, ) # Use the result text directly # Verify the success message self.assertIn("Code test successful", selector_result_text) # Verify that the selector was used self.assertIn("test_another.py", selector_result_text) self.assertNotIn("test_simple.py", selector_result_text) async def test_run_tests_with_string_arguments(self): """Test the RunCommand with string arguments that should be parsed.""" # Create a test directory for testing test_dir = os.path.join(self.temp_dir.name, "test_directory") os.makedirs(test_dir, exist_ok=True) # Create a test.py file with a simple test test_file_path = os.path.join(test_dir, "test_simple.py") with open(test_file_path, "w") as f: f.write(""" import unittest class SimpleTestCase(unittest.TestCase): def test_success(self): self.assertEqual(1 + 1, 2) def test_another_success(self): self.assertTrue(True) """) # Create a second test file with another test test_file_path2 = os.path.join(test_dir, "test_another.py") with open(test_file_path2, "w") as f: f.write(""" import unittest class AnotherTestCase(unittest.TestCase): def test_success(self): self.assertEqual(2 + 2, 4) """) # Get the current Python executable path current_python = os.path.abspath(sys.executable) # Create run_test.sh script using the current Python executable runner_script_path = os.path.join(self.temp_dir.name, "run_test.sh") with open(runner_script_path, "w") as f: f.write(f"""#!/bin/bash set -e cd "$(dirname "$0")" {current_python} -m pytest $@ """) os.chmod(runner_script_path, 0o755) # Make it executable # Update codemcp.toml to include the test subtool config_path = os.path.join(self.temp_dir.name, "codemcp.toml") with open(config_path, "w") as f: f.write(""" [project] name = "test-project" [commands] test = ["./run_test.sh"] """) # Add files to git await self.git_run(["add", "."]) await self.git_run(["commit", "-m", "Add test files"]) async with self.create_client_session() as session: # First initialize project to get chat_id init_result_text = await self.call_tool_assert_success( session, "codemcp", { "subtool": "InitProject", "path": self.temp_dir.name, "user_prompt": "Test initialization for string arguments test", "subject_line": "test: initialize for string arguments test", "reuse_head_chat_id": False, }, ) # Extract chat_id from the init result chat_id = self.extract_chat_id_from_text(init_result_text) # Test 1: Test with a string argument containing a specific test selector # This tests the basic space-separated argument parsing result_text = await self.call_tool_assert_success( session, "codemcp", { "subtool": "RunCommand", "path": self.temp_dir.name, "command": "test", "arguments": "test_directory/test_simple.py::SimpleTestCase::test_success", "chat_id": chat_id, }, ) # Verify the success message and proper argument parsing self.assertIn("Code test successful", result_text) # We should see evidence that the test was run with the specific test case self.assertIn("test_simple.py", result_text) self.assertIn("1 passed", result_text) # Only one test should be run due to the specific selector self.assertIn("collected 1 item", result_text) # Test 2: Test with multiple arguments separated by spaces in a single string # This verifies that the string is split into multiple arguments multi_arg_test = await self.call_tool_assert_success( session, "codemcp", { "subtool": "RunCommand", "path": self.temp_dir.name, "command": "test", "arguments": "test_directory/test_simple.py -k test_success", "chat_id": chat_id, }, ) # Verify multiple space-separated arguments were parsed correctly self.assertIn("Code test successful", multi_arg_test) # Only the specific test should be run due to the -k filter self.assertIn("collected 2 items", multi_arg_test) self.assertIn("1 passed, 1 deselected", multi_arg_test) if __name__ == "__main__": unittest.main()