Feature: LSP language discovery coverage Exercise uncovered lines in src/cleveragents/lsp/discovery.py covering shebang detection, cache behaviour, directory scanning, special-name detection, UKO layer, and server matching. # ------------------------------------------------------------------ # Layer 2 – shebang detection edge cases (lines 142, 146, 157) # ------------------------------------------------------------------ Scenario: Shebang returns None for non-shebang line Given ldcov a first line "echo hello" When ldcov I detect from shebang Then ldcov the shebang result is None Scenario: Shebang returns None for bare hashbang Given ldcov a first line "#!" When ldcov I detect from shebang Then ldcov the shebang result is None Scenario: Shebang returns None for empty hashbang with whitespace Given ldcov a first line "#! " When ldcov I detect from shebang Then ldcov the shebang result is None Scenario: Shebang returns None for unknown interpreter Given ldcov a first line "#!/usr/bin/unknownlang" When ldcov I detect from shebang Then ldcov the shebang result is None # ------------------------------------------------------------------ # Cache hit (line 201) # ------------------------------------------------------------------ Scenario: detect_file_language returns cached result on second call Given ldcov a LanguageDiscovery instance And ldcov the cache already contains "/tmp/cached.py" mapped to "python" When ldcov I detect file language for "/tmp/cached.py" Then ldcov the detected language is "python" # ------------------------------------------------------------------ # invalidate_all (line 246) # ------------------------------------------------------------------ Scenario: invalidate_all clears the entire cache Given ldcov a LanguageDiscovery instance And ldcov the cache already contains "/a.py" mapped to "python" And ldcov the cache already contains "/b.rs" mapped to "rust" When ldcov I call invalidate_all Then ldcov the cache is empty # ------------------------------------------------------------------ # Special basenames – Makefile (line 257), CMakeLists.txt (line 259) # ------------------------------------------------------------------ Scenario: Makefile is detected as makefile language Given ldcov a LanguageDiscovery instance When ldcov I detect uncached language for "project/Makefile" Then ldcov the detected language is "makefile" Scenario: CMakeLists.txt is detected as cmake language Given ldcov a LanguageDiscovery instance When ldcov I detect uncached language for "project/CMakeLists.txt" Then ldcov the detected language is "cmake" # ------------------------------------------------------------------ # Layer 3 – UKO classification (line 276) # ------------------------------------------------------------------ Scenario: UKO classification is used when extension and shebang miss Given ldcov a LanguageDiscovery instance with UKO mapping "/data/blob" to "python" When ldcov I detect uncached language for "/data/blob" Then ldcov the detected language is "python" # ------------------------------------------------------------------ # Directory scanning (lines 219-231, 234) # ------------------------------------------------------------------ Scenario: detect_directory_languages finds languages in a tree Given ldcov a LanguageDiscovery instance And ldcov a mock directory tree with files "app.py,lib.rs,readme.txt" When ldcov I detect directory languages Then ldcov the directory languages include "python" And ldcov the directory languages include "rust" Scenario: detect_directory_languages handles OSError gracefully Given ldcov a LanguageDiscovery instance And ldcov os.walk will raise an OSError When ldcov I detect directory languages for "/nonexistent" Then ldcov the directory languages result is an empty list # ------------------------------------------------------------------ # get_servers_for_language (lines 298-301) # ------------------------------------------------------------------ Scenario: get_servers_for_language filters matching configs Given ldcov a LanguageDiscovery instance And ldcov server configs with languages "python,rust" and "javascript" When ldcov I get servers for language "python" Then ldcov the matched server count is 1 Scenario: get_servers_for_language returns empty for no match Given ldcov a LanguageDiscovery instance And ldcov server configs with languages "python,rust" and "javascript" When ldcov I get servers for language "haskell" Then ldcov the matched server count is 0