mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 08:15:59 +00:00
test: Add comprehensive TOML language server tests
Add 28 new tests across 4 test files for Taplo TOML language support: - test_toml_edge_cases.py: Tests for inline tables, multiline strings, arrays of tables, nested tables, datetime values, and dependency tables - test_toml_ignored_dirs.py: Tests for TOML-specific directory ignoring (target, .cargo, node_modules) - test_toml_symbol_retrieval.py: Tests for document overview, symbol tree, directory overview, and symbol hierarchy operations - __init__.py: Package initialization Also adds config.toml test fixture with comprehensive TOML features for edge case testing. Total: 35 TOML tests (7 basic + 28 new), all passing.
This commit is contained in:
1 parent
8b4cd2d33e
commit
5b31dfffed
5 files changed
+591
No files matched your search
@@ -0,0 +1,66 @@
|
||||
# Configuration file with various TOML features for testing
|
||||
|
||||
[server]
|
||||
host = "localhost"
|
||||
port = 8080
|
||||
debug = false
|
||||
timeout = 30.5
|
||||
|
||||
# Inline table example
|
||||
endpoint = { url = "https://api.example.com", version = "v1" }
|
||||
|
||||
[server.ssl]
|
||||
enabled = true
|
||||
cert_path = "/etc/ssl/cert.pem"
|
||||
key_path = "/etc/ssl/key.pem"
|
||||
|
||||
[database]
|
||||
connection_string = """
|
||||
postgresql://user:password@localhost:5432/mydb?
|
||||
sslmode=require&
|
||||
pool_size=10
|
||||
"""
|
||||
|
||||
[database.pool]
|
||||
min_connections = 5
|
||||
max_connections = 20
|
||||
idle_timeout = 300
|
||||
|
||||
[logging]
|
||||
level = "info"
|
||||
format = "json"
|
||||
outputs = ["stdout", "file"]
|
||||
|
||||
[logging.file]
|
||||
path = "/var/log/app.log"
|
||||
max_size = 10485760 # 10MB
|
||||
max_backups = 5
|
||||
compress = true
|
||||
|
||||
# Array of inline tables
|
||||
[[endpoints]]
|
||||
name = "users"
|
||||
path = "/api/users"
|
||||
methods = ["GET", "POST", "PUT", "DELETE"]
|
||||
auth_required = true
|
||||
|
||||
[[endpoints]]
|
||||
name = "health"
|
||||
path = "/health"
|
||||
methods = ["GET"]
|
||||
auth_required = false
|
||||
|
||||
# Datetime values
|
||||
[metadata]
|
||||
created = 1979-05-27T07:32:00Z
|
||||
updated = 2024-01-15T10:30:00-05:00
|
||||
|
||||
# Special characters in strings
|
||||
[messages]
|
||||
welcome = "Hello, World!"
|
||||
multiline = '''
|
||||
This is a
|
||||
multiline literal
|
||||
string.
|
||||
'''
|
||||
with_escapes = "Line1\nLine2\tTabbed"
|
||||
@@ -0,0 +1 @@
|
||||
"""TOML language server tests."""
|
||||
@@ -0,0 +1,273 @@
|
||||
"""
|
||||
Tests for TOML language server edge cases and advanced features.
|
||||
|
||||
These tests cover:
|
||||
- Inline tables
|
||||
- Multiline strings
|
||||
- Arrays of tables
|
||||
- Nested tables
|
||||
- Various TOML data types
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
|
||||
pytestmark = pytest.mark.toml
|
||||
|
||||
|
||||
class TestTomlEdgeCases:
|
||||
"""Test TOML language server handling of edge cases and advanced features."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_inline_table_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that inline tables are properly detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
assert all_symbols is not None
|
||||
assert len(all_symbols) > 0
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# The inline table 'endpoint' should be detected
|
||||
assert "endpoint" in symbol_names, "Should detect 'endpoint' inline table"
|
||||
|
||||
# Find the endpoint symbol and check its properties
|
||||
endpoint_symbol = next((s for s in all_symbols if s.get("name") == "endpoint"), None)
|
||||
assert endpoint_symbol is not None
|
||||
# Inline tables should be kind 19 (object)
|
||||
assert endpoint_symbol.get("kind") == 19, "Inline table should have kind 19 (object)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_nested_table_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that deeply nested tables are properly detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect nested tables like server.ssl and database.pool
|
||||
has_ssl = any("ssl" in str(name).lower() for name in symbol_names if name)
|
||||
has_pool = any("pool" in str(name).lower() for name in symbol_names if name)
|
||||
|
||||
assert has_ssl, f"Should detect 'server.ssl' nested table, got: {symbol_names}"
|
||||
assert has_pool, f"Should detect 'database.pool' nested table, got: {symbol_names}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_array_of_tables_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that [[array_of_tables]] syntax is properly detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect [[endpoints]] array of tables
|
||||
assert "endpoints" in symbol_names, f"Should detect '[[endpoints]]' array of tables, got: {symbol_names}"
|
||||
|
||||
# Find the endpoints symbol
|
||||
endpoints_symbol = next((s for s in all_symbols if s.get("name") == "endpoints"), None)
|
||||
assert endpoints_symbol is not None
|
||||
|
||||
# Array of tables should be kind 18 (array)
|
||||
assert endpoints_symbol.get("kind") == 18, "Array of tables should have kind 18 (array)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_multiline_string_handling(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that multiline strings are handled correctly."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect connection_string and multiline fields
|
||||
assert "connection_string" in symbol_names, "Should detect 'connection_string' with multiline value"
|
||||
assert "multiline" in symbol_names, "Should detect 'multiline' literal string"
|
||||
|
||||
# Find connection_string and verify it's a string type
|
||||
conn_symbol = next((s for s in all_symbols if s.get("name") == "connection_string"), None)
|
||||
assert conn_symbol is not None
|
||||
# String type should be kind 15
|
||||
assert conn_symbol.get("kind") == 15, "Multiline string should have kind 15 (string)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_array_value_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that array values are properly detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect 'outputs' and 'methods' arrays
|
||||
assert "outputs" in symbol_names, "Should detect 'outputs' array"
|
||||
assert "methods" in symbol_names, "Should detect 'methods' array"
|
||||
|
||||
# Find outputs array and verify kind
|
||||
outputs_symbol = next((s for s in all_symbols if s.get("name") == "outputs"), None)
|
||||
assert outputs_symbol is not None
|
||||
# Arrays should have kind 18
|
||||
assert outputs_symbol.get("kind") == 18, "'outputs' should have kind 18 (array)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_float_value_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that float values are properly detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect 'timeout' which has a float value (30.5)
|
||||
assert "timeout" in symbol_names, "Should detect 'timeout' float value"
|
||||
|
||||
# Find timeout and verify it's a number
|
||||
timeout_symbol = next((s for s in all_symbols if s.get("name") == "timeout"), None)
|
||||
assert timeout_symbol is not None
|
||||
# Numbers should have kind 16
|
||||
assert timeout_symbol.get("kind") == 16, "'timeout' should have kind 16 (number)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_datetime_value_detection(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that datetime values are detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect metadata section with datetime values
|
||||
assert "metadata" in symbol_names, "Should detect 'metadata' section"
|
||||
assert "created" in symbol_names, "Should detect 'created' datetime field"
|
||||
assert "updated" in symbol_names, "Should detect 'updated' datetime field"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_symbol_body_with_inline_table(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that symbol bodies include inline table content."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Find the endpoint symbol with body
|
||||
endpoint_symbol = next((s for s in all_symbols if s.get("name") == "endpoint"), None)
|
||||
assert endpoint_symbol is not None
|
||||
|
||||
if "body" in endpoint_symbol:
|
||||
body = endpoint_symbol["body"]
|
||||
# Body should contain the inline table syntax
|
||||
assert "url" in body or "version" in body, f"Body should contain inline table contents, got: {body}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_symbol_ranges_in_config(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that symbol ranges are correct in config.toml."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Find the server symbol
|
||||
server_symbol = next((s for s in all_symbols if s.get("name") == "server"), None)
|
||||
assert server_symbol is not None
|
||||
assert "range" in server_symbol
|
||||
|
||||
# Server should start near the beginning (line 2 is [server], 0-indexed: line 2)
|
||||
server_range = server_symbol["range"]
|
||||
assert server_range["start"]["line"] >= 0, "Server should start at or near the beginning"
|
||||
assert server_range["end"]["line"] > server_range["start"]["line"], "Server block should span multiple lines"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_comment_handling(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that comments don't interfere with symbol detection."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# File has comments but symbols should still be detected correctly
|
||||
expected_sections = {"server", "database", "logging", "endpoints", "metadata", "messages"}
|
||||
found_sections = expected_sections.intersection(set(symbol_names))
|
||||
|
||||
assert len(found_sections) >= 4, f"Should find most sections despite comments, found: {found_sections}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_special_characters_in_strings(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that strings with escape sequences are handled."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("config.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect the messages section with special strings
|
||||
assert "messages" in symbol_names, "Should detect 'messages' section"
|
||||
assert "with_escapes" in symbol_names, "Should detect 'with_escapes' field"
|
||||
assert "welcome" in symbol_names, "Should detect 'welcome' field"
|
||||
|
||||
|
||||
class TestTomlDependencyTables:
|
||||
"""Test handling of dependency-style tables common in Cargo.toml and pyproject.toml."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_complex_dependency_inline_table(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test detection of complex inline table dependencies like serde = { version = "1.0", features = ["derive"] }."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("Cargo.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect serde and tokio dependencies
|
||||
assert "serde" in symbol_names, "Should detect 'serde' dependency"
|
||||
assert "tokio" in symbol_names, "Should detect 'tokio' dependency"
|
||||
|
||||
# Find serde symbol
|
||||
serde_symbol = next((s for s in all_symbols if s.get("name") == "serde"), None)
|
||||
assert serde_symbol is not None
|
||||
|
||||
# Dependency with inline table should be kind 19 (object)
|
||||
assert serde_symbol.get("kind") == 19, "Complex dependency should have kind 19 (object)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_simple_dependency_string(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test detection of simple string dependencies like proptest = "1.0"."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("Cargo.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect proptest dev-dependency
|
||||
assert "proptest" in symbol_names, "Should detect 'proptest' dependency"
|
||||
|
||||
# Find proptest symbol
|
||||
proptest_symbol = next((s for s in all_symbols if s.get("name") == "proptest"), None)
|
||||
assert proptest_symbol is not None
|
||||
|
||||
# Simple string dependency should be kind 15 (string)
|
||||
assert proptest_symbol.get("kind") == 15, "Simple string dependency should have kind 15 (string)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_pyproject_dependencies_array(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test detection of pyproject.toml dependencies array."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("pyproject.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect dependencies array
|
||||
assert "dependencies" in symbol_names, "Should detect 'dependencies' array"
|
||||
|
||||
# Find dependencies symbol
|
||||
deps_symbol = next((s for s in all_symbols if s.get("name") == "dependencies"), None)
|
||||
assert deps_symbol is not None
|
||||
|
||||
# Dependencies array should be kind 18 (array)
|
||||
assert deps_symbol.get("kind") == 18, "Dependencies array should have kind 18 (array)"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_optional_dependencies_table(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test detection of optional-dependencies in pyproject.toml."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("pyproject.toml").get_all_symbols_and_roots()
|
||||
|
||||
symbol_names = [sym.get("name") for sym in all_symbols]
|
||||
|
||||
# Should detect optional-dependencies or its nested form
|
||||
has_optional_deps = any("optional" in str(name).lower() for name in symbol_names if name)
|
||||
has_dev = "dev" in symbol_names
|
||||
|
||||
assert has_optional_deps or has_dev, f"Should detect optional-dependencies or dev group, got: {symbol_names}"
|
||||
@@ -0,0 +1,60 @@
|
||||
"""
|
||||
Tests for TOML language server directory ignoring functionality.
|
||||
|
||||
These tests validate that the Taplo language server correctly ignores
|
||||
TOML-specific directories like target, .cargo, and node_modules.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
|
||||
pytestmark = pytest.mark.toml
|
||||
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
class TestTomlIgnoredDirectories:
|
||||
"""Test TOML-specific directory ignoring behavior."""
|
||||
|
||||
def test_default_ignored_directories(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test that default TOML directories are ignored."""
|
||||
# Test that TOML/Rust/Node-specific directories are ignored by default
|
||||
assert language_server.is_ignored_dirname("target"), "target should be ignored"
|
||||
assert language_server.is_ignored_dirname(".cargo"), ".cargo should be ignored"
|
||||
assert language_server.is_ignored_dirname("node_modules"), "node_modules should be ignored"
|
||||
|
||||
# Directories starting with . are ignored by base class
|
||||
assert language_server.is_ignored_dirname(".git"), ".git should be ignored"
|
||||
assert language_server.is_ignored_dirname(".venv"), ".venv should be ignored"
|
||||
|
||||
def test_important_directories_not_ignored(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test that important directories are not ignored."""
|
||||
# Common project directories should not be ignored
|
||||
assert not language_server.is_ignored_dirname("src"), "src should not be ignored"
|
||||
assert not language_server.is_ignored_dirname("crates"), "crates should not be ignored"
|
||||
assert not language_server.is_ignored_dirname("lib"), "lib should not be ignored"
|
||||
assert not language_server.is_ignored_dirname("tests"), "tests should not be ignored"
|
||||
assert not language_server.is_ignored_dirname("config"), "config should not be ignored"
|
||||
|
||||
def test_cargo_related_directories(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test Cargo/Rust-related directory handling."""
|
||||
# Rust build directories should be ignored
|
||||
assert language_server.is_ignored_dirname("target"), "target (Rust build) should be ignored"
|
||||
assert language_server.is_ignored_dirname(".cargo"), ".cargo should be ignored"
|
||||
|
||||
# But important Rust directories should not be ignored
|
||||
assert not language_server.is_ignored_dirname("benches"), "benches should not be ignored"
|
||||
assert not language_server.is_ignored_dirname("examples"), "examples should not be ignored"
|
||||
|
||||
def test_various_cache_directories(self, language_server: SolidLanguageServer) -> None:
|
||||
"""Test various cache and temporary directories are ignored."""
|
||||
# Directories starting with . are ignored by base class
|
||||
assert language_server.is_ignored_dirname(".cache"), ".cache should be ignored"
|
||||
|
||||
# IDE directories (start with .)
|
||||
assert language_server.is_ignored_dirname(".idea"), ".idea should be ignored"
|
||||
assert language_server.is_ignored_dirname(".vscode"), ".vscode should be ignored"
|
||||
|
||||
# Note: __pycache__ is NOT ignored by TOML server (only Python servers ignore it)
|
||||
assert not language_server.is_ignored_dirname("__pycache__"), "__pycache__ is not TOML-specific"
|
||||
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
Tests for TOML language server symbol retrieval functionality.
|
||||
|
||||
These tests focus on advanced symbol operations:
|
||||
- request_containing_symbol
|
||||
- request_document_overview
|
||||
- request_full_symbol_tree
|
||||
- request_dir_overview
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from solidlsp import SolidLanguageServer
|
||||
from solidlsp.ls_config import Language
|
||||
|
||||
pytestmark = pytest.mark.toml
|
||||
|
||||
|
||||
class TestTomlSymbolRetrieval:
|
||||
"""Test advanced symbol retrieval functionality for TOML files."""
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_request_containing_symbol_behavior(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test request_containing_symbol behavior for TOML files.
|
||||
|
||||
Note: Taplo LSP doesn't support definition/containing symbol lookups for TOML files
|
||||
since TOML is a configuration format, not code. This test verifies the behavior.
|
||||
"""
|
||||
# Line 2 (0-indexed: 1) is inside the [package] table
|
||||
containing_symbol = language_server.request_containing_symbol("Cargo.toml", 1, 5)
|
||||
|
||||
# Taplo doesn't support containing symbol lookup - returns None
|
||||
# This is expected behavior for a configuration file format
|
||||
assert containing_symbol is None, "TOML LSP doesn't support containing symbol lookup"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_request_document_overview_cargo(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test request_document_overview for Cargo.toml."""
|
||||
overview = language_server.request_document_overview("Cargo.toml")
|
||||
|
||||
assert overview is not None
|
||||
assert len(overview) > 0
|
||||
|
||||
# Get symbol names from overview
|
||||
symbol_names = {symbol.get("name") for symbol in overview if "name" in symbol}
|
||||
|
||||
# Verify expected top-level tables appear
|
||||
expected_tables = {"package", "dependencies", "dev-dependencies", "features", "workspace"}
|
||||
assert expected_tables.issubset(symbol_names), f"Missing expected tables in overview: {expected_tables - symbol_names}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_request_document_overview_pyproject(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test request_document_overview for pyproject.toml."""
|
||||
overview = language_server.request_document_overview("pyproject.toml")
|
||||
|
||||
assert overview is not None
|
||||
assert len(overview) > 0
|
||||
|
||||
# Get symbol names from overview
|
||||
symbol_names = {symbol.get("name") for symbol in overview if "name" in symbol}
|
||||
|
||||
# Verify expected top-level tables appear
|
||||
assert "project" in symbol_names, "Should detect 'project' table"
|
||||
assert "build-system" in symbol_names, "Should detect 'build-system' table"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_request_full_symbol_tree(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test request_full_symbol_tree returns TOML files."""
|
||||
symbol_tree = language_server.request_full_symbol_tree()
|
||||
|
||||
assert symbol_tree is not None
|
||||
assert len(symbol_tree) > 0
|
||||
|
||||
# The root should be test_repo
|
||||
root = symbol_tree[0]
|
||||
assert root["name"] == "test_repo"
|
||||
assert "children" in root
|
||||
|
||||
# Children should include TOML files
|
||||
child_names = {child["name"] for child in root.get("children", [])}
|
||||
# Note: File names are stripped of extension in some cases
|
||||
assert "Cargo" in child_names or "Cargo.toml" in child_names or any("cargo" in name.lower() for name in child_names), (
|
||||
f"Should find Cargo.toml in tree, got: {child_names}"
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_request_dir_overview(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test request_dir_overview returns symbols for TOML files."""
|
||||
overview = language_server.request_dir_overview(".")
|
||||
|
||||
assert overview is not None
|
||||
assert len(overview) > 0
|
||||
|
||||
# Should have entries for both Cargo.toml and pyproject.toml
|
||||
file_paths = list(overview.keys())
|
||||
assert any("Cargo.toml" in path for path in file_paths), f"Should find Cargo.toml in overview, got: {file_paths}"
|
||||
assert any("pyproject.toml" in path for path in file_paths), f"Should find pyproject.toml in overview, got: {file_paths}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_symbol_hierarchy_in_cargo(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that symbol hierarchy is properly preserved in Cargo.toml."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("Cargo.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Find the 'package' table
|
||||
package_symbol = next((s for s in root_symbols if s.get("name") == "package"), None)
|
||||
assert package_symbol is not None, "Should find 'package' as root symbol"
|
||||
|
||||
# Verify it has children (nested keys)
|
||||
assert "children" in package_symbol, "'package' should have children"
|
||||
child_names = {child.get("name") for child in package_symbol.get("children", [])}
|
||||
|
||||
# Package should have name, version, edition at minimum
|
||||
assert "name" in child_names, "'package' should have 'name' child"
|
||||
assert "version" in child_names, "'package' should have 'version' child"
|
||||
assert "edition" in child_names, "'package' should have 'edition' child"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_symbol_hierarchy_in_pyproject(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that symbol hierarchy is properly preserved in pyproject.toml."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("pyproject.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Find the 'project' table
|
||||
project_symbol = next((s for s in root_symbols if s.get("name") == "project"), None)
|
||||
assert project_symbol is not None, "Should find 'project' as root symbol"
|
||||
|
||||
# Verify it has children
|
||||
assert "children" in project_symbol, "'project' should have children"
|
||||
child_names = {child.get("name") for child in project_symbol.get("children", [])}
|
||||
|
||||
# Project should have name, version, dependencies at minimum
|
||||
assert "name" in child_names, "'project' should have 'name' child"
|
||||
assert "version" in child_names, "'project' should have 'version' child"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_tool_section_hierarchy(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that tool sections in pyproject.toml are properly structured."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("pyproject.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Get all symbol names
|
||||
all_names = [s.get("name") for s in all_symbols]
|
||||
|
||||
# Should detect tool.ruff, tool.mypy, or tool.pytest
|
||||
has_ruff = any("ruff" in name.lower() for name in all_names if name)
|
||||
has_mypy = any("mypy" in name.lower() for name in all_names if name)
|
||||
has_pytest = any("pytest" in name.lower() for name in all_names if name)
|
||||
|
||||
assert has_ruff or has_mypy or has_pytest, f"Should detect tool sections, got names: {all_names}"
|
||||
|
||||
@pytest.mark.parametrize("language_server", [Language.TOML], indirect=True)
|
||||
@pytest.mark.parametrize("repo_path", [Language.TOML], indirect=True)
|
||||
def test_array_of_tables_symbol(self, language_server: SolidLanguageServer, repo_path: Path) -> None:
|
||||
"""Test that [[bin]] array of tables is detected."""
|
||||
all_symbols, root_symbols = language_server.request_document_symbols("Cargo.toml").get_all_symbols_and_roots()
|
||||
|
||||
# Get all symbol names
|
||||
all_names = [s.get("name") for s in all_symbols]
|
||||
|
||||
# Should detect bin array of tables
|
||||
has_bin = "bin" in all_names
|
||||
assert has_bin, f"Should detect [[bin]] array of tables, got names: {all_names}"
|
||||
|
||||
# Find the bin symbol and verify its structure
|
||||
bin_symbol = next((s for s in all_symbols if s.get("name") == "bin"), None)
|
||||
assert bin_symbol is not None, "Should find bin symbol"
|
||||
|
||||
# Array of tables should be kind 18 (array)
|
||||
assert bin_symbol.get("kind") == 18, "[[bin]] should have kind 18 (array)"
|
||||
|
||||
# Children of array of tables are indexed by position ('0', '1', etc.)
|
||||
if "children" in bin_symbol:
|
||||
bin_children = bin_symbol.get("children", [])
|
||||
assert len(bin_children) > 0, "[[bin]] should have at least one child element"
|
||||
# First child is index '0'
|
||||
first_child = bin_children[0]
|
||||
assert first_child.get("name") == "0", f"First array element should be named '0', got: {first_child.get('name')}"
|
||||
|
||||
# The '0' element should contain name and path as grandchildren
|
||||
if "children" in first_child:
|
||||
grandchild_names = {gc.get("name") for gc in first_child.get("children", [])}
|
||||
assert "name" in grandchild_names, f"[[bin]] element should have 'name' field, got: {grandchild_names}"
|
||||
assert "path" in grandchild_names, f"[[bin]] element should have 'path' field, got: {grandchild_names}"
|
||||
Reference in new issue
Block a user