1use super::{FeatureCategory, FeatureTest};
16
17pub const TESTS: &[FeatureTest] = &[
18 FeatureTest {
20 name: "where_clause_basic",
21 covers: &["where_clause"],
22 code: r#"
23function test() {
24 let data = [1, 2, 3, 4, 5];
25 let filtered = data.filter(x => x > 2);
26 return filtered;
27}
28"#,
29 function: "test",
30 category: FeatureCategory::Collection,
31 requires_data: false,
32 },
33 FeatureTest {
34 name: "where_clause_complex",
35 covers: &["where_clause", "and_expr", "comparison_expr"],
36 code: r#"
37function test() {
38 let items = [{ v: 1 }, { v: 5 }, { v: 10 }];
39 let filtered = items.filter(x => x.v > 2 && x.v < 8);
40 return filtered[0].v;
41}
42"#,
43 function: "test",
44 category: FeatureCategory::Collection,
45 requires_data: false,
46 },
47 FeatureTest {
49 name: "group_by_clause_basic",
50 covers: &["group_by_clause", "group_by_list", "group_by_expr"],
51 code: r#"
52function test() {
53 let items = [
54 { category: "a", value: 1 },
55 { category: "a", value: 2 },
56 { category: "b", value: 3 }
57 ];
58 let grouped = items.group(x => x.category);
59 return true;
60}
61"#,
62 function: "test",
63 category: FeatureCategory::Collection,
64 requires_data: false,
65 },
66 FeatureTest {
68 name: "having_clause_basic",
69 covers: &["having_clause"],
70 code: r#"
71function test() {
72 let counts = [{ name: "a", count: 5 }, { name: "b", count: 15 }];
73 let filtered = counts.filter(x => x.count > 10);
74 return filtered[0].name;
75}
76"#,
77 function: "test",
78 category: FeatureCategory::Collection,
79 requires_data: false,
80 },
81 FeatureTest {
83 name: "order_by_clause_asc",
84 covers: &[
85 "order_by_clause",
86 "order_by_list",
87 "order_by_item",
88 "sort_direction",
89 ],
90 code: r#"
91function test() {
92 let items = [3, 1, 4, 1, 5];
93 let sorted = items.sort((a, b) => a - b);
94 return sorted[0];
95}
96"#,
97 function: "test",
98 category: FeatureCategory::Collection,
99 requires_data: false,
100 },
101 FeatureTest {
102 name: "order_by_clause_desc",
103 covers: &["order_by_clause", "sort_direction"],
104 code: r#"
105function test() {
106 let items = [3, 1, 4, 1, 5];
107 let sorted = items.sort((a, b) => b - a);
108 return sorted[0];
109}
110"#,
111 function: "test",
112 category: FeatureCategory::Collection,
113 requires_data: false,
114 },
115 FeatureTest {
117 name: "limit_clause_basic",
118 covers: &["limit_clause"],
119 code: r#"
120function test() {
121 let items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
122 let limited = items[0:5];
123 return length(limited);
124}
125"#,
126 function: "test",
127 category: FeatureCategory::Collection,
128 requires_data: false,
129 },
130 FeatureTest {
132 name: "join_clause_basic",
133 covers: &["join_clause", "join_type", "join_source", "join_condition"],
134 code: r#"
135function test() {
136 let left = [{ id: 1, name: "a" }, { id: 2, name: "b" }];
137 let right = [{ id: 1, value: 100 }, { id: 2, value: 200 }];
138 let joined = [
139 for l in left {
140 for r in right {
141 if l.id == r.id { { id: l.id, name: l.name, value: r.value } }
142 }
143 }
144 ];
145 return true;
146}
147"#,
148 function: "test",
149 category: FeatureCategory::Collection,
150 requires_data: false,
151 },
152 FeatureTest {
154 name: "on_clause_timeframe",
155 covers: &["on_clause", "timeframe_expr", "timeframe"],
156 code: r#"
157function test() {
158 let result = on(1h) { 2 + 2 };
159 return result;
160}
161"#,
162 function: "test",
163 category: FeatureCategory::Domain,
164 requires_data: false,
165 },
166 FeatureTest {
167 name: "on_clause_nested",
168 covers: &["on_clause", "timeframe_expr"],
169 code: r#"
170function test() {
171 let outer = on(1d) {
172 let inner = on(1h) { 3 };
173 inner * 2
174 };
175 return outer;
176}
177"#,
178 function: "test",
179 category: FeatureCategory::Domain,
180 requires_data: false,
181 },
182 FeatureTest {
184 name: "pipe_expr_basic",
185 covers: &["pipe_expr"],
186 code: r#"
187function double(x) { return x * 2; }
188function add_one(x) { return x + 1; }
189
190function test() {
191 let result = 5 |> double |> add_one;
192 return result;
193}
194"#,
195 function: "test",
196 category: FeatureCategory::Operator,
197 requires_data: false,
198 },
199 FeatureTest {
200 name: "pipe_expr_chain",
201 covers: &["pipe_expr"],
202 code: r#"
203function square(x) { return x * x; }
204function negate(x) { return -x; }
205function abs_val(x) { return if x < 0 then -x else x; }
206
207function test() {
208 let result = 3 |> square |> negate |> abs_val;
209 return result;
210}
211"#,
212 function: "test",
213 category: FeatureCategory::Operator,
214 requires_data: false,
215 },
216 FeatureTest {
217 name: "pipe_expr_with_lambda",
218 covers: &["pipe_expr", "arrow_function"],
219 code: r#"
220function test() {
221 let data = [1, 2, 3, 4, 5];
222 let result = data
223 |> (arr => arr.filter(x => x > 2))
224 |> (arr => arr.map(x => x * 2));
225 return result[0];
226}
227"#,
228 function: "test",
229 category: FeatureCategory::Operator,
230 requires_data: false,
231 },
232 FeatureTest {
234 name: "named_arg_basic",
235 covers: &["named_arg", "arg_list", "argument"],
236 code: r#"
237function greet(name, greeting) {
238 return greeting;
239}
240
241function test() {
242 return greet(name: "World", greeting: "Hello");
243}
244"#,
245 function: "test",
246 category: FeatureCategory::Function,
247 requires_data: false,
248 },
249 FeatureTest {
250 name: "named_arg_mixed",
251 covers: &["named_arg", "arg_list"],
252 code: r#"
253function calc(a, b, c) {
254 return a + b + c;
255}
256
257function test() {
258 return calc(1, c: 3, b: 2);
259}
260"#,
261 function: "test",
262 category: FeatureCategory::Function,
263 requires_data: false,
264 },
265 FeatureTest {
266 name: "named_arg_with_defaults",
267 covers: &["named_arg", "function_param"],
268 code: r#"
269function make_config(width = 100, height = 50) {
270 return width * height;
271}
272
273function test() {
274 return make_config(width: 200);
275}
276"#,
277 function: "test",
278 category: FeatureCategory::Function,
279 requires_data: false,
280 },
281 FeatureTest {
283 name: "try_operator_basic",
284 covers: &["try_operator", "postfix_expr"],
285 code: r#"
286function may_fail(x) {
287 if x < 0 {
288 return { error: "negative value" };
289 }
290 return { value: x * 2 };
291}
292
293function test() {
294 let result = may_fail(5);
295 return result.value;
296}
297"#,
298 function: "test",
299 category: FeatureCategory::Exception,
300 requires_data: false,
301 },
302 FeatureTest {
303 name: "try_operator_chain",
304 covers: &["try_operator"],
305 code: r#"
306function step1(x) { return x + 1; }
307function step2(x) { return x * 2; }
308
309function test() {
310 let a = step1(5);
311 let b = step2(a);
312 return b;
313}
314"#,
315 function: "test",
316 category: FeatureCategory::Exception,
317 requires_data: false,
318 },
319 ];
321
322#[cfg(test)]
323mod tests {
324 use super::*;
325
326 #[test]
327 fn test_query_tests_defined() {
328 assert!(!TESTS.is_empty());
329 let has_collection = TESTS
331 .iter()
332 .any(|t| t.category == FeatureCategory::Collection);
333 let has_domain = TESTS.iter().any(|t| t.category == FeatureCategory::Domain);
334 let has_operator = TESTS
335 .iter()
336 .any(|t| t.category == FeatureCategory::Operator);
337 let has_function = TESTS
338 .iter()
339 .any(|t| t.category == FeatureCategory::Function);
340 let has_exception = TESTS
341 .iter()
342 .any(|t| t.category == FeatureCategory::Exception);
343
344 assert!(has_collection, "Should have Collection tests");
345 assert!(has_domain, "Should have Domain tests");
346 assert!(has_operator, "Should have Operator tests");
347 assert!(has_function, "Should have Function tests");
348 assert!(has_exception, "Should have Exception tests");
349 }
350}