Files
wehub-resource-sync c6af9e284a
Tests / catch-all (windows-latest) (push) Has been cancelled
Tests / jvm (macos-latest) (push) Has been cancelled
Tests / jvm (ubuntu-latest) (push) Has been cancelled
Tests / jvm (windows-latest) (push) Has been cancelled
Tests / native (macos-latest) (push) Has been cancelled
Tests / native (ubuntu-latest) (push) Has been cancelled
Tests / native (windows-latest) (push) Has been cancelled
Tests / niche (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (macos-latest) (push) Has been cancelled
Tests / other-langs (ubuntu-latest) (push) Has been cancelled
Tests / other-langs (windows-latest) (push) Has been cancelled
Tests / catch-all (macos-latest) (push) Has been cancelled
Tests / catch-all (ubuntu-latest) (push) Has been cancelled
Docs Build / build (push) Has been cancelled
Docs Build / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Build and Push Docker Images / build-and-push (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:39:38 +08:00

111 lines
6.2 KiB
Python

"""Regression tests for clojure-lsp project-wide indexing.
Bug: ``find_referencing_symbols`` (and the underlying ``request_references``)
returns incomplete cross-file results unless the referencing files have already
been opened/indexed during the current session via ``find_symbol`` /
``get_symbols_overview``. The result is deterministically partial — it grows as
more files happen to get indexed by side-effect — which silently biases call
graphs towards files the user has already explored.
The tests here use a fresh module-scoped language server and probe a symbol
whose references live in a file (``extra.clj``) that no other test in this
module touches. The references must be returned even though no prior tool call
has caused the file to be opened in the LSP.
"""
from pathlib import Path
import pytest
from serena.util.text_utils import find_text_coordinates
from solidlsp.ls import SolidLanguageServer
from solidlsp.ls_config import Language
from test.conftest import language_tests_enabled
from test.solidlsp.conftest import read_repo_file
from . import CORE_PATH, TEST_APP_PATH
EXTRA_PATH = str(TEST_APP_PATH / "extra.clj")
SUBMODULE_CONSUMER_PATH = str(Path("sub_module") / "src" / "sub_module_app" / "consumer.clj")
@pytest.mark.skipif(not language_tests_enabled(Language.CLOJURE), reason="Clojure tests are disabled")
@pytest.mark.clojure
class TestClojureProjectIndexing:
"""Covers the "indexing leaks through results" bug for clojure-lsp.
The fixture is module-scoped, so all tests within this class share a single
server. We deliberately avoid any operation that would open ``extra.clj``
(``get_symbols_overview``, ``find_symbol``, ``open_file``) before asserting
on references — otherwise the bug would be masked by the side-effectful
indexing of those calls.
"""
@pytest.mark.parametrize("language_server", [Language.CLOJURE], indirect=True)
def test_request_references_includes_unopened_file(self, language_server: SolidLanguageServer) -> None:
# locate the definition of `multiply` in core.clj without hardcoding coords
core_content = read_repo_file(language_server, CORE_PATH)
coords = find_text_coordinates(core_content, r"\(defn (multiply)\b", require_unique=True)
assert coords is not None, "Could not locate the 'multiply' definition in core.clj"
# request references straight away — nothing has caused extra.clj to be opened in the LSP
refs = language_server.request_references(CORE_PATH, coords.line, coords.col)
ref_paths = {r.get("relativePath", "") for r in refs}
# extra.clj contains two real call sites (in double-product and triple-product);
# they must be returned regardless of whether the file was opened beforehand
extra_refs = [r for r in refs if r.get("relativePath", "").endswith("extra.clj")]
assert extra_refs, (
"Expected references to 'multiply' to include call sites from extra.clj, "
f"but got files: {sorted(ref_paths)}. "
"This indicates clojure-lsp is only indexing files that have been opened "
"during the session, so cross-file references are silently incomplete."
)
assert len(extra_refs) >= 2, (
f"Expected at least 2 references in extra.clj (double-product and triple-product), got {len(extra_refs)}: {extra_refs}"
)
@pytest.mark.parametrize("language_server", [Language.CLOJURE], indirect=True)
def test_request_references_includes_unopened_sibling_module_file(self, language_server: SolidLanguageServer) -> None:
"""Mirrors the real-world penpot bug repro: ``multiply`` is defined in one
module (root ``src/``) and consumed from a sibling module that has its
own ``deps.edn`` (``sub_module/``). With clojure-lsp running at the
repository root, references to ``multiply`` must include the sibling
module's call sites — even when no prior tool call has opened those
files in the LSP.
"""
core_content = read_repo_file(language_server, CORE_PATH)
coords = find_text_coordinates(core_content, r"\(defn (multiply)\b", require_unique=True)
assert coords is not None, "Could not locate the 'multiply' definition in core.clj"
refs = language_server.request_references(CORE_PATH, coords.line, coords.col)
ref_paths = {r.get("relativePath", "") for r in refs}
consumer_refs = [
r for r in refs if r.get("relativePath", "").replace("\\", "/").endswith("sub_module/src/sub_module_app/consumer.clj")
]
assert consumer_refs, (
"Expected references to 'multiply' to include call sites from the sibling module "
"(sub_module/src/sub_module_app/consumer.clj), but got files: "
f"{sorted(ref_paths)}. This mirrors the penpot bug: clojure-lsp does not appear to "
"index files in sibling modules until they are explicitly opened via find_symbol / "
"get_symbols_overview, so reference search returns silently incomplete results."
)
@pytest.mark.parametrize("language_server", [Language.CLOJURE], indirect=True)
def test_request_referencing_symbols_includes_unopened_file(self, language_server: SolidLanguageServer) -> None:
core_content = read_repo_file(language_server, CORE_PATH)
coords = find_text_coordinates(core_content, r"\(defn (multiply)\b", require_unique=True)
assert coords is not None, "Could not locate the 'multiply' definition in core.clj"
# request_referencing_symbols is what the user-facing find_referencing_symbols tool calls into
refs = language_server.request_referencing_symbols(CORE_PATH, coords.line, coords.col)
referencing_names = {ref.symbol.get("name", "") for ref in refs if hasattr(ref, "symbol")}
# double-product and triple-product live in extra.clj and both call multiply
assert "double-product" in referencing_names or "triple-product" in referencing_names, (
"Expected referencing symbols to include functions from extra.clj (double-product / triple-product), "
f"but got: {sorted(referencing_names)}. "
"extra.clj appears not to have been indexed by clojure-lsp because no prior tool call opened it."
)