Deskaid
by ezyang
- e2e
#!/usr/bin/env python3
"""Tests for the RunCommand with format."""
import os
import unittest
from codemcp.testing import MCPEndToEndTestCase
class RunCommandFormatTest(MCPEndToEndTestCase):
"""Test the RunCommand with format subtool."""
async def test_format_with_run_subtool(self):
"""Test that RunCommand with format commits changes made by formatting."""
# Create a file that is not properly formatted (needs formatting)
# We'll use Python's ruff formatter conventions
unformatted_file_path = os.path.join(self.temp_dir.name, "unformatted.py")
unformatted_content = """def badly_formatted_function ( arg1,arg2 ):
x=1+2
y= [1,2,
3, 4]
return x+y
"""
with open(unformatted_file_path, "w") as f:
f.write(unformatted_content)
# Add it to git
await self.git_run(["add", unformatted_file_path])
# Commit it
await self.git_run(["commit", "-m", "Add unformatted file"])
# Create a simple format script that simulates ruff formatting
format_script_path = os.path.join(self.temp_dir.name, "run_format.sh")
with open(format_script_path, "w") as f:
f.write("""#!/bin/bash
# Simple mock formatter that just fixes the format of the unformatted.py file
if [ -f unformatted.py ]; then
# Replace with properly formatted version
cat > unformatted.py << 'EOF'
def badly_formatted_function(arg1, arg2):
x = 1 + 2
y = [1, 2, 3, 4]
return x + y
EOF
echo "Formatted unformatted.py"
fi
""")
# Make it executable
os.chmod(format_script_path, 0o755)
# Create a codemcp.toml file with format subtool
codemcp_toml_path = os.path.join(self.temp_dir.name, "codemcp.toml")
with open(codemcp_toml_path, "w") as f:
f.write("""[project]
name = "test-project"
[commands]
format = ["./run_format.sh"]
""")
# Record the current commit hash before formatting
commit_before = await self.git_run(
["rev-parse", "HEAD"], capture_output=True, text=True
)
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 format test",
"subject_line": "test: initialize for format 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 format command and chat_id
result_text = await self.call_tool_assert_success(
session,
"codemcp",
{
"subtool": "RunCommand",
"path": self.temp_dir.name,
"command": "format",
"chat_id": chat_id,
},
)
# Verify the success message
self.assertIn("Code format successful", result_text)
# Verify the file was formatted correctly
with open(unformatted_file_path) as f:
file_content = f.read()
expected_content = """def badly_formatted_function(arg1, arg2):
x = 1 + 2
y = [1, 2, 3, 4]
return x + y
"""
self.assertEqual(file_content, expected_content)
# Verify git state shows clean working tree after commit
status = await self.git_run(["status"], capture_output=True, text=True)
# Verify that the working tree is clean (changes were committed)
self.assertExpectedInline(
status,
"""\
On branch main
nothing to commit, working tree clean""",
)
# Verify that a new commit was created
commit_after = await self.git_run(
["rev-parse", "HEAD"], capture_output=True, text=True
)
# The commit hash should be different
self.assertNotEqual(commit_before, commit_after)
# Verify the commit message indicates it was a formatting change
commit_msg = await self.git_run(
["log", "-1", "--pretty=%B"], capture_output=True, text=True
)
self.assertIn("Auto-commit format changes", commit_msg)
if __name__ == "__main__":
unittest.main()