From ec9e9f9896b4d063a4f53f2e31d132c9af8ba190 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Mon, 24 Mar 2025 20:03:05 +0800 Subject: [PATCH 1/2] Update [ghstack-poisoned] --- e2e/test_git_tools.py | 161 ++++++++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 62 deletions(-) diff --git a/e2e/test_git_tools.py b/e2e/test_git_tools.py index b9181b9b..7e15d266 100644 --- a/e2e/test_git_tools.py +++ b/e2e/test_git_tools.py @@ -1,13 +1,12 @@ #!/usr/bin/env python3 +import asyncio import os import shutil import tempfile import unittest from unittest import mock -import pytest - from codemcp.shell import run_command from codemcp.tools.git_blame import git_blame from codemcp.tools.git_diff import git_diff @@ -15,14 +14,17 @@ from codemcp.tools.git_show import git_show -@pytest.mark.asyncio class TestGitTools(unittest.TestCase): """Test the git tools functionality.""" - async def asyncSetUp(self): + def setUp(self): # Create a temporary directory self.temp_dir = tempfile.mkdtemp() + # Initialize a git repository + asyncio.run(self.async_setup()) + + async def async_setup(self): # Initialize a git repository await run_command( cmd=["git", "init"], cwd=self.temp_dir, capture_output=True, text=True @@ -76,84 +78,119 @@ async def asyncSetUp(self): text=True, ) - async def asyncTearDown(self): + def tearDown(self): # Clean up the temporary directory shutil.rmtree(self.temp_dir) - async def test_git_log(self): + def test_git_log(self): """Test the git_log tool.""" - # Test with no arguments - result = await git_log(path=self.temp_dir) - self.assertIn("Initial commit", result["output"]) - self.assertIn("Second commit", result["output"]) - # Test with arguments - result = await git_log(arguments="--oneline -n 1", path=self.temp_dir) - self.assertIn("Second commit", result["output"]) - self.assertNotIn("Initial commit", result["output"]) + async def _test(): + # Test with no arguments + result = await git_log(path=self.temp_dir) + self.assertIn("Initial commit", result["output"]) + self.assertIn("Second commit", result["output"]) + + # Test with arguments + result = await git_log(arguments="--oneline -n 1", path=self.temp_dir) + self.assertIn("Second commit", result["output"]) + self.assertNotIn("Initial commit", result["output"]) - async def test_git_diff(self): + asyncio.run(_test()) + + def test_git_diff(self): """Test the git_diff tool.""" - # Create a change but don't commit it - with open(self.sample_file, "a") as f: - f.write("Uncommitted change\n") - # Test with no arguments - result = await git_diff(path=self.temp_dir) - self.assertIn("Uncommitted change", result["output"]) + async def _test(): + # Create a change but don't commit it + with open(self.sample_file, "a") as f: + f.write("Uncommitted change\n") + + # Test with no arguments + result = await git_diff(path=self.temp_dir) + self.assertIn("Uncommitted change", result["output"]) + + # Test with arguments + result = await git_diff(arguments="HEAD~1 HEAD", path=self.temp_dir) + self.assertIn("Line 4", result["output"]) - # Test with arguments - result = await git_diff(arguments="HEAD~1 HEAD", path=self.temp_dir) - self.assertIn("Line 4", result["output"]) + asyncio.run(_test()) - async def test_git_show(self): + def test_git_show(self): """Test the git_show tool.""" - # Test with no arguments (should show the latest commit) - result = await git_show(path=self.temp_dir) - self.assertIn("Second commit", result["output"]) - # Test with arguments - result = await git_show(arguments="HEAD~1", path=self.temp_dir) - self.assertIn("Initial commit", result["output"]) + async def _test(): + # Test with no arguments (should show the latest commit) + result = await git_show(path=self.temp_dir) + self.assertIn("Second commit", result["output"]) - async def test_git_blame(self): - """Test the git_blame tool.""" - # Test with file argument - result = await git_blame(arguments="sample.txt", path=self.temp_dir) - self.assertIn("Test User", result["output"]) - self.assertIn("Line 2", result["output"]) + # Test with arguments + result = await git_show(arguments="HEAD~1", path=self.temp_dir) + self.assertIn("Initial commit", result["output"]) - # Test with line range - result = await git_blame(arguments="-L 4,5 sample.txt", path=self.temp_dir) - self.assertIn("Line 4", result["output"]) - self.assertNotIn("Line 2", result["output"]) + asyncio.run(_test()) - async def test_invalid_path(self): - """Test that tools handle invalid paths.""" - with mock.patch("codemcp.git.is_git_repository", return_value=False): - with self.assertRaises(ValueError): - await git_log(path="/invalid/path") + def test_git_blame(self): + """Test the git_blame tool.""" - with self.assertRaises(ValueError): - await git_diff(path="/invalid/path") + async def _test(): + # Test with file argument + result = await git_blame(arguments="sample.txt", path=self.temp_dir) + self.assertIn("Test User", result["output"]) + self.assertIn("Line 2", result["output"]) - with self.assertRaises(ValueError): - await git_show(path="/invalid/path") + # Test with line range + result = await git_blame(arguments="-L 4,5 sample.txt", path=self.temp_dir) + self.assertIn("Line 4", result["output"]) + self.assertNotIn("Line 2", result["output"]) - with self.assertRaises(ValueError): - await git_blame(path="/invalid/path") + asyncio.run(_test()) - async def test_command_failure(self): + def test_invalid_path(self): + """Test that tools handle invalid paths.""" + + async def _test(): + with mock.patch( + "codemcp.tools.git_log.is_git_repository", return_value=False + ): + with self.assertRaises(ValueError): + await git_log(path="/invalid/path") + + with mock.patch( + "codemcp.tools.git_diff.is_git_repository", return_value=False + ): + with self.assertRaises(ValueError): + await git_diff(path="/invalid/path") + + with mock.patch( + "codemcp.tools.git_show.is_git_repository", return_value=False + ): + with self.assertRaises(ValueError): + await git_show(path="/invalid/path") + + with mock.patch( + "codemcp.tools.git_blame.is_git_repository", return_value=False + ): + with self.assertRaises(ValueError): + await git_blame(path="/invalid/path") + + asyncio.run(_test()) + + def test_command_failure(self): """Test that tools handle command failures.""" - # Test with invalid arguments - result = await git_log(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) - result = await git_diff(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) + async def _test(): + # Test with invalid arguments + result = await git_log(arguments="--invalid-option", path=self.temp_dir) + self.assertIn("Error", result["resultForAssistant"]) + + result = await git_diff(arguments="--invalid-option", path=self.temp_dir) + self.assertIn("Error", result["resultForAssistant"]) + + result = await git_show(arguments="--invalid-option", path=self.temp_dir) + self.assertIn("Error", result["resultForAssistant"]) - result = await git_show(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) + result = await git_blame(arguments="--invalid-option", path=self.temp_dir) + self.assertIn("Error", result["resultForAssistant"]) - result = await git_blame(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) + asyncio.run(_test()) From 65569c136f99c0f44aea61f8a487ee2e52fa15f4 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Mon, 24 Mar 2025 20:06:24 +0800 Subject: [PATCH 2/2] Update [ghstack-poisoned] --- e2e/test_git_tools.py | 231 ++++++++++++++---------------------------- 1 file changed, 77 insertions(+), 154 deletions(-) diff --git a/e2e/test_git_tools.py b/e2e/test_git_tools.py index 7e15d266..dbdaa67a 100644 --- a/e2e/test_git_tools.py +++ b/e2e/test_git_tools.py @@ -1,196 +1,119 @@ #!/usr/bin/env python3 -import asyncio import os -import shutil -import tempfile -import unittest from unittest import mock -from codemcp.shell import run_command +from codemcp.testing import MCPEndToEndTestCase from codemcp.tools.git_blame import git_blame from codemcp.tools.git_diff import git_diff from codemcp.tools.git_log import git_log from codemcp.tools.git_show import git_show -class TestGitTools(unittest.TestCase): +class TestGitTools(MCPEndToEndTestCase): """Test the git tools functionality.""" - def setUp(self): - # Create a temporary directory - self.temp_dir = tempfile.mkdtemp() - - # Initialize a git repository - asyncio.run(self.async_setup()) - - async def async_setup(self): - # Initialize a git repository - await run_command( - cmd=["git", "init"], cwd=self.temp_dir, capture_output=True, text=True - ) + async def asyncSetUp(self): + # Use the parent class's asyncSetUp to set up test environment + await super().asyncSetUp() # Create a sample file - self.sample_file = os.path.join(self.temp_dir, "sample.txt") + self.sample_file = os.path.join(self.temp_dir.name, "sample.txt") with open(self.sample_file, "w") as f: f.write("Sample content\nLine 2\nLine 3\n") - # Add and commit the file - await run_command( - cmd=["git", "config", "user.name", "Test User"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) - await run_command( - cmd=["git", "config", "user.email", "test@example.com"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) - await run_command( - cmd=["git", "add", "sample.txt"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) - await run_command( - cmd=["git", "commit", "-m", "Initial commit"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) + # Add and commit the file (the base class already has git initialized) + await self.git_run(["add", "sample.txt"]) + await self.git_run(["commit", "-m", "Initial commit"]) # Modify the file and create another commit with open(self.sample_file, "a") as f: f.write("Line 4\nLine 5\n") - await run_command( - cmd=["git", "add", "sample.txt"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) - await run_command( - cmd=["git", "commit", "-m", "Second commit"], - cwd=self.temp_dir, - capture_output=True, - text=True, - ) - - def tearDown(self): - # Clean up the temporary directory - shutil.rmtree(self.temp_dir) - - def test_git_log(self): - """Test the git_log tool.""" - - async def _test(): - # Test with no arguments - result = await git_log(path=self.temp_dir) - self.assertIn("Initial commit", result["output"]) - self.assertIn("Second commit", result["output"]) + await self.git_run(["add", "sample.txt"]) + await self.git_run(["commit", "-m", "Second commit"]) - # Test with arguments - result = await git_log(arguments="--oneline -n 1", path=self.temp_dir) - self.assertIn("Second commit", result["output"]) - self.assertNotIn("Initial commit", result["output"]) + async def test_git_log(self): + """Test the git_log tool.""" + # Test with no arguments + result = await git_log(path=self.temp_dir.name) + self.assertIn("Initial commit", result["output"]) + self.assertIn("Second commit", result["output"]) - asyncio.run(_test()) + # Test with arguments + result = await git_log(arguments="--oneline -n 1", path=self.temp_dir.name) + self.assertIn("Second commit", result["output"]) + self.assertNotIn("Initial commit", result["output"]) - def test_git_diff(self): + async def test_git_diff(self): """Test the git_diff tool.""" + # Create a change but don't commit it + with open(self.sample_file, "a") as f: + f.write("Uncommitted change\n") - async def _test(): - # Create a change but don't commit it - with open(self.sample_file, "a") as f: - f.write("Uncommitted change\n") - - # Test with no arguments - result = await git_diff(path=self.temp_dir) - self.assertIn("Uncommitted change", result["output"]) - - # Test with arguments - result = await git_diff(arguments="HEAD~1 HEAD", path=self.temp_dir) - self.assertIn("Line 4", result["output"]) + # Test with no arguments + result = await git_diff(path=self.temp_dir.name) + self.assertIn("Uncommitted change", result["output"]) - asyncio.run(_test()) + # Test with arguments + result = await git_diff(arguments="HEAD~1 HEAD", path=self.temp_dir.name) + self.assertIn("Line 4", result["output"]) - def test_git_show(self): + async def test_git_show(self): """Test the git_show tool.""" + # Test with no arguments (should show the latest commit) + result = await git_show(path=self.temp_dir.name) + self.assertIn("Second commit", result["output"]) - async def _test(): - # Test with no arguments (should show the latest commit) - result = await git_show(path=self.temp_dir) - self.assertIn("Second commit", result["output"]) + # Test with arguments + result = await git_show(arguments="HEAD~1", path=self.temp_dir.name) + self.assertIn("Initial commit", result["output"]) - # Test with arguments - result = await git_show(arguments="HEAD~1", path=self.temp_dir) - self.assertIn("Initial commit", result["output"]) - - asyncio.run(_test()) - - def test_git_blame(self): + async def test_git_blame(self): """Test the git_blame tool.""" + # Test with file argument + result = await git_blame(arguments="sample.txt", path=self.temp_dir.name) + self.assertIn( + "A U Thor", result["output"] + ) # MCPEndToEndTestCase sets this author + self.assertIn("Line 2", result["output"]) + + # Test with line range + result = await git_blame(arguments="-L 4,5 sample.txt", path=self.temp_dir.name) + self.assertIn("Line 4", result["output"]) + self.assertNotIn("Line 2", result["output"]) + + async def test_invalid_path(self): + """Test that tools handle invalid paths.""" + with mock.patch("codemcp.tools.git_log.is_git_repository", return_value=False): + with self.assertRaises(ValueError): + await git_log(path="/invalid/path") - async def _test(): - # Test with file argument - result = await git_blame(arguments="sample.txt", path=self.temp_dir) - self.assertIn("Test User", result["output"]) - self.assertIn("Line 2", result["output"]) + with mock.patch("codemcp.tools.git_diff.is_git_repository", return_value=False): + with self.assertRaises(ValueError): + await git_diff(path="/invalid/path") - # Test with line range - result = await git_blame(arguments="-L 4,5 sample.txt", path=self.temp_dir) - self.assertIn("Line 4", result["output"]) - self.assertNotIn("Line 2", result["output"]) + with mock.patch("codemcp.tools.git_show.is_git_repository", return_value=False): + with self.assertRaises(ValueError): + await git_show(path="/invalid/path") - asyncio.run(_test()) + with mock.patch( + "codemcp.tools.git_blame.is_git_repository", return_value=False + ): + with self.assertRaises(ValueError): + await git_blame(path="/invalid/path") - def test_invalid_path(self): - """Test that tools handle invalid paths.""" - - async def _test(): - with mock.patch( - "codemcp.tools.git_log.is_git_repository", return_value=False - ): - with self.assertRaises(ValueError): - await git_log(path="/invalid/path") - - with mock.patch( - "codemcp.tools.git_diff.is_git_repository", return_value=False - ): - with self.assertRaises(ValueError): - await git_diff(path="/invalid/path") - - with mock.patch( - "codemcp.tools.git_show.is_git_repository", return_value=False - ): - with self.assertRaises(ValueError): - await git_show(path="/invalid/path") - - with mock.patch( - "codemcp.tools.git_blame.is_git_repository", return_value=False - ): - with self.assertRaises(ValueError): - await git_blame(path="/invalid/path") - - asyncio.run(_test()) - - def test_command_failure(self): + async def test_command_failure(self): """Test that tools handle command failures.""" + # Test with invalid arguments + result = await git_log(arguments="--invalid-option", path=self.temp_dir.name) + self.assertIn("Error", result["resultForAssistant"]) - async def _test(): - # Test with invalid arguments - result = await git_log(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) - - result = await git_diff(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) - - result = await git_show(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) + result = await git_diff(arguments="--invalid-option", path=self.temp_dir.name) + self.assertIn("Error", result["resultForAssistant"]) - result = await git_blame(arguments="--invalid-option", path=self.temp_dir) - self.assertIn("Error", result["resultForAssistant"]) + result = await git_show(arguments="--invalid-option", path=self.temp_dir.name) + self.assertIn("Error", result["resultForAssistant"]) - asyncio.run(_test()) + result = await git_blame(arguments="--invalid-option", path=self.temp_dir.name) + self.assertIn("Error", result["resultForAssistant"])