Merge pull request #102 from oraios/tests/test_ls_on_rust

Tests for rust
This commit is contained in:
Michael Panchenko authored and GitHub committed 2025-04-27 16:05:35 +02:00
commit 483744cf3a
8 files changed
+196 -49

No files matched your search

+19 -6
View File
@@ -28,7 +28,6 @@ class TestJavaLanguageServer:
# Use correct Maven/Java file paths
file_path = os.path.join("src", "main", "java", "test_repo", "Utils.java")
refs = language_server.request_references(file_path, 4, 20)
print(f"References for Utils.printHello: {refs}")
assert any("Main.java" in ref.get("relativePath", "") for ref in refs), "Main should reference Utils.printHello"
# Dynamically determine the correct line/column for the 'Model' class name
@@ -40,11 +39,25 @@ class TestJavaLanguageServer:
model_symbol = sym
break
assert model_symbol is not None, "Could not find 'Model' class symbol in Model.java"
rng = model_symbol["range"]["start"]
print(f"Model symbol range: {model_symbol['range']}")
refs = language_server.request_references(file_path, rng["line"], rng["character"])
print(f"References for Model class: {refs}")
assert any("Main.java" in ref.get("relativePath", "") for ref in refs), "Main should reference Model"
# Use selectionRange if present, otherwise fall back to range
if "selectionRange" in model_symbol:
sel_start = model_symbol["selectionRange"]["start"]
sel_end = model_symbol["selectionRange"]["end"]
else:
sel_start = model_symbol["range"]["start"]
sel_end = model_symbol["range"]["end"]
found = False
if sel_start["line"] == sel_end["line"]:
for col in range(sel_start["character"], sel_end["character"] + 1):
refs = language_server.request_references(file_path, sel_start["line"], col)
if any("Main.java" in ref.get("relativePath", "") for ref in refs):
found = True
else:
refs_start = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
refs_end = language_server.request_references(file_path, sel_end["line"], sel_end["character"])
if any("Main.java" in ref.get("relativePath", "") for ref in refs_start + refs_end):
found = True
assert found, "Main should reference Model (tried all positions in selectionRange)"
@pytest.mark.parametrize("language_server", [Language.JAVA], indirect=True)
def test_overview_methods(self, language_server):
+32 -22
View File
@@ -23,13 +23,14 @@ class TestLanguageServerBasics:
# Get references to the User class in models.py
file_path = os.path.join("test_repo", "models.py")
# Line 31 contains the User class definition
references = language_server.request_references(file_path, 31, 6)
# User class should be referenced in multiple files
assert len(references) > 0
# At least two references should be found (one for the class definition itself)
assert len(references) > 1
# Use selectionRange only
symbols = language_server.request_document_symbols(file_path)
user_symbol = next((s for s in symbols[0] if s.get("name") == "User"), None)
if not user_symbol or "selectionRange" not in user_symbol:
raise AssertionError("User symbol or its selectionRange not found")
sel_start = user_symbol["selectionRange"]["start"]
references = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
assert len(references) > 1, "User class should be referenced in multiple files (using selectionRange if present)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_request_references_item_class(self, language_server: SyncLanguageServer):
@@ -37,14 +38,15 @@ class TestLanguageServerBasics:
# Get references to the Item class in models.py
file_path = os.path.join("test_repo", "models.py")
# Line 56 contains the Item class definition
references = language_server.request_references(file_path, 56, 6)
# Item class should be referenced in multiple places
assert len(references) > 0
# At least one reference should be in services.py (ItemService class)
# Use selectionRange only
symbols = language_server.request_document_symbols(file_path)
item_symbol = next((s for s in symbols[0] if s.get("name") == "Item"), None)
if not item_symbol or "selectionRange" not in item_symbol:
raise AssertionError("Item symbol or its selectionRange not found")
sel_start = item_symbol["selectionRange"]["start"]
references = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
services_references = [ref for ref in references if "services.py" in ref["uri"]]
assert len(services_references) > 0
assert len(services_references) > 0, "At least one reference should be in services.py (using selectionRange if present)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_request_references_function_parameter(self, language_server: SyncLanguageServer):
@@ -52,20 +54,28 @@ class TestLanguageServerBasics:
# Get references to the id parameter in get_user method
file_path = os.path.join("test_repo", "services.py")
# Line 24 contains the get_user method with id parameter
references = language_server.request_references(file_path, 24, 16)
# id parameter should be referenced within the method
assert len(references) > 0
# Use selectionRange only
symbols = language_server.request_document_symbols(file_path)
get_user_symbol = next((s for s in symbols[0] if s.get("name") == "get_user"), None)
if not get_user_symbol or "selectionRange" not in get_user_symbol:
raise AssertionError("get_user symbol or its selectionRange not found")
sel_start = get_user_symbol["selectionRange"]["start"]
references = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
assert len(references) > 0, "id parameter should be referenced within the method (using selectionRange if present)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_request_references_create_user_method(self, language_server: SyncLanguageServer):
# Get references to the create_user method in UserService
file_path = os.path.join("test_repo", "services.py")
# Line 15 contains the create_user method definition
references = language_server.request_references(file_path, 15, 9)
# Verify that we get valid references
assert len(references) > 1
# Use selectionRange only
symbols = language_server.request_document_symbols(file_path)
create_user_symbol = next((s for s in symbols[0] if s.get("name") == "create_user"), None)
if not create_user_symbol or "selectionRange" not in create_user_symbol:
raise AssertionError("create_user symbol or its selectionRange not found")
sel_start = create_user_symbol["selectionRange"]["start"]
references = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
assert len(references) > 1, "Should get valid references for create_user (using selectionRange if present)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_retrieve_content_around_line(self, language_server: SyncLanguageServer):
+24 -21
View File
@@ -104,10 +104,13 @@ class TestLanguageServerSymbols:
# Test referencing symbols for create_user function
file_path = os.path.join("test_repo", "services.py")
# Line 15 contains the create_user function definition
ref_symbols = language_server.request_referencing_symbols(file_path, 15, 9)
# Verify we get referencing symbols
assert len(ref_symbols) > 0
symbols = language_server.request_document_symbols(file_path)
create_user_symbol = next((s for s in symbols[0] if s.get("name") == "create_user"), None)
if not create_user_symbol or "selectionRange" not in create_user_symbol:
raise AssertionError("create_user symbol or its selectionRange not found")
sel_start = create_user_symbol["selectionRange"]["start"]
ref_symbols = language_server.request_referencing_symbols(file_path, sel_start["line"], sel_start["character"])
assert len(ref_symbols) > 0, "No referencing symbols found for create_user (selectionRange)"
# Verify the structure of referencing symbols
for symbol in ref_symbols:
@@ -123,19 +126,18 @@ class TestLanguageServerSymbols:
# Test referencing symbols for User class
file_path = os.path.join("test_repo", "models.py")
# Line 31 contains the User class definition
ref_symbols = language_server.request_referencing_symbols(file_path, 31, 6)
# Verify we get referencing symbols
assert len(ref_symbols) > 0
# At least one reference should be from services.py
symbols = language_server.request_document_symbols(file_path)
user_symbol = next((s for s in symbols[0] if s.get("name") == "User"), None)
if not user_symbol or "selectionRange" not in user_symbol:
raise AssertionError("User symbol or its selectionRange not found")
sel_start = user_symbol["selectionRange"]["start"]
ref_symbols = language_server.request_referencing_symbols(file_path, sel_start["line"], sel_start["character"])
services_references = [
symbol
for symbol in ref_symbols
if "location" in symbol and "uri" in symbol["location"] and "services.py" in symbol["location"]["uri"]
]
assert len(services_references) > 0
assert len(services_references) > 0, "No referencing symbols from services.py for User (selectionRange)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_request_referencing_symbols_parameter(self, language_server: SyncLanguageServer):
@@ -143,19 +145,20 @@ class TestLanguageServerSymbols:
# Test referencing symbols for id parameter in get_user
file_path = os.path.join("test_repo", "services.py")
# Line 24 contains the get_user method with id parameter
ref_symbols = language_server.request_referencing_symbols(file_path, 24, 16)
# Verify we get referencing symbols
assert len(ref_symbols) > 0
# Verify the symbols include references within the method body
symbols = language_server.request_document_symbols(file_path)
get_user_symbol = next((s for s in symbols[0] if s.get("name") == "get_user"), None)
if not get_user_symbol or "selectionRange" not in get_user_symbol:
raise AssertionError("get_user symbol or its selectionRange not found")
sel_start = get_user_symbol["selectionRange"]["start"]
ref_symbols = language_server.request_referencing_symbols(file_path, sel_start["line"], sel_start["character"])
method_refs = [
symbol
for symbol in ref_symbols
if "location" in symbol and "range" in symbol["location"] and symbol["location"]["range"]["start"]["line"] > 24
if "location" in symbol
and "range" in symbol["location"]
and symbol["location"]["range"]["start"]["line"] > sel_start["line"]
]
assert len(method_refs) > 0
assert len(method_refs) > 0, "No referencing symbols within method body for get_user (selectionRange)"
@pytest.mark.parametrize("language_server", [Language.PYTHON], indirect=True)
def test_request_referencing_symbols_none(self, language_server: SyncLanguageServer):
+91
View File
@@ -0,0 +1,91 @@
import os
import pytest
from multilspy.multilspy_config import Language
def find_symbol_recursive(symbols, name):
for symbol in symbols:
if symbol.get("name") == name:
return True
if symbol.get("children"):
if find_symbol_recursive(symbol["children"], name):
return True
return False
class TestRustLanguageServer:
@pytest.mark.parametrize("language_server", [Language.RUST], indirect=True)
def test_find_references_raw(self, language_server):
# Directly test the request_references method for the add function
file_path = os.path.join("src", "lib.rs")
symbols = language_server.request_document_symbols(file_path)
add_symbol = None
for sym in symbols[0]:
if sym.get("name") == "add":
add_symbol = sym
break
assert add_symbol is not None, "Could not find 'add' function symbol in lib.rs"
sel_start = add_symbol["selectionRange"]["start"]
sel_end = add_symbol["selectionRange"]["end"]
found = False
if sel_start["line"] == sel_end["line"]:
for col in range(sel_start["character"], sel_end["character"] + 1):
refs = language_server.request_references(file_path, sel_start["line"], col)
# f"Raw request_references for add in lib.rs at col {col}: {refs}")
if any("main.rs" in ref.get("relativePath", "") for ref in refs):
found = True
else:
refs_start = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
refs_end = language_server.request_references(file_path, sel_end["line"], sel_end["character"])
# f"Raw request_references for add in lib.rs at selectionRange start: {refs_start}")
# f"Raw request_references for add in lib.rs at selectionRange end: {refs_end}")
if any("main.rs" in ref.get("relativePath", "") for ref in refs_start + refs_end):
found = True
assert found, "main.rs should reference add (raw, tried all positions in selectionRange)"
@pytest.mark.parametrize("language_server", [Language.RUST], indirect=True)
def test_find_symbol(self, language_server):
symbols = language_server.request_full_symbol_tree()
assert find_symbol_recursive(symbols, "main"), "main function not found in symbol tree"
assert find_symbol_recursive(symbols, "add"), "add function not found in symbol tree"
# Add more as needed based on test_repo
@pytest.mark.parametrize("language_server", [Language.RUST], indirect=True)
def test_find_referencing_symbols(self, language_server):
# Find references to 'add' defined in lib.rs, should be referenced from main.rs
file_path = os.path.join("src", "lib.rs")
symbols = language_server.request_document_symbols(file_path)
add_symbol = None
for sym in symbols[0]:
if sym.get("name") == "add":
add_symbol = sym
break
assert add_symbol is not None, "Could not find 'add' function symbol in lib.rs"
sel_start = add_symbol["selectionRange"]["start"]
sel_end = add_symbol["selectionRange"]["end"]
# f"add symbol selectionRange: start={sel_start}, end={sel_end}")
found = False
# Try all character positions in the selectionRange (same line, from start to end character)
if sel_start["line"] == sel_end["line"]:
for col in range(sel_start["character"], sel_end["character"] + 1):
refs = language_server.request_references(file_path, sel_start["line"], col)
# f"References for add in lib.rs at col {col} (selectionRange): {refs}")
if any("main.rs" in ref.get("relativePath", "") for ref in refs):
found = True
else:
# If the function name spans multiple lines, try start and end
refs_start = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
refs_end = language_server.request_references(file_path, sel_end["line"], sel_end["character"])
# f"References for add in lib.rs at selectionRange start: {refs_start}")
# f"References for add in lib.rs at selectionRange end: {refs_end}")
if any("main.rs" in ref.get("relativePath", "") for ref in refs_start + refs_end):
found = True
assert found, "main.rs should reference add (tried all positions in selectionRange)"
@pytest.mark.parametrize("language_server", [Language.RUST], indirect=True)
def test_overview_methods(self, language_server):
symbols = language_server.request_full_symbol_tree()
assert find_symbol_recursive(symbols, "main"), "main missing from overview"
assert find_symbol_recursive(symbols, "add"), "add missing from overview"
+7
View File
@@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "rsandbox"
version = "0.1.0"
@@ -0,0 +1,6 @@
[package]
name = "rsandbox"
version = "0.1.0"
edition = "2021"
[dependencies]
@@ -0,0 +1,9 @@
// This function returns the sum of 2 + 2
pub fn add() -> i32 {
let res = 2 + 2;
res
}
pub fn multiply() -> i32 {
2 * 3
}
@@ -0,0 +1,8 @@
use rsandbox::add;
fn main() {
println!("Hello, World!");
println!("Good morning!");
println!("add result: {}", add());
println!("inserted line");
}