From e6f0ddacef9b42e754ecd8730d447fc09148987b Mon Sep 17 00:00:00 2001 From: Michael Panchenko Date: Sun, 27 Apr 2025 15:34:29 +0200 Subject: [PATCH] Tests for LS on rust, written by windsurf with GPT4.1 --- test/multilspy/rust/test_rust_basic.py | 87 +++++++++++++++++++ .../resources/repos/rust/test_repo/Cargo.lock | 7 ++ .../resources/repos/rust/test_repo/Cargo.toml | 6 ++ .../resources/repos/rust/test_repo/src/lib.rs | 9 ++ .../repos/rust/test_repo/src/main.rs | 8 ++ 5 files changed, 117 insertions(+) create mode 100644 test/multilspy/rust/test_rust_basic.py create mode 100644 test/resources/repos/rust/test_repo/Cargo.lock create mode 100644 test/resources/repos/rust/test_repo/Cargo.toml create mode 100644 test/resources/repos/rust/test_repo/src/lib.rs create mode 100644 test/resources/repos/rust/test_repo/src/main.rs diff --git a/test/multilspy/rust/test_rust_basic.py b/test/multilspy/rust/test_rust_basic.py new file mode 100644 index 0000000..2328227 --- /dev/null +++ b/test/multilspy/rust/test_rust_basic.py @@ -0,0 +1,87 @@ +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" diff --git a/test/resources/repos/rust/test_repo/Cargo.lock b/test/resources/repos/rust/test_repo/Cargo.lock new file mode 100644 index 0000000..ebc459f --- /dev/null +++ b/test/resources/repos/rust/test_repo/Cargo.lock @@ -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" diff --git a/test/resources/repos/rust/test_repo/Cargo.toml b/test/resources/repos/rust/test_repo/Cargo.toml new file mode 100644 index 0000000..43ffbf6 --- /dev/null +++ b/test/resources/repos/rust/test_repo/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rsandbox" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/test/resources/repos/rust/test_repo/src/lib.rs b/test/resources/repos/rust/test_repo/src/lib.rs new file mode 100644 index 0000000..8ad43ea --- /dev/null +++ b/test/resources/repos/rust/test_repo/src/lib.rs @@ -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 +} + diff --git a/test/resources/repos/rust/test_repo/src/main.rs b/test/resources/repos/rust/test_repo/src/main.rs new file mode 100644 index 0000000..7385c9d --- /dev/null +++ b/test/resources/repos/rust/test_repo/src/main.rs @@ -0,0 +1,8 @@ +use rsandbox::add; + +fn main() { + println!("Hello, World!"); + println!("Good morning!"); + println!("add result: {}", add()); + println!("inserted line"); +}