test(lsp): cover documented completions
Add protocol and helper coverage for documented hemplate completion items, including data-hemx-root. req: diagnostics/006
This commit is contained in:
@@ -394,6 +394,11 @@ fn hemplate_completion_items(
|
|||||||
"{+= trusted_html =+}",
|
"{+= trusted_html =+}",
|
||||||
"Trusted/rendered HTML expression; prefer escaped `{+ expr +}` for user content.",
|
"Trusted/rendered HTML expression; prefer escaped `{+ expr +}` for user content.",
|
||||||
),
|
),
|
||||||
|
completion_item(
|
||||||
|
"data-hemx-root",
|
||||||
|
"data-hemx-root=\"app\"",
|
||||||
|
"Generated hemx root for delegated runtime behavior.",
|
||||||
|
),
|
||||||
completion_item(
|
completion_item(
|
||||||
"data-hemx-slot",
|
"data-hemx-slot",
|
||||||
"data-hemx-slot=\"content\"",
|
"data-hemx-slot=\"content\"",
|
||||||
@@ -746,6 +751,81 @@ mod tests {
|
|||||||
assert!(!outside_hover.to_string().contains("exercise.name: String"));
|
assert!(!outside_hover.to_string().contains("exercise.name: String"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn completion_items_cover_documented_hemplate_surface() {
|
||||||
|
// req: diagnostics/006
|
||||||
|
let text = r#"<main data-hemx-root="app"><template h-for="item in &self.items" h-key="item.id"><p +class="self.class_name">{+ self.title +}{+= trusted =+}</p></template></main>"#;
|
||||||
|
let items = hemplate_completion_items("file:///tmp/app.heml", text, Some((0, 6)));
|
||||||
|
let labels = items
|
||||||
|
.iter()
|
||||||
|
.filter_map(|item| item["label"].as_str())
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
for label in [
|
||||||
|
"h-for",
|
||||||
|
"h-key",
|
||||||
|
"h-if",
|
||||||
|
"h-match",
|
||||||
|
"h-case",
|
||||||
|
"+attr",
|
||||||
|
"{+ expr +}",
|
||||||
|
"{+= expr =+}",
|
||||||
|
"data-hemx-root",
|
||||||
|
"data-hemx-slot",
|
||||||
|
"data-hemx-form",
|
||||||
|
"data-hemx-handle",
|
||||||
|
] {
|
||||||
|
assert!(labels.contains(label), "missing completion item `{label}`");
|
||||||
|
}
|
||||||
|
assert!(items.iter().all(|item| item["documentation"]["value"]
|
||||||
|
.as_str()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.contains("docs/hemplate-syntax.md")));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lsp_completion_returns_documented_items() {
|
||||||
|
// req: diagnostics/006
|
||||||
|
let text = r#"<main data-hemx-root="todos"><div data-hemx-slot="content">{+ self.title +}</div></main>"#;
|
||||||
|
let uri = "file:///tmp/completion.heml";
|
||||||
|
let input = [
|
||||||
|
lsp_message(serde_json::json!({"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}})),
|
||||||
|
lsp_message(serde_json::json!({
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "textDocument/didOpen",
|
||||||
|
"params": {"textDocument": {"uri": uri, "languageId": "heml", "version": 1, "text": text}}
|
||||||
|
})),
|
||||||
|
lsp_message(serde_json::json!({
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": 2,
|
||||||
|
"method": "textDocument/completion",
|
||||||
|
"params": {"textDocument": {"uri": uri}, "position": {"line": 0, "character": 6}}
|
||||||
|
})),
|
||||||
|
lsp_message(serde_json::json!({"jsonrpc": "2.0", "method": "exit"})),
|
||||||
|
]
|
||||||
|
.join("");
|
||||||
|
let mut reader = std::io::BufReader::new(input.as_bytes());
|
||||||
|
let mut output = Vec::new();
|
||||||
|
|
||||||
|
serve_lsp(&mut reader, &mut output).expect("serve LSP");
|
||||||
|
let messages = lsp_messages(&output);
|
||||||
|
let completion = messages
|
||||||
|
.iter()
|
||||||
|
.find(|message| message["id"] == 2)
|
||||||
|
.expect("completion response");
|
||||||
|
let completion_items = completion["result"]
|
||||||
|
.as_array()
|
||||||
|
.or_else(|| completion["result"]["items"].as_array())
|
||||||
|
.expect("completion items");
|
||||||
|
let labels = completion_items
|
||||||
|
.iter()
|
||||||
|
.filter_map(|item| item["label"].as_str())
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert!(labels.contains("h-if"));
|
||||||
|
assert!(labels.contains("data-hemx-root"));
|
||||||
|
assert!(labels.contains("data-hemx-slot"));
|
||||||
|
assert!(labels.contains("{+ expr +}"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn workout_template_fields_are_available_from_repo_facts() {
|
fn workout_template_fields_are_available_from_repo_facts() {
|
||||||
// req: diagnostics/006
|
// req: diagnostics/006
|
||||||
|
|||||||
Reference in New Issue
Block a user