mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-14 16:18:03 +00:00
Add MATLAB language server support (#893)
Requires Matlab and node to be installed, using vscode Matlab extension as LS
This commit is contained in:
1 parent
823e7c6325
commit
f758a3d19c
9 files changed
+839
-1
No files matched your search
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
Basic integration tests for the MATLAB language server functionality.
|
||||
|
||||
These tests validate the functionality of the language server APIs
|
||||
like request_document_symbols using the MATLAB test repository.
|
||||
|
||||
Requirements:
|
||||
- MATLAB R2021b or later must be installed
|
||||
- MATLAB_PATH environment variable should be set to MATLAB installation directory
|
||||
- Node.js and npm must be installed
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
|
||||
# Skip all tests if MATLAB is not available
|
||||
pytestmark = pytest.mark.matlab
|
||||
|
||||
# Check if MATLAB is available
|
||||
MATLAB_AVAILABLE = os.environ.get("MATLAB_PATH") is not None or any(
|
||||
os.path.exists(p)
|
||||
for p in [
|
||||
"/Applications/MATLAB_R2024b.app",
|
||||
"/Applications/MATLAB_R2025b.app",
|
||||
"/Volumes/S1/Applications/MATLAB_R2024b.app",
|
||||
"/Volumes/S1/Applications/MATLAB_R2025b.app",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.skipif(not MATLAB_AVAILABLE, reason="MATLAB installation not found")
|
||||
class TestMatlabLanguageServerBasics:
|
||||
"""Test basic functionality of the MATLAB language server."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_language_server_initialization(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test that MATLAB language server can be initialized successfully."""
|
||||
assert language_server is not None
|
||||
assert language_server.language == Language.MATLAB
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_request_document_symbols_class(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_document_symbols for MATLAB class file."""
|
||||
# Test getting symbols from Calculator.m (class file)
|
||||
all_symbols, _root_symbols = language_server.request_document_symbols("Calculator.m").get_all_symbols_and_roots()
|
||||
|
||||
# Extract class symbols (LSP Symbol Kind 5 for class)
|
||||
class_symbols = [symbol for symbol in all_symbols if symbol.get("kind") == 5]
|
||||
class_names = [symbol["name"] for symbol in class_symbols]
|
||||
|
||||
# Should find the Calculator class
|
||||
assert "Calculator" in class_names, "Should find Calculator class"
|
||||
|
||||
# Extract method symbols (LSP Symbol Kind 6 for method or 12 for function)
|
||||
method_symbols = [symbol for symbol in all_symbols if symbol.get("kind") in [6, 12]]
|
||||
method_names = [symbol["name"] for symbol in method_symbols]
|
||||
|
||||
# Should find key methods
|
||||
expected_methods = ["add", "subtract", "multiply", "divide"]
|
||||
for method in expected_methods:
|
||||
assert method in method_names, f"Should find {method} method in Calculator class"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_request_document_symbols_function(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_document_symbols for MATLAB function file."""
|
||||
# Test getting symbols from lib/mathUtils.m (function file)
|
||||
all_symbols, _root_symbols = language_server.request_document_symbols("lib/mathUtils.m").get_all_symbols_and_roots()
|
||||
|
||||
# Extract function symbols (LSP Symbol Kind 12 for function)
|
||||
function_symbols = [symbol for symbol in all_symbols if symbol.get("kind") == 12]
|
||||
function_names = [symbol["name"] for symbol in function_symbols]
|
||||
|
||||
# Should find the main mathUtils function
|
||||
assert "mathUtils" in function_names, "Should find mathUtils function"
|
||||
|
||||
# Should also find nested/local functions
|
||||
expected_local_functions = ["computeFactorial", "computeFibonacci", "checkPrime", "computeStats"]
|
||||
for func in expected_local_functions:
|
||||
assert func in function_names, f"Should find {func} local function"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_request_document_symbols_script(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_document_symbols for MATLAB script file."""
|
||||
# Test getting symbols from main.m (script file)
|
||||
all_symbols, _root_symbols = language_server.request_document_symbols("main.m").get_all_symbols_and_roots()
|
||||
|
||||
# Scripts may have variables and sections, but less structured symbols
|
||||
# Just verify we can get symbols without errors
|
||||
assert all_symbols is not None
|
||||
|
||||
|
||||
@pytest.mark.skipif(not MATLAB_AVAILABLE, reason="MATLAB installation not found")
|
||||
class TestMatlabLanguageServerReferences:
|
||||
"""Test find references functionality of the MATLAB language server."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_find_references_within_file(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test finding references within a single MATLAB file."""
|
||||
# Find references to 'result' variable in Calculator.m
|
||||
# This is a basic test to verify references work
|
||||
references = language_server.request_references("Calculator.m", 25, 12) # 'result' in add method
|
||||
|
||||
# Should find at least the definition
|
||||
assert references is not None
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.MATLAB], indirect=True)
|
||||
def test_matlab_find_references_cross_file(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test finding references across MATLAB files."""
|
||||
# Find references to Calculator class used in main.m
|
||||
references = language_server.request_references("main.m", 11, 8) # 'Calculator' reference
|
||||
|
||||
# Should find references in both main.m and Calculator.m
|
||||
assert references is not None
|
||||
Reference in new issue
Block a user