styx_lsp_test_schema/
lib.rs

1#![doc = include_str!("../README.md")]
2//! Schema types for LSP extension test files.
3//!
4//! These types define the structure of `.styx` test files that exercise
5//! LSP extensions through real IPC (roam over stdio).
6//!
7//! # Example Test File
8//!
9//! ```styx
10//! tests [
11//!     @test {
12//!         name "column completions are context-aware"
13//!         input <<STYX
14//!             @schema {id crate:dibs-queries@1}
15//!             AllProducts @query {
16//!                 from product
17//!                 select {h|}
18//!             }
19//!         STYX
20//!         completions {
21//!             has (handle id status)
22//!             not_has (locale currency)
23//!         }
24//!     }
25//! ]
26//! ```
27
28use facet::Facet;
29
30/// A test file containing one or more test cases.
31#[derive(Debug, Clone, Facet)]
32pub struct TestFile {
33    /// Test cases in this file.
34    pub tests: Vec<TestCase>,
35}
36
37/// A single test case.
38#[derive(Debug, Clone, Facet)]
39pub struct TestCase {
40    /// Name of the test (for reporting).
41    pub name: String,
42
43    /// The input document. Use `|` to mark cursor position.
44    pub input: String,
45
46    /// Optional schema to use (if not embedded in input).
47    #[facet(default)]
48    pub schema: Option<String>,
49
50    /// Expected completions at cursor position.
51    #[facet(default)]
52    pub completions: Option<CompletionExpectations>,
53
54    /// Expected hover result at cursor position.
55    #[facet(default)]
56    pub hover: Option<HoverExpectations>,
57
58    /// Expected diagnostics for the document.
59    #[facet(default)]
60    pub diagnostics: Option<DiagnosticExpectations>,
61
62    /// Expected inlay hints for the document.
63    #[facet(default)]
64    pub inlay_hints: Option<InlayHintExpectations>,
65
66    /// Expected definition locations at cursor position.
67    #[facet(default)]
68    pub definition: Option<DefinitionExpectations>,
69}
70
71/// Expectations for completion results.
72#[derive(Debug, Clone, Facet)]
73pub struct CompletionExpectations {
74    /// Labels that must be present.
75    #[facet(default)]
76    pub has: Vec<String>,
77
78    /// Labels that must NOT be present.
79    #[facet(default)]
80    pub not_has: Vec<String>,
81
82    /// Detailed expectations for specific items.
83    #[facet(default)]
84    pub items: Vec<CompletionItemExpectation>,
85}
86
87/// Detailed expectation for a single completion item.
88#[derive(Debug, Clone, Facet)]
89pub struct CompletionItemExpectation {
90    /// The label to match.
91    pub label: String,
92
93    /// Expected detail text.
94    #[facet(default)]
95    pub detail: Option<String>,
96
97    /// Expected documentation (substring match).
98    #[facet(default)]
99    pub documentation: Option<String>,
100
101    /// Expected kind.
102    #[facet(default)]
103    pub kind: Option<String>,
104}
105
106/// Expectations for hover results.
107#[derive(Debug, Clone, Facet)]
108pub struct HoverExpectations {
109    /// Substrings that must be present in hover content.
110    #[facet(default)]
111    pub contains: Vec<String>,
112
113    /// Substrings that must NOT be present.
114    #[facet(default)]
115    pub not_contains: Vec<String>,
116}
117
118/// Expectations for diagnostics.
119#[derive(Debug, Clone, Facet)]
120pub struct DiagnosticExpectations {
121    /// Expected number of diagnostics (if specified).
122    #[facet(default)]
123    pub count: Option<u32>,
124
125    /// Diagnostics that must be present.
126    #[facet(default)]
127    pub has: Vec<DiagnosticExpectation>,
128
129    /// Message substrings that must NOT appear in any diagnostic.
130    #[facet(default)]
131    pub not_has: Vec<String>,
132}
133
134/// Expectation for a single diagnostic.
135#[derive(Debug, Clone, Facet)]
136pub struct DiagnosticExpectation {
137    /// Substring that must appear in the message.
138    pub message: String,
139
140    /// Expected severity (error, warning, info, hint).
141    #[facet(default)]
142    pub severity: Option<String>,
143
144    /// Expected line number (1-indexed for human readability).
145    #[facet(default)]
146    pub line: Option<u32>,
147}
148
149/// Expectations for inlay hints.
150#[derive(Debug, Clone, Facet)]
151pub struct InlayHintExpectations {
152    /// Expected number of hints (if specified).
153    #[facet(default)]
154    pub count: Option<u32>,
155
156    /// Hints that must be present.
157    #[facet(default)]
158    pub has: Vec<InlayHintExpectation>,
159}
160
161/// Expectation for a single inlay hint.
162#[derive(Debug, Clone, Facet)]
163pub struct InlayHintExpectation {
164    /// The hint label text.
165    pub label: String,
166
167    /// Expected line number (1-indexed).
168    #[facet(default)]
169    pub line: Option<u32>,
170}
171
172/// Expectations for definition results.
173#[derive(Debug, Clone, Facet)]
174pub struct DefinitionExpectations {
175    /// Expected number of locations (if specified).
176    #[facet(default)]
177    pub count: Option<u32>,
178
179    /// Whether we expect no results (empty).
180    #[facet(default)]
181    pub empty: bool,
182
183    /// Locations that must be present.
184    #[facet(default)]
185    pub has: Vec<DefinitionExpectation>,
186}
187
188/// Expectation for a single definition location.
189#[derive(Debug, Clone, Facet)]
190pub struct DefinitionExpectation {
191    /// Expected line number (1-indexed).
192    #[facet(default)]
193    pub line: Option<u32>,
194
195    /// Expected URI (substring match).
196    #[facet(default)]
197    pub uri: Option<String>,
198}