mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 00:15:05 +00:00
Refactoring: Rename Language to LanguageServerId
This resolves a long-standing naming issue in Serena & SolidLSP.
This commit is contained in:
1 parent
ef0e218fb1
commit
d2cf18ddcb
180 files changed
+1806
-1767
No files matched your search
@@ -10,20 +10,23 @@ import os
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
from solidlsp.ls_config import LanguageServerId
|
||||
from solidlsp.ls_types import SymbolKind
|
||||
from test.conftest import language_tests_enabled
|
||||
from test.conftest import language_server_tests_enabled
|
||||
from test.solidlsp.conftest import format_symbol_for_assert, has_malformed_name, request_all_symbols
|
||||
from test.solidlsp.util.diagnostics import assert_file_diagnostics
|
||||
|
||||
# These marks will be applied to all tests in this module
|
||||
pytestmark = [pytest.mark.elixir, pytest.mark.skipif(not language_tests_enabled(Language.ELIXIR), reason="Elixir tests are disabled")]
|
||||
pytestmark = [
|
||||
pytest.mark.elixir,
|
||||
pytest.mark.skipif(not language_server_tests_enabled(LanguageServerId.ELIXIR), reason="Elixir tests are disabled"),
|
||||
]
|
||||
|
||||
|
||||
class TestElixirBasic:
|
||||
"""Basic Elixir language server functionality tests."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_references_function_definition(self, language_server: SolidLanguageServer):
|
||||
"""Test finding references to a function definition."""
|
||||
file_path = os.path.join("lib", "models.ex")
|
||||
@@ -52,7 +55,7 @@ class TestElixirBasic:
|
||||
found_definition = any(ref["uri"].endswith("models.ex") for ref in references)
|
||||
assert found_definition, "Should find the function definition"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_references_create_user_function(self, language_server: SolidLanguageServer):
|
||||
"""Test finding references to create_user function."""
|
||||
file_path = os.path.join("lib", "services.ex")
|
||||
@@ -77,7 +80,7 @@ class TestElixirBasic:
|
||||
assert references is not None
|
||||
assert len(references) > 0
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_referencing_symbols_function(self, language_server: SolidLanguageServer):
|
||||
"""Test finding symbols that reference a specific function."""
|
||||
file_path = os.path.join("lib", "models.ex")
|
||||
@@ -101,7 +104,7 @@ class TestElixirBasic:
|
||||
|
||||
assert referencing_symbols is not None
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_timeout_enumeration_bug(self, language_server: SolidLanguageServer):
|
||||
"""Test that enumeration doesn't timeout (regression test)."""
|
||||
# This should complete without timing out
|
||||
@@ -113,7 +116,7 @@ class TestElixirBasic:
|
||||
symbols = language_server.request_document_symbols("lib/services.ex").get_all_symbols_and_roots()
|
||||
assert symbols is not None
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_bare_symbol_names(self, language_server) -> None:
|
||||
all_symbols = request_all_symbols(language_server)
|
||||
malformed_symbols = []
|
||||
@@ -139,7 +142,7 @@ class TestElixirBasic:
|
||||
pytrace=False,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_file_diagnostics(self, language_server: SolidLanguageServer) -> None:
|
||||
assert_file_diagnostics(
|
||||
language_server,
|
||||
|
||||
@@ -5,11 +5,14 @@ from pathlib import Path
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
from test.conftest import language_tests_enabled, start_ls_context
|
||||
from solidlsp.ls_config import LanguageServerId
|
||||
from test.conftest import language_server_tests_enabled, start_ls_context
|
||||
|
||||
# These marks will be applied to all tests in this module
|
||||
pytestmark = [pytest.mark.elixir, pytest.mark.skipif(not language_tests_enabled(Language.ELIXIR), reason="Elixir tests are disabled")]
|
||||
pytestmark = [
|
||||
pytest.mark.elixir,
|
||||
pytest.mark.skipif(not language_server_tests_enabled(LanguageServerId.ELIXIR), reason="Elixir tests are disabled"),
|
||||
]
|
||||
|
||||
# Skip slow tests in CI - they require multiple Expert instances which is too slow
|
||||
IN_CI = bool(os.environ.get("CI") or os.environ.get("GITHUB_ACTIONS"))
|
||||
@@ -26,7 +29,7 @@ def ls_with_ignored_dirs() -> Generator[SolidLanguageServer, None, None]:
|
||||
Uses session scope to avoid restarting Expert for each test.
|
||||
"""
|
||||
ignored_paths = ["scripts", "ignored_dir"]
|
||||
with start_ls_context(language=Language.ELIXIR, ignored_paths=ignored_paths) as ls:
|
||||
with start_ls_context(ls_id=LanguageServerId.ELIXIR, ignored_paths=ignored_paths) as ls:
|
||||
yield ls
|
||||
|
||||
|
||||
@@ -81,7 +84,7 @@ def test_find_references_ignores_dir(ls_with_ignored_dirs: SolidLanguageServer):
|
||||
|
||||
@pytest.mark.slow
|
||||
@SKIP_SLOW_IN_CI
|
||||
@pytest.mark.parametrize("repo_path", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_refs_and_symbols_with_glob_patterns(repo_path: Path) -> None:
|
||||
"""Tests that refs and symbols with glob patterns are ignored.
|
||||
|
||||
@@ -89,7 +92,7 @@ def test_refs_and_symbols_with_glob_patterns(repo_path: Path) -> None:
|
||||
which adds ~60-90s startup time.
|
||||
"""
|
||||
ignored_paths = ["*cripts", "ignored_*"] # codespell:ignore cripts
|
||||
with start_ls_context(language=Language.ELIXIR, repo_path=str(repo_path), ignored_paths=ignored_paths) as ls:
|
||||
with start_ls_context(ls_id=LanguageServerId.ELIXIR, repo_path=str(repo_path), ignored_paths=ignored_paths) as ls:
|
||||
# Same as in the above tests
|
||||
root = ls.request_full_symbol_tree()[0]
|
||||
root_children = root["children"]
|
||||
@@ -121,7 +124,7 @@ def test_refs_and_symbols_with_glob_patterns(repo_path: Path) -> None:
|
||||
assert not any("ignored_dir" in ref["relativePath"] for ref in references), "ignored_dir should be ignored (glob)"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_default_ignored_directories(language_server: SolidLanguageServer):
|
||||
"""Test that default Elixir directories are ignored."""
|
||||
# Test that Elixir-specific directories are ignored by default
|
||||
@@ -142,7 +145,7 @@ def test_default_ignored_directories(language_server: SolidLanguageServer):
|
||||
reason="Expert 0.1.0 bug: document_symbols may return nil for some files (flaky)",
|
||||
raises=Exception,
|
||||
)
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_symbol_tree_excludes_build_dirs(language_server: SolidLanguageServer):
|
||||
"""Test that symbol tree excludes build and dependency directories."""
|
||||
symbol_tree = language_server.request_full_symbol_tree()
|
||||
|
||||
@@ -12,11 +12,14 @@ import pytest
|
||||
|
||||
from serena.project import Project
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
from test.conftest import language_tests_enabled
|
||||
from solidlsp.ls_config import LanguageServerId
|
||||
from test.conftest import language_server_tests_enabled
|
||||
|
||||
# These marks will be applied to all tests in this module
|
||||
pytestmark = [pytest.mark.elixir, pytest.mark.skipif(not language_tests_enabled(Language.ELIXIR), reason="Elixir tests are disabled")]
|
||||
pytestmark = [
|
||||
pytest.mark.elixir,
|
||||
pytest.mark.skipif(not language_server_tests_enabled(LanguageServerId.ELIXIR), reason="Elixir tests are disabled"),
|
||||
]
|
||||
|
||||
|
||||
class TestElixirIntegration:
|
||||
@@ -42,7 +45,7 @@ class TestElixirIntegration:
|
||||
assert (repo_path / "test" / "test_repo_test.exs").exists(), "test file should exist"
|
||||
assert (repo_path / "test" / "models_test.exs").exists(), "models test should exist"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_cross_file_symbol_resolution(self, language_server: SolidLanguageServer):
|
||||
"""Test that symbols can be resolved across different files."""
|
||||
# Test that User struct from models.ex can be found when referenced in services.ex
|
||||
@@ -67,7 +70,7 @@ class TestElixirIntegration:
|
||||
# Should point to models.ex
|
||||
assert "models.ex" in defining_symbol["location"]["uri"]
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_module_hierarchy_understanding(self, language_server: SolidLanguageServer):
|
||||
"""Test that the language server understands Elixir module hierarchy."""
|
||||
models_file = os.path.join("lib", "models.ex")
|
||||
@@ -91,7 +94,7 @@ class TestElixirIntegration:
|
||||
|
||||
def test_file_extension_matching(self):
|
||||
"""Test that the Elixir language recognizes the correct file extensions."""
|
||||
language = Language.ELIXIR
|
||||
language = LanguageServerId.ELIXIR
|
||||
matcher = language.get_source_fn_matcher()
|
||||
|
||||
# Test Elixir file extensions
|
||||
@@ -110,7 +113,7 @@ class TestElixirIntegration:
|
||||
|
||||
|
||||
class TestElixirProject:
|
||||
@pytest.mark.parametrize("project", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("project", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_comprehensive_symbol_search(self, project: Project):
|
||||
"""Test comprehensive symbol search across the entire project."""
|
||||
# Search for all function definitions
|
||||
@@ -138,7 +141,7 @@ class TestElixirProject:
|
||||
models_structs = [m for m in struct_matches if m.source_file_path and "models.ex" in m.source_file_path]
|
||||
assert len(models_structs) > 0, "Should find struct definitions in models.ex"
|
||||
|
||||
@pytest.mark.parametrize("project", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("project", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_protocol_and_implementation_understanding(self, project: Project):
|
||||
"""Test that the language server understands Elixir protocols and implementations."""
|
||||
# Search for protocol definitions
|
||||
|
||||
@@ -12,12 +12,15 @@ import os
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
from solidlsp.ls_config import LanguageServerId
|
||||
from solidlsp.ls_types import SymbolKind
|
||||
from test.conftest import language_tests_enabled
|
||||
from test.conftest import language_server_tests_enabled
|
||||
|
||||
# These marks will be applied to all tests in this module
|
||||
pytestmark = [pytest.mark.elixir, pytest.mark.skipif(not language_tests_enabled(Language.ELIXIR), reason="Elixir tests are disabled")]
|
||||
pytestmark = [
|
||||
pytest.mark.elixir,
|
||||
pytest.mark.skipif(not language_server_tests_enabled(LanguageServerId.ELIXIR), reason="Elixir tests are disabled"),
|
||||
]
|
||||
|
||||
|
||||
class TestElixirLanguageServerSymbols:
|
||||
@@ -26,7 +29,7 @@ class TestElixirLanguageServerSymbols:
|
||||
@pytest.mark.xfail(
|
||||
reason="Expert 0.1.0 bug: document_symbols returns nil for some files (FunctionClauseError in XPExpert.EngineApi.document_symbols/2)"
|
||||
)
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_containing_symbol_function(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_containing_symbol for a function."""
|
||||
# Test for a position inside the create_user function
|
||||
@@ -54,7 +57,7 @@ class TestElixirLanguageServerSymbols:
|
||||
if "body" in containing_symbol:
|
||||
assert "def create_user" in containing_symbol["body"].get_text()
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_containing_symbol_module(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_containing_symbol for a module."""
|
||||
# Test for a position inside the UserService module but outside any function
|
||||
@@ -79,7 +82,7 @@ class TestElixirLanguageServerSymbols:
|
||||
assert "UserService" in containing_symbol["name"]
|
||||
assert containing_symbol["kind"] == SymbolKind.Module or containing_symbol["kind"] == SymbolKind.Class
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_containing_symbol_nested(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_containing_symbol with nested scopes."""
|
||||
# Test for a position inside a function which is inside a module
|
||||
@@ -104,7 +107,7 @@ class TestElixirLanguageServerSymbols:
|
||||
expected_names = ["create_user", "UserService"]
|
||||
assert any(name in containing_symbol["name"] for name in expected_names)
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_containing_symbol_none(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_containing_symbol for a position with no containing symbol."""
|
||||
# Test for a position outside any function/module (e.g., in module doc)
|
||||
@@ -116,7 +119,7 @@ class TestElixirLanguageServerSymbols:
|
||||
# This is acceptable behavior for module-level positions
|
||||
assert containing_symbol is None or containing_symbol == {} or "TestRepo.Services" in str(containing_symbol)
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_referencing_symbols_struct(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_referencing_symbols for a struct."""
|
||||
# Test referencing symbols for User struct
|
||||
@@ -146,7 +149,7 @@ class TestElixirLanguageServerSymbols:
|
||||
# We expect some references from services.ex
|
||||
assert len(services_references) >= 0 # At least attempt to find references
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_referencing_symbols_none(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_referencing_symbols for a position with no symbol."""
|
||||
file_path = os.path.join("lib", "services.ex")
|
||||
@@ -164,7 +167,7 @@ class TestElixirLanguageServerSymbols:
|
||||
@pytest.mark.xfail(
|
||||
reason="Expert 0.1.0 bug: definition request crashes (FunctionClauseError in XPExpert.Protocol.Conversions.to_elixir/2)"
|
||||
)
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_defining_symbol_function_call(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_defining_symbol for a function call."""
|
||||
# Find a place where User.new is called in services.ex
|
||||
@@ -191,7 +194,7 @@ class TestElixirLanguageServerSymbols:
|
||||
@pytest.mark.xfail(
|
||||
reason="Expert 0.1.0 bug: definition request crashes (FunctionClauseError in XPExpert.Protocol.Conversions.to_elixir/2)"
|
||||
)
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_defining_symbol_struct_usage(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_defining_symbol for a struct usage."""
|
||||
# Find a place where User struct is used in services.ex
|
||||
@@ -215,7 +218,7 @@ class TestElixirLanguageServerSymbols:
|
||||
@pytest.mark.xfail(
|
||||
reason="Expert 0.1.0 bug: definition request crashes (FunctionClauseError in XPExpert.Protocol.Conversions.to_elixir/2)"
|
||||
)
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_defining_symbol_none(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_defining_symbol for a position with no symbol."""
|
||||
# Test for a position with no symbol (e.g., whitespace or comment)
|
||||
@@ -226,7 +229,7 @@ class TestElixirLanguageServerSymbols:
|
||||
# Should return None or empty
|
||||
assert defining_symbol is None or defining_symbol == {}
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_symbol_methods_integration(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test integration between different symbol methods."""
|
||||
file_path = os.path.join("lib", "models.ex")
|
||||
@@ -257,7 +260,7 @@ class TestElixirLanguageServerSymbols:
|
||||
assert isinstance(refs, list)
|
||||
|
||||
@pytest.mark.xfail(reason="Flaky test, sometimes fails with an Expert-internal error")
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_symbol_tree_structure(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test that symbol tree structure is correctly built."""
|
||||
symbol_tree = language_server.request_full_symbol_tree()
|
||||
@@ -283,7 +286,7 @@ class TestElixirLanguageServerSymbols:
|
||||
found_modules = [name for name in expected_modules if name in file_names]
|
||||
assert len(found_modules) > 0, f"Expected to find some modules from {expected_modules}, but got {file_names}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_request_dir_overview(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test request_dir_overview functionality."""
|
||||
lib_overview = language_server.request_dir_overview("lib")
|
||||
@@ -321,7 +324,7 @@ class TestElixirLanguageServerSymbols:
|
||||
# found_terms = [term for term in expected_terms if term in overview_text]
|
||||
# assert len(found_terms) > 0, f"Expected to find some terms from {expected_terms} in overview"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.ELIXIR], indirect=True)
|
||||
@pytest.mark.parametrize("language_server", [LanguageServerId.ELIXIR], indirect=True)
|
||||
def test_containing_symbol_of_module_attribute(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test containing symbol for module attributes."""
|
||||
file_path = os.path.join("lib", "models.ex")
|
||||
|
||||
Reference in new issue
Block a user