133 lines
4.4 KiB
Python
133 lines
4.4 KiB
Python
|
|
import json
|
||
|
|
|
||
|
|
from ilsp.bicep_lsp.local_features import (
|
||
|
|
compute_folding_ranges,
|
||
|
|
compute_signature_help,
|
||
|
|
compute_workspace_symbols,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
# ── signatureHelp ────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def test_signature_help_simple_call():
|
||
|
|
lines = ["var id = resourceId('Microsoft.Storage/storageAccounts', "]
|
||
|
|
result = compute_signature_help(lines, 0, len(lines[0]))
|
||
|
|
assert result is not None
|
||
|
|
sig = result["signatures"][0]
|
||
|
|
assert sig["label"].startswith("resourceId(")
|
||
|
|
assert result["activeParameter"] == 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_signature_help_first_arg():
|
||
|
|
lines = ["var g = guid("]
|
||
|
|
result = compute_signature_help(lines, 0, len(lines[0]))
|
||
|
|
assert result is not None
|
||
|
|
assert result["activeParameter"] == 0
|
||
|
|
assert result["signatures"][0]["label"].startswith("guid(")
|
||
|
|
|
||
|
|
|
||
|
|
def test_signature_help_unknown_function_returns_none():
|
||
|
|
lines = ["var x = notARealFunction("]
|
||
|
|
result = compute_signature_help(lines, 0, len(lines[0]))
|
||
|
|
assert result is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_signature_help_outside_call_returns_none():
|
||
|
|
lines = ["var x = 'hello world'"]
|
||
|
|
result = compute_signature_help(lines, 0, len(lines[0]))
|
||
|
|
assert result is None
|
||
|
|
|
||
|
|
|
||
|
|
def test_signature_help_nested_call_uses_innermost():
|
||
|
|
lines = ["var x = concat(toLower("]
|
||
|
|
result = compute_signature_help(lines, 0, len(lines[0]))
|
||
|
|
assert result is not None
|
||
|
|
assert result["signatures"][0]["label"].startswith("toLower(")
|
||
|
|
|
||
|
|
|
||
|
|
# ── foldingRange ─────────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def test_folding_range_multiline_object():
|
||
|
|
lines = [
|
||
|
|
"resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {",
|
||
|
|
" name: 'demo'",
|
||
|
|
" sku: {",
|
||
|
|
" name: 'Standard_LRS'",
|
||
|
|
" }",
|
||
|
|
"}",
|
||
|
|
]
|
||
|
|
ranges = compute_folding_ranges(lines)
|
||
|
|
assert {"startLine": 0, "endLine": 5, "kind": "region"} in ranges
|
||
|
|
assert {"startLine": 2, "endLine": 4, "kind": "region"} in ranges
|
||
|
|
|
||
|
|
|
||
|
|
def test_folding_range_ignores_single_line_brackets():
|
||
|
|
lines = ["var x = { a: 1 }"]
|
||
|
|
ranges = compute_folding_ranges(lines)
|
||
|
|
assert ranges == []
|
||
|
|
|
||
|
|
|
||
|
|
def test_folding_range_comment_block():
|
||
|
|
lines = [
|
||
|
|
"// line one",
|
||
|
|
"// line two",
|
||
|
|
"// line three",
|
||
|
|
"var x = 1",
|
||
|
|
]
|
||
|
|
ranges = compute_folding_ranges(lines)
|
||
|
|
assert {"startLine": 0, "endLine": 2, "kind": "comment"} in ranges
|
||
|
|
|
||
|
|
|
||
|
|
def test_folding_range_short_comment_block_not_folded():
|
||
|
|
lines = ["// only one line", "var x = 1"]
|
||
|
|
ranges = compute_folding_ranges(lines)
|
||
|
|
assert not any(r["kind"] == "comment" for r in ranges)
|
||
|
|
|
||
|
|
|
||
|
|
# ── workspace/symbol ─────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
def test_workspace_symbol_finds_declarations():
|
||
|
|
docs = {
|
||
|
|
"file:///a.bicep": [
|
||
|
|
"param location string = 'westeurope'",
|
||
|
|
"var storageName = 'demo'",
|
||
|
|
"resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {",
|
||
|
|
" name: storageName",
|
||
|
|
"}",
|
||
|
|
"module roleAssignment 'br/modules:modules/roleassignments:2.0.x' = {",
|
||
|
|
" name: 'ra'",
|
||
|
|
"}",
|
||
|
|
],
|
||
|
|
}
|
||
|
|
results = compute_workspace_symbols(docs, "")
|
||
|
|
names = {r["name"] for r in results}
|
||
|
|
assert names == {"location", "storageName", "sa", "roleAssignment"}
|
||
|
|
|
||
|
|
|
||
|
|
def test_workspace_symbol_filters_by_query():
|
||
|
|
docs = {
|
||
|
|
"file:///a.bicep": [
|
||
|
|
"var storageName = 'demo'",
|
||
|
|
"var otherThing = 'x'",
|
||
|
|
],
|
||
|
|
}
|
||
|
|
results = compute_workspace_symbols(docs, "storage")
|
||
|
|
assert len(results) == 1
|
||
|
|
assert results[0]["name"] == "storageName"
|
||
|
|
|
||
|
|
|
||
|
|
def test_workspace_symbol_query_is_case_insensitive():
|
||
|
|
docs = {"file:///a.bicep": ["var StorageName = 'demo'"]}
|
||
|
|
results = compute_workspace_symbols(docs, "storagename")
|
||
|
|
assert len(results) == 1
|
||
|
|
|
||
|
|
|
||
|
|
def test_workspace_symbol_searches_across_multiple_documents():
|
||
|
|
docs = {
|
||
|
|
"file:///a.bicep": ["var fromA = 1"],
|
||
|
|
"file:///b.bicep": ["var fromB = 2"],
|
||
|
|
}
|
||
|
|
results = compute_workspace_symbols(docs, "")
|
||
|
|
names = {r["name"] for r in results}
|
||
|
|
assert names == {"fromA", "fromB"}
|