remove files

This commit is contained in:
Don Syme committed 2025-10-10 15:12:35 +01:00
1 parent 061bbbde90
commit 9373d33151
2 files changed
-401

No files matched your search

-229
View File
@@ -1,229 +0,0 @@
"""Tests for the GetDiagnosticsTool."""
import json
from unittest.mock import Mock, patch
import pytest
from src.serena.agent import SerenaAgent
from src.serena.project import Project
from src.serena.tools.symbol_tools import GetDiagnosticsTool
class TestGetDiagnosticsTool:
"""Unit tests for GetDiagnosticsTool."""
def setup_method(self):
"""Set up test fixtures."""
# Mock agent
self.mock_agent = Mock(spec=SerenaAgent)
self.mock_agent.is_using_language_server.return_value = True
# Mock language server
self.mock_language_server = Mock()
self.mock_agent.language_server = self.mock_language_server
# Mock project
self.mock_project = Mock(spec=Project)
self.mock_project.project_root = "/test/project"
self.mock_agent.get_active_project_or_raise.return_value = self.mock_project
# Create tool instance
self.tool = GetDiagnosticsTool(self.mock_agent)
def test_get_severity_name(self):
"""Test the _get_severity_name helper method."""
assert self.tool._get_severity_name(1) == "error"
assert self.tool._get_severity_name(2) == "warning"
assert self.tool._get_severity_name(3) == "information"
assert self.tool._get_severity_name(4) == "hint"
assert self.tool._get_severity_name(None) == "unknown"
assert self.tool._get_severity_name(999) == "unknown(999)"
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_success_with_diagnostics(self, mock_isdir, mock_exists):
"""Test successful diagnostic retrieval with results."""
# Setup mocks
mock_exists.return_value = True
mock_isdir.return_value = False
# Mock diagnostic data
mock_diagnostics = [
{
"severity": 1,
"message": "Undefined variable 'foo'",
"code": "undefined-variable",
"source": "pylsp",
"range": {"start": {"line": 10, "character": 5}, "end": {"line": 10, "character": 8}},
},
{
"severity": 2,
"message": "Line too long",
"code": "E501",
"source": "flake8",
"range": {"start": {"line": 20, "character": 0}, "end": {"line": 20, "character": 100}},
},
]
self.mock_language_server.request_text_document_diagnostics.return_value = mock_diagnostics
# Mock the _limit_length method
with patch.object(self.tool, "_limit_length", side_effect=lambda x, _: x):
result = self.tool.apply("test_file.py")
# Verify result
result_data = json.loads(result)
assert len(result_data) == 2
# Check first diagnostic
diag1 = result_data[0]
assert diag1["severity"] == 1
assert diag1["severity_name"] == "error"
assert diag1["message"] == "Undefined variable 'foo'"
assert diag1["code"] == "undefined-variable"
assert diag1["source"] == "pylsp"
assert diag1["range"]["start"]["line"] == 10
assert diag1["range"]["start"]["character"] == 5
# Check second diagnostic
diag2 = result_data[1]
assert diag2["severity"] == 2
assert diag2["severity_name"] == "warning"
assert diag2["message"] == "Line too long"
# Verify method calls
self.mock_language_server.request_text_document_diagnostics.assert_called_once_with("test_file.py")
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_success_no_diagnostics(self, mock_isdir, mock_exists):
"""Test successful diagnostic retrieval with no results."""
# Setup mocks
mock_exists.return_value = True
mock_isdir.return_value = False
self.mock_language_server.request_text_document_diagnostics.return_value = []
# Mock the _limit_length method
with patch.object(self.tool, "_limit_length", side_effect=lambda x, _: x):
result = self.tool.apply("clean_file.py")
# Verify result
result_data = json.loads(result)
assert len(result_data) == 0
assert result_data == []
def test_apply_no_language_server(self):
"""Test error when language server is not available."""
self.mock_agent.is_using_language_server.return_value = False
with pytest.raises(Exception, match="Cannot get diagnostics; agent is not in language server mode"):
self.tool.apply("test_file.py")
@patch("os.path.exists")
def test_apply_file_not_found(self, mock_exists):
"""Test error when file does not exist."""
mock_exists.return_value = False
with pytest.raises(FileNotFoundError, match=r"File test_file.py does not exist in the project"):
self.tool.apply("test_file.py")
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_is_directory(self, mock_isdir, mock_exists):
"""Test error when path is a directory instead of a file."""
mock_exists.return_value = True
mock_isdir.return_value = True
with pytest.raises(ValueError, match="Expected a file path, but got a directory path: test_dir"):
self.tool.apply("test_dir")
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_language_server_error(self, mock_isdir, mock_exists):
"""Test handling of language server errors."""
mock_exists.return_value = True
mock_isdir.return_value = False
# Mock language server to raise an exception
self.mock_language_server.request_text_document_diagnostics.side_effect = Exception("Language server failed")
with pytest.raises(RuntimeError, match=r"Failed to retrieve diagnostics for test_file.py: Language server failed"):
self.tool.apply("test_file.py")
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_with_missing_fields(self, mock_isdir, mock_exists):
"""Test handling of diagnostics with missing optional fields."""
# Setup mocks
mock_exists.return_value = True
mock_isdir.return_value = False
# Mock diagnostic with missing optional fields
mock_diagnostics = [
{
"message": "Error without optional fields",
"range": {"start": {"line": 5, "character": 0}, "end": {"line": 5, "character": 10}},
# Missing severity, code, source
}
]
self.mock_language_server.request_text_document_diagnostics.return_value = mock_diagnostics
# Mock the _limit_length method
with patch.object(self.tool, "_limit_length", side_effect=lambda x, _: x):
result = self.tool.apply("test_file.py")
# Verify result handles missing fields gracefully
result_data = json.loads(result)
assert len(result_data) == 1
diag = result_data[0]
assert diag["severity"] == "unknown"
assert diag["severity_name"] == "unknown"
assert diag["message"] == "Error without optional fields"
assert diag["code"] == ""
assert diag["source"] == ""
@patch("os.path.exists")
@patch("os.path.isdir")
def test_apply_with_max_answer_chars(self, mock_isdir, mock_exists):
"""Test limiting output with max_answer_chars parameter."""
mock_exists.return_value = True
mock_isdir.return_value = False
mock_diagnostics = [
{
"severity": 1,
"message": "Test error",
"code": "test",
"source": "test",
"range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}},
}
]
self.mock_language_server.request_text_document_diagnostics.return_value = mock_diagnostics
# Mock _limit_length to return truncated result
with patch.object(self.tool, "_limit_length", return_value="TRUNCATED"):
result = self.tool.apply("test_file.py", max_answer_chars=100)
assert result == "TRUNCATED"
def test_path_construction(self):
"""Test that file paths are constructed correctly."""
relative_path = "src/module/file.py"
with (
patch("os.path.exists", return_value=True),
patch("os.path.isdir", return_value=False),
patch.object(self.tool, "_limit_length", side_effect=lambda x, _: x),
):
self.mock_language_server.request_text_document_diagnostics.return_value = []
self.tool.apply(relative_path)
# Verify os.path.join was called with correct arguments
# The actual path checking happens in the method, we verify the LS call
self.mock_language_server.request_text_document_diagnostics.assert_called_once_with(relative_path)
@@ -1,172 +0,0 @@
"""Integration tests for GetDiagnosticsTool with Go language server."""
import json
import os
from unittest.mock import Mock
import pytest
from solidlsp.ls_config import Language
from src.serena.agent import SerenaAgent
from src.serena.project import Project
from src.serena.tools.symbol_tools import GetDiagnosticsTool
from test.conftest import create_ls
@pytest.mark.go
class TestGetDiagnosticsToolGoIntegration:
"""Integration tests for GetDiagnosticsTool with Go language server."""
def setup_method(self):
"""Set up test fixtures with real Go language server."""
# Path to our diagnostic test repository
self.repo_path = os.path.join(os.path.dirname(__file__), "..", "resources", "repos", "go", "diagnostic_test_repo")
self.repo_path = os.path.abspath(self.repo_path)
# Create real language server for Go
self.language_server = create_ls(Language.GO, repo_path=self.repo_path)
# Mock agent with real language server
self.mock_agent = Mock(spec=SerenaAgent)
self.mock_agent.is_using_language_server.return_value = True
self.mock_agent.language_server = self.language_server
# Mock project
self.mock_project = Mock(spec=Project)
self.mock_project.project_root = self.repo_path
self.mock_agent.get_active_project_or_raise.return_value = self.mock_project
# Create tool instance
self.tool = GetDiagnosticsTool(self.mock_agent)
def teardown_method(self):
"""Clean up language server."""
if hasattr(self, "language_server"):
self.language_server.stop()
def test_get_diagnostics_with_go_errors(self):
"""Test GetDiagnosticsTool retrieves actual Go diagnostics from language server."""
# Mock the _limit_length method to avoid character limits in tests
def mock_limit_length(content, max_chars):
return content
self.tool._limit_length = mock_limit_length
try:
print(f"Starting Go language server for repo: {self.repo_path}")
# Start the language server
self.language_server.start()
print("Language server started successfully")
# Get diagnostics for the main.go file with intentional errors
result = self.tool.apply("main.go")
# Parse the JSON result
diagnostics = json.loads(result)
# We should have at least some diagnostics due to the intentional errors
assert isinstance(diagnostics, list)
assert len(diagnostics) > 0, f"Expected diagnostics but got none. Result: {result}"
# Check that we have actual diagnostic data
for diagnostic in diagnostics:
assert "severity" in diagnostic
assert "severity_name" in diagnostic
assert "message" in diagnostic
assert "range" in diagnostic
assert "start" in diagnostic["range"]
assert "end" in diagnostic["range"]
assert "line" in diagnostic["range"]["start"]
assert "character" in diagnostic["range"]["start"]
# Severity should be a known value
assert diagnostic["severity_name"] in ["error", "warning", "information", "hint", "unknown"]
# Message should not be empty for real diagnostics
assert len(diagnostic["message"]) > 0
# Check that we have at least one error (due to undefined variables/functions)
error_diagnostics = [d for d in diagnostics if d["severity_name"] == "error"]
assert len(error_diagnostics) > 0, f"Expected at least one error diagnostic. Got diagnostics: {diagnostics}"
print(f"Successfully retrieved {len(diagnostics)} diagnostics:")
for i, diag in enumerate(diagnostics[:5]): # Print first 5 diagnostics
print(f" {i+1}. [{diag['severity_name']}] {diag['message']} at line {diag['range']['start']['line']}")
except Exception as e:
pytest.skip(f"Go language server not available or failed: {e}")
def test_get_diagnostics_empty_file(self):
"""Test GetDiagnosticsTool with a valid Go file that has no errors."""
# Create a valid Go file with no errors
valid_go_content = """package utils
import "fmt"
func PrintMessage() {
fmt.Println("Hello, World!")
}
"""
# Create subdirectory for the valid file to avoid package conflicts
valid_dir = os.path.join(self.repo_path, "utils")
os.makedirs(valid_dir, exist_ok=True)
# Write the valid content to a test file in subdirectory
valid_file_path = os.path.join(valid_dir, "valid.go")
try:
with open(valid_file_path, "w") as f:
f.write(valid_go_content)
# Mock the _limit_length method
def mock_limit_length(content, max_chars):
return content
self.tool._limit_length = mock_limit_length
# Start the language server
self.language_server.start()
# Get diagnostics for the valid file
result = self.tool.apply("utils/valid.go")
# Parse the JSON result
diagnostics = json.loads(result)
# Should be an empty list or only contain minor warnings
assert isinstance(diagnostics, list)
# If there are any diagnostics, they should not be errors
error_diagnostics = [d for d in diagnostics if d["severity_name"] == "error"]
assert len(error_diagnostics) == 0, f"Valid Go file should not have errors. Got: {error_diagnostics}"
print(f"Valid Go file has {len(diagnostics)} diagnostics (expected 0 or only warnings/hints)")
except Exception as e:
pytest.skip(f"Go language server not available or failed: {e}")
finally:
# Clean up the test file and directory
if os.path.exists(valid_file_path):
os.remove(valid_file_path)
if os.path.exists(valid_dir) and os.path.isdir(valid_dir):
os.rmdir(valid_dir)
def test_get_diagnostics_nonexistent_file(self):
"""Test GetDiagnosticsTool error handling with nonexistent file."""
with pytest.raises(FileNotFoundError, match=r"File nonexistent.go does not exist in the project"):
self.tool.apply("nonexistent.go")
def test_get_diagnostics_directory_path(self):
"""Test GetDiagnosticsTool error handling when given a directory path."""
# Create a test directory
test_dir = os.path.join(self.repo_path, "test_dir")
os.makedirs(test_dir, exist_ok=True)
try:
with pytest.raises(ValueError, match="Expected a file path, but got a directory path"):
self.tool.apply("test_dir")
finally:
# Clean up
if os.path.exists(test_dir):
os.rmdir(test_dir)