use super::*;
#[test]
fn source_diagnostics_surface_variant_recipe_option_universe() -> TestResult {
let source_uri = "file:///workspace-a/src/App.tsx";
let source_text = r#"import { cva } from "class-variance-authority";
const button = cva("btn", {
variants: {
intent: {
primary: "btn-primary",
secondary: "btn-secondary",
},
},
});
const view = button({ intent: "ghost" });
"#;
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": source_uri,
"languageId": "typescriptreact",
"version": 1,
"text": source_text,
},
},
}),
);
let diagnostics_response = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 2,
"method": SOURCE_DIAGNOSTICS_REQUEST,
"params": {
"textDocument": {
"uri": source_uri,
},
},
}),
);
let diagnostics = diagnostics_response
.as_ref()
.and_then(|value| value.pointer("/result"))
.and_then(Value::as_array)
.ok_or_else(|| std::io::Error::other("source diagnostics should return an array"))?;
let missing_option = diagnostics
.iter()
.find(|diagnostic| diagnostic.get("code") == Some(&json!("missingClassValueOption")))
.ok_or_else(|| std::io::Error::other("expected variant option diagnostic"))?;
assert!(
missing_option
.get("message")
.and_then(Value::as_str)
.is_some_and(|message| message.contains("ghost")),
"{missing_option:?}"
);
assert_eq!(
missing_option
.pointer("/data/provenance/0")
.and_then(Value::as_str),
Some("omena-bridge.class-value-universe-provider")
);
Ok(())
}
#[test]
fn source_diagnostics_surface_vanilla_recipe_option_universe() -> TestResult {
let source_uri = "file:///workspace-a/src/App.tsx";
let source_text = r#"import { recipe } from "@vanilla-extract/recipes";
const badge = recipe({
base: "badge",
variants: {
tone: {
info: "badge-info",
danger: "badge-danger",
},
},
});
const view = badge({ tone: "ghost" });
"#;
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": source_uri,
"languageId": "typescriptreact",
"version": 1,
"text": source_text,
},
},
}),
);
let diagnostics_response = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 2,
"method": SOURCE_DIAGNOSTICS_REQUEST,
"params": {
"textDocument": {
"uri": source_uri,
},
},
}),
);
let diagnostics = diagnostics_response
.as_ref()
.and_then(|value| value.pointer("/result"))
.and_then(Value::as_array)
.ok_or_else(|| std::io::Error::other("source diagnostics should return an array"))?;
let missing_option = diagnostics
.iter()
.find(|diagnostic| diagnostic.get("code") == Some(&json!("missingClassValueOption")))
.ok_or_else(|| std::io::Error::other("expected vanilla recipe option diagnostic"))?;
assert!(
missing_option
.get("message")
.and_then(Value::as_str)
.is_some_and(|message| message.contains("badge.tone")),
"{missing_option:?}"
);
assert_eq!(
missing_option
.pointer("/data/provenance/0")
.and_then(Value::as_str),
Some("omena-bridge.class-value-universe-provider")
);
Ok(())
}
#[test]
fn resolves_classnames_bind_dynamic_source_expressions() -> TestResult {
let source_text = r#"import bind from "classnames/bind";
import styles from "./styles.module.scss";
const cx = bind.bind(styles);
const tone = "item--primary";
const icon = { glyph: "item__icon" };
const prefix = "item--";
export const view = <div className={cx(tone, icon.glyph, `item--${variant}`, { "item--danger": danger, item__label: true }, ok && "item--ok", active ? "item--on" : "item--off", prefix + state)} />;
"#;
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/App.tsx",
"languageId": "typescriptreact",
"version": 1,
"text": source_text,
},
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/styles.module.scss",
"languageId": "scss",
"version": 1,
"text": ".item--primary {}\n.item__icon {}\n.item--large {}\n.item--danger {}\n.item__label {}\n.item--ok {}\n.item--on {}\n.item--off {}\n.item--muted {}\n",
},
},
}),
);
let tone_position = parser_position_for_byte_offset(
source_text,
fixture_find(
source_text,
"tone,",
"source fixture contains tone reference",
)?,
);
let tone_definition = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 2,
"method": "textDocument/definition",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/App.tsx",
},
"position": tone_position,
},
}),
);
assert_eq!(
tone_definition
.as_ref()
.and_then(|value| value.pointer("/result/0/range")),
Some(&json!({
"start": {
"line": 0,
"character": 1,
},
"end": {
"line": 0,
"character": 14,
},
})),
);
let icon_position = parser_position_for_byte_offset(
source_text,
fixture_find(
source_text,
"icon.glyph",
"source fixture contains object property reference",
)?,
);
let icon_definition = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 3,
"method": "textDocument/definition",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/App.tsx",
},
"position": icon_position,
},
}),
);
assert_eq!(
icon_definition
.as_ref()
.and_then(|value| value.pointer("/result/0/range")),
Some(&json!({
"start": {
"line": 1,
"character": 1,
},
"end": {
"line": 1,
"character": 11,
},
})),
);
let template_position = parser_position_for_byte_offset(
source_text,
fixture_find(
source_text,
"`item--",
"source fixture contains template prefix reference",
)? + 1,
);
let template_definition = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 4,
"method": "textDocument/definition",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/App.tsx",
},
"position": template_position,
},
}),
);
let template_targets = template_definition
.as_ref()
.and_then(|value| value.pointer("/result"))
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
assert!(
template_targets
.iter()
.any(|target| target.pointer("/range/start/line") == Some(&json!(2)))
);
assert!(
!template_targets
.iter()
.any(|target| target.pointer("/range/start/line") == Some(&json!(1)))
);
let object_key_position = parser_position_for_byte_offset(
source_text,
fixture_find(
source_text,
"item__label",
"source fixture contains object key reference",
)?,
);
let object_key_definition = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 5,
"method": "textDocument/definition",
"params": {
"textDocument": {
"uri": "file:///workspace-a/src/App.tsx",
},
"position": object_key_position,
},
}),
);
assert_eq!(
object_key_definition
.as_ref()
.and_then(|value| value.pointer("/result/0/range/start/line")),
Some(&json!(4)),
);
Ok(())
}
#[test]
fn source_diagnostics_surface_target_scoped_dynamic_m_tier_flow() -> TestResult {
let source_uri = "file:///workspace-a/src/App.tsx";
let module_a_uri = "file:///workspace-a/src/A.module.scss";
let module_b_uri = "file:///workspace-a/src/B.module.scss";
let source_text = r#"import bind from "classnames/bind";
import a from "./A.module.scss";
import b from "./B.module.scss";
const cx = bind.bind(b);
export function App({ variant }) {
return <div className={cx(`card-${variant}`, `btn-${variant}`)} />;
}"#;
let mut state = LspShellState::default();
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"workspaceFolders": [
{
"uri": "file:///workspace-a",
"name": "workspace-a",
},
],
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": module_a_uri,
"languageId": "scss",
"version": 1,
"text": ".btn-primary {}\n",
},
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": module_b_uri,
"languageId": "scss",
"version": 1,
"text": ".card-primary {}\n",
},
},
}),
);
handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"method": "textDocument/didOpen",
"params": {
"textDocument": {
"uri": source_uri,
"languageId": "typescriptreact",
"version": 1,
"text": source_text,
},
},
}),
);
let diagnostics_response = handle_lsp_message(
&mut state,
json!({
"jsonrpc": "2.0",
"id": 2,
"method": SOURCE_DIAGNOSTICS_REQUEST,
"params": {
"textDocument": {
"uri": source_uri,
},
},
}),
);
let diagnostics = diagnostics_response
.as_ref()
.and_then(|value| value.pointer("/result"))
.and_then(Value::as_array)
.ok_or_else(|| std::io::Error::other("source diagnostics should return an array"))?;
let unknown_dynamic = diagnostics
.iter()
.filter(|diagnostic| diagnostic.get("code") == Some(&json!("noUnknownDynamicClass")))
.collect::<Vec<_>>();
assert_eq!(
unknown_dynamic.len(),
1,
"LSP source diagnostics must surface exactly the bound-module dynamic M-tier finding"
);
assert_eq!(
unknown_dynamic[0]
.pointer("/data/provenance/1")
.and_then(Value::as_str),
Some("omena-abstract-value.k-limited-call-site-flow"),
"the LSP diagnostic must be backed by the query/checker k-CFA flow, not a local scan"
);
assert!(
diagnostics
.iter()
.all(|diagnostic| diagnostic.get("code") != Some(&json!("noImpreciseValue"))),
"harvested template diagnostics should not expose information-free noImpreciseValue noise"
);
let range_start = unknown_dynamic[0]
.pointer("/range/start")
.ok_or_else(|| std::io::Error::other("unknown dynamic diagnostic has a range"))?;
assert_eq!(
range_start.get("line"),
Some(&json!(5)),
"the dynamic finding must anchor to the unmatched btn- template"
);
Ok(())
}