1use super::{FeatureCategory, FeatureTest};
8
9pub const FEATURE_TESTS: &[FeatureTest] = &[
16 FeatureTest {
18 name: "number_literal",
19 covers: &["number", "integer", "literal"],
20 code: "function test() { return 42; }",
21 function: "test",
22 category: FeatureCategory::Literal,
23 requires_data: false,
24 },
25 FeatureTest {
26 name: "string_literal",
27 covers: &["string", "literal"],
28 code: r#"function test() { return "hello"; }"#,
29 function: "test",
30 category: FeatureCategory::Literal,
31 requires_data: false,
32 },
33 FeatureTest {
34 name: "boolean_literal",
35 covers: &["boolean", "literal"],
36 code: "function test() { return true; }",
37 function: "test",
38 category: FeatureCategory::Literal,
39 requires_data: false,
40 },
41 FeatureTest {
42 name: "null_literal",
43 covers: &["none_literal", "literal"],
44 code: "function test() { return null; }",
45 function: "test",
46 category: FeatureCategory::Literal,
47 requires_data: false,
48 },
49 FeatureTest {
50 name: "array_literal",
51 covers: &["array_literal", "array_elements", "array_element"],
52 code: "function test() { return [1, 2, 3]; }",
53 function: "test",
54 category: FeatureCategory::Literal,
55 requires_data: false,
56 },
57 FeatureTest {
58 name: "object_literal",
59 covers: &["object_literal", "object_fields", "object_field"],
60 code: "function test() { return { a: 1, b: 2 }; }",
61 function: "test",
62 category: FeatureCategory::Literal,
63 requires_data: false,
64 },
65 FeatureTest {
66 name: "color_literal",
67 covers: &["color", "literal"],
68 code: "function test() { return 'red'; }",
69 function: "test",
70 category: FeatureCategory::Literal,
71 requires_data: false,
72 },
73 FeatureTest {
74 name: "duration_literal",
75 covers: &["duration", "duration_unit", "simple_duration"],
76 code: "function test() { return 5m; }",
77 function: "test",
78 category: FeatureCategory::Literal,
79 requires_data: false,
80 },
81 FeatureTest {
82 name: "datetime_literal",
83 covers: &["datetime_literal", "datetime_expr"],
84 code: r#"function test() { return @"2020-01-01"; }"#,
85 function: "test",
86 category: FeatureCategory::Literal,
87 requires_data: false,
88 },
89 FeatureTest {
90 name: "time_ref",
91 covers: &["time_ref", "named_time"],
92 code: "function test() { return @today; }",
93 function: "test",
94 category: FeatureCategory::Literal,
95 requires_data: false,
96 },
97 FeatureTest {
99 name: "arithmetic_add_sub",
100 covers: &["additive_expr", "expression"],
101 code: "function test() { return 1 + 2 - 1; }",
102 function: "test",
103 category: FeatureCategory::Operator,
104 requires_data: false,
105 },
106 FeatureTest {
107 name: "arithmetic_mul_div_mod",
108 covers: &["multiplicative_expr"],
109 code: "function test() { return 2 * 3 / 2 % 2; }",
110 function: "test",
111 category: FeatureCategory::Operator,
112 requires_data: false,
113 },
114 FeatureTest {
115 name: "arithmetic_pow",
116 covers: &["exponential_expr"],
117 code: "function test() { return 2 ^ 3; }",
118 function: "test",
119 category: FeatureCategory::Operator,
120 requires_data: false,
121 },
122 FeatureTest {
123 name: "comparison_operators",
124 covers: &["comparison_expr", "comparison_op", "comparison_tail"],
125 code: "function test() { return (5 > 3) && (3 < 5) && (5 >= 5) && (3 <= 5); }",
126 function: "test",
127 category: FeatureCategory::Operator,
128 requires_data: false,
129 },
130 FeatureTest {
131 name: "equality_operators",
132 covers: &["comparison_op"],
133 code: "function test() { return (5 == 5) && (5 != 3); }",
134 function: "test",
135 category: FeatureCategory::Operator,
136 requires_data: false,
137 },
138 FeatureTest {
140 name: "fuzzy_equal_basic",
141 covers: &["fuzzy_comparison_tail", "fuzzy_op"],
142 code: "function test() { return 100 ~= 102; }", function: "test",
144 category: FeatureCategory::Operator,
145 requires_data: false,
146 },
147 FeatureTest {
148 name: "fuzzy_equal_with_absolute_tolerance",
149 covers: &[
150 "fuzzy_comparison_tail",
151 "fuzzy_op",
152 "within_clause",
153 "tolerance_spec",
154 ],
155 code: "function test() { return 100 ~= 105 within 10; }", function: "test",
157 category: FeatureCategory::Operator,
158 requires_data: false,
159 },
160 FeatureTest {
161 name: "fuzzy_equal_with_percentage_tolerance",
162 covers: &[
163 "fuzzy_comparison_tail",
164 "fuzzy_op",
165 "within_clause",
166 "tolerance_spec",
167 ],
168 code: "function test() { return 100 ~= 110 within 15%; }", function: "test",
170 category: FeatureCategory::Operator,
171 requires_data: false,
172 },
173 FeatureTest {
174 name: "fuzzy_greater",
175 covers: &["fuzzy_comparison_tail", "fuzzy_op"],
176 code: "function test() { return 100 ~> 98; }", function: "test",
178 category: FeatureCategory::Operator,
179 requires_data: false,
180 },
181 FeatureTest {
182 name: "fuzzy_less",
183 covers: &["fuzzy_comparison_tail", "fuzzy_op"],
184 code: "function test() { return 98 ~< 100; }", function: "test",
186 category: FeatureCategory::Operator,
187 requires_data: false,
188 },
189 FeatureTest {
190 name: "fuzzy_equal_false",
191 covers: &["fuzzy_comparison_tail", "fuzzy_op", "within_clause"],
192 code: "function test() { return 100 ~= 200 within 5; }", function: "test",
194 category: FeatureCategory::Operator,
195 requires_data: false,
196 },
197 FeatureTest {
198 name: "logical_and",
199 covers: &["and_expr"],
200 code: "function test() { return true && false; }",
201 function: "test",
202 category: FeatureCategory::Operator,
203 requires_data: false,
204 },
205 FeatureTest {
206 name: "logical_or",
207 covers: &["or_expr"],
208 code: "function test() { return true || false; }",
209 function: "test",
210 category: FeatureCategory::Operator,
211 requires_data: false,
212 },
213 FeatureTest {
214 name: "logical_not",
215 covers: &["unary_expr"],
216 code: "function test() { return !false; }",
217 function: "test",
218 category: FeatureCategory::Operator,
219 requires_data: false,
220 },
221 FeatureTest {
222 name: "unary_negation",
223 covers: &["unary_expr"],
224 code: "function test() { return -5; }",
225 function: "test",
226 category: FeatureCategory::Operator,
227 requires_data: false,
228 },
229 FeatureTest {
230 name: "ternary_op",
231 covers: &["ternary_expr", "ternary_branch"],
232 code: "function test() { return 1 > 0 ? 1 : 2; }",
233 function: "test",
234 category: FeatureCategory::Operator,
235 requires_data: false,
236 },
237 FeatureTest {
238 name: "null_coalesce",
239 covers: &["null_coalesce_expr"],
240 code: "function test() { let x = null; return x ?? 5; }",
241 function: "test",
242 category: FeatureCategory::Operator,
243 requires_data: false,
244 },
245 FeatureTest {
246 name: "range_expr",
247 covers: &["range_expr"],
248 code: "function test() { return 1:5; }",
249 function: "test",
250 category: FeatureCategory::Operator,
251 requires_data: false,
252 },
253 FeatureTest {
255 name: "if_expr",
256 covers: &["if_expr"],
257 code: "function test() { return if 1 > 0 then 1 else 2; }",
258 function: "test",
259 category: FeatureCategory::ControlFlow,
260 requires_data: false,
261 },
262 FeatureTest {
263 name: "if_stmt",
264 covers: &["if_stmt", "else_clause"],
265 code: "function test() { let x = 0; if (1 > 0) { x = 1; } else { x = 2; } return x; }",
266 function: "test",
267 category: FeatureCategory::ControlFlow,
268 requires_data: false,
269 },
270 FeatureTest {
271 name: "match_expr",
272 covers: &["match_expr", "match_arm", "pattern"],
273 code: "function test() { return match 2 { 1 => 10, 2 => 20, _ => 0 }; }",
274 function: "test",
275 category: FeatureCategory::ControlFlow,
276 requires_data: false,
277 },
278 FeatureTest {
279 name: "match_with_guard",
280 covers: &["match_expr", "match_arm"],
281 code: "function test() { return match 4 { x where x > 3 => x, _ => 0 }; }",
282 function: "test",
283 category: FeatureCategory::ControlFlow,
284 requires_data: false,
285 },
286 FeatureTest {
287 name: "match_array_pattern",
288 covers: &["pattern_array"],
289 code: "function test() { return match [1, 2] { [a, b] => a + b, _ => 0 }; }",
290 function: "test",
291 category: FeatureCategory::ControlFlow,
292 requires_data: false,
293 },
294 FeatureTest {
295 name: "match_object_pattern",
296 covers: &["pattern_object", "pattern_field"],
297 code: "function test() { return match { a: 1, b: 2 } { { a: x, b: y } => x + y, _ => 0 }; }",
298 function: "test",
299 category: FeatureCategory::ControlFlow,
300 requires_data: false,
301 },
302 FeatureTest {
303 name: "match_constructor",
304 covers: &["pattern_constructor"],
305 code: "function test() { return match { value: 3 } { Ok(x) => x, Err(e) => -1 }; }",
306 function: "test",
307 category: FeatureCategory::ControlFlow,
308 requires_data: false,
309 },
310 FeatureTest {
311 name: "for_loop",
312 covers: &["for_loop", "for_clause"],
313 code: "function test() { let sum = 0; for x in [1, 2, 3] { sum = sum + x; } return sum; }",
314 function: "test",
315 category: FeatureCategory::ControlFlow,
316 requires_data: false,
317 },
318 FeatureTest {
319 name: "for_expr",
320 covers: &["for_expr", "for_expr_clause"],
321 code: "function test() { return for x in [1, 2, 3] { x * 2 }; }",
322 function: "test",
323 category: FeatureCategory::ControlFlow,
324 requires_data: false,
325 },
326 FeatureTest {
327 name: "while_loop",
328 covers: &["while_loop"],
329 code: "function test() { let i = 0; while (i < 3) { i = i + 1; } return i; }",
330 function: "test",
331 category: FeatureCategory::ControlFlow,
332 requires_data: false,
333 },
334 FeatureTest {
335 name: "while_expr",
336 covers: &["while_expr"],
337 code: "function test() { let i = 0; return while i < 3 { i = i + 1; i }; }",
338 function: "test",
339 category: FeatureCategory::ControlFlow,
340 requires_data: false,
341 },
342 FeatureTest {
343 name: "loop_expr",
344 covers: &["loop_expr", "block_expr"],
345 code: "function test() { let i = 0; return loop { i = i + 1; if i == 3 then break i; i }; }",
346 function: "test",
347 category: FeatureCategory::ControlFlow,
348 requires_data: false,
349 },
350 FeatureTest {
351 name: "break_continue",
352 covers: &["break_stmt", "break_expr", "continue_stmt", "continue_expr"],
353 code: "function test() { let sum = 0; for x in [1, 2, 3, 4] { if x == 2 { continue; } if x == 4 { break; } sum = sum + x; } return sum; }",
354 function: "test",
355 category: FeatureCategory::ControlFlow,
356 requires_data: false,
357 },
358 FeatureTest {
359 name: "return_stmt",
360 covers: &["return_stmt", "return_expr"],
361 code: "function test() { return 42; }",
362 function: "test",
363 category: FeatureCategory::ControlFlow,
364 requires_data: false,
365 },
366 FeatureTest {
368 name: "variable_decl",
369 covers: &["variable_decl", "var_keyword"],
370 code: "function test() { let x = 5; return x; }",
371 function: "test",
372 category: FeatureCategory::Variable,
373 requires_data: false,
374 },
375 FeatureTest {
376 name: "const_var_decl",
377 covers: &["variable_decl", "var_keyword"],
378 code: "function test() { const a = 1; var b = 2; return a + b; }",
379 function: "test",
380 category: FeatureCategory::Variable,
381 requires_data: false,
382 },
383 FeatureTest {
384 name: "assignment",
385 covers: &["assignment", "assignment_expr"],
386 code: "function test() { let x = 1; x = 2; return x; }",
387 function: "test",
388 category: FeatureCategory::Variable,
389 requires_data: false,
390 },
391 FeatureTest {
392 name: "destructure_array",
393 covers: &["destructure_pattern", "destructure_array_pattern"],
394 code: "function test() { let [a, b] = [1, 2]; return a + b; }",
395 function: "test",
396 category: FeatureCategory::Variable,
397 requires_data: false,
398 },
399 FeatureTest {
400 name: "destructure_object",
401 covers: &[
402 "destructure_pattern",
403 "destructure_object_pattern",
404 "destructure_object_pattern_field",
405 ],
406 code: "function test() { let { a, b } = { a: 1, b: 2 }; return a + b; }",
407 function: "test",
408 category: FeatureCategory::Variable,
409 requires_data: false,
410 },
411 FeatureTest {
412 name: "destructure_rest",
413 covers: &["destructure_rest_pattern"],
414 code: "function test() { let { a, ...rest } = { a: 1, b: 2 }; return rest.b; }",
415 function: "test",
416 category: FeatureCategory::Variable,
417 requires_data: false,
418 },
419 FeatureTest {
420 name: "let_expr",
421 covers: &["let_expr"],
422 code: "function test() { return let x = 5 in x + 3; }",
423 function: "test",
424 category: FeatureCategory::Variable,
425 requires_data: false,
426 },
427 FeatureTest {
429 name: "function_def",
430 covers: &[
431 "function_def",
432 "function_params",
433 "function_param",
434 "function_body",
435 ],
436 code: "function add(a, b) { return a + b; } function test() { return add(1, 2); }",
437 function: "test",
438 category: FeatureCategory::Function,
439 requires_data: false,
440 },
441 FeatureTest {
442 name: "arrow_function",
443 covers: &["arrow_function"],
444 code: "function test() { let f = x => x + 1; return f(5); }",
445 function: "test",
446 category: FeatureCategory::Function,
447 requires_data: false,
448 },
449 FeatureTest {
450 name: "function_expr",
451 covers: &["function_expr"],
452 code: "function test() { let f = function(x) { return x + 1; }; return f(5); }",
453 function: "test",
454 category: FeatureCategory::Function,
455 requires_data: false,
456 },
457 FeatureTest {
458 name: "closure_capture",
459 covers: &["function_expr"],
460 code: "function test() { let base = 3; let f = function(x) { return x + base; }; return f(4); }",
461 function: "test",
462 category: FeatureCategory::Function,
463 requires_data: false,
464 },
465 FeatureTest {
466 name: "function_call",
467 covers: &["function_call", "arg_list"],
468 code: "function double(x) { return x * 2; } function test() { return double(5); }",
469 function: "test",
470 category: FeatureCategory::Function,
471 requires_data: false,
472 },
473 FeatureTest {
474 name: "return_type_annotation",
475 covers: &["return_type", "type_annotation"],
476 code: "function add(a, b) -> number { return a + b; } function test() { return add(1, 2); }",
477 function: "test",
478 category: FeatureCategory::Function,
479 requires_data: false,
480 },
481 FeatureTest {
483 name: "index_access",
484 covers: &["index_access", "index_expr", "postfix_expr"],
485 code: "function test() { return [1, 2, 3][1]; }",
486 function: "test",
487 category: FeatureCategory::Collection,
488 requires_data: false,
489 },
490 FeatureTest {
491 name: "negative_index",
492 covers: &["index_access", "index_expr"],
493 code: "function test() { return [1, 2, 3][-1]; }",
494 function: "test",
495 category: FeatureCategory::Collection,
496 requires_data: false,
497 },
498 FeatureTest {
499 name: "slice_access",
500 covers: &["index_access", "range_expr"],
501 code: "function test() { return [1, 2, 3, 4][1:3]; }",
502 function: "test",
503 category: FeatureCategory::Collection,
504 requires_data: false,
505 },
506 FeatureTest {
507 name: "property_access",
508 covers: &["property_access", "postfix_expr"],
509 code: "function test() { return { a: 1 }.a; }",
510 function: "test",
511 category: FeatureCategory::Collection,
512 requires_data: false,
513 },
514 FeatureTest {
515 name: "optional_property_access",
516 covers: &["optional_property_access"],
517 code: "function test() { let x = null; return x?.a; }",
518 function: "test",
519 category: FeatureCategory::Collection,
520 requires_data: false,
521 },
522 FeatureTest {
523 name: "spread_element",
524 covers: &["spread_element", "array_element"],
525 code: "function test() { let xs = [1, 2]; return [0, ...xs, 3]; }",
526 function: "test",
527 category: FeatureCategory::Collection,
528 requires_data: false,
529 },
530 FeatureTest {
531 name: "object_spread",
532 covers: &["object_spread", "object_field_item"],
533 code: "function test() { let a = { x: 1 }; return { ...a, y: 2 }; }",
534 function: "test",
535 category: FeatureCategory::Collection,
536 requires_data: false,
537 },
538 FeatureTest {
539 name: "list_comprehension",
540 covers: &["list_comprehension", "comprehension_clause"],
541 code: "function test() { return [x * 2 for x in [1, 2, 3]]; }",
542 function: "test",
543 category: FeatureCategory::Collection,
544 requires_data: false,
545 },
546 FeatureTest {
547 name: "list_comprehension_filter",
548 covers: &["list_comprehension", "comprehension_clause"],
549 code: "function test() { return [x for x in [1, 2, 3, 4] if x > 2]; }",
550 function: "test",
551 category: FeatureCategory::Collection,
552 requires_data: false,
553 },
554 FeatureTest {
556 name: "data_ref",
557 covers: &["data_ref", "primary_expr"],
558 code: "function test() { return data[0].close; }",
559 function: "test",
560 category: FeatureCategory::Domain,
561 requires_data: true,
562 },
563 FeatureTest {
564 name: "datetime_access",
565 covers: &["datetime_access", "datetime_range"],
566 code: r#"function test() { return data[@"2020-01-01"]; }"#,
567 function: "test",
568 category: FeatureCategory::Domain,
569 requires_data: false,
570 },
571 FeatureTest {
572 name: "timeframe_expr",
573 covers: &["timeframe_expr", "timeframe"],
574 code: "function test() { return on(1h) { 2 + 2 }; }",
575 function: "test",
576 category: FeatureCategory::Domain,
577 requires_data: false,
578 },
579 FeatureTest {
580 name: "temporal_nav",
581 covers: &["temporal_nav", "back_nav", "forward_nav", "nav_amount"],
582 code: "function test() { return back(5); }",
583 function: "test",
584 category: FeatureCategory::Domain,
585 requires_data: false,
586 },
587 FeatureTest {
588 name: "pattern_name",
589 covers: &["pattern_name"],
590 code: "function test() { return pattern::mypat; }",
591 function: "test",
592 category: FeatureCategory::Domain,
593 requires_data: false,
594 },
595 FeatureTest {
596 name: "builtin_function",
597 covers: &["builtin_function"],
598 code: "function test() { return abs(-5) + sqrt(9); }",
599 function: "test",
600 category: FeatureCategory::Domain,
601 requires_data: false,
602 },
603 FeatureTest {
607 name: "type_method_expr",
608 covers: &["postfix_expr"],
609 code: "function test() { return 123.type().to_string(); }",
610 function: "test",
611 category: FeatureCategory::TypeSystem,
612 requires_data: false,
613 },
614 FeatureTest {
615 name: "type_assertion",
616 covers: &["type_assertion_suffix", "postfix_expr"],
617 code: "function test() { let x = 5 as number; return x; }",
618 function: "test",
619 category: FeatureCategory::TypeSystem,
620 requires_data: false,
621 },
622 FeatureTest {
623 name: "type_annotation",
624 covers: &["type_annotation", "primary_type", "basic_type"],
625 code: "function test(x: number) -> number { return x; } function main() { return test(5); }",
626 function: "main",
627 category: FeatureCategory::TypeSystem,
628 requires_data: false,
629 },
630 FeatureTest {
631 name: "generic_type",
632 covers: &["generic_type", "type_param_list"],
633 code: "function test() { let arr: Vec<number> = [1, 2, 3]; return arr[0]; }",
634 function: "test",
635 category: FeatureCategory::TypeSystem,
636 requires_data: false,
637 },
638 FeatureTest {
639 name: "tuple_type",
640 covers: &["tuple_type"],
641 code: "function test() { let t: [number, string] = [1, \"a\"]; return t[0]; }",
642 function: "test",
643 category: FeatureCategory::TypeSystem,
644 requires_data: false,
645 },
646 FeatureTest {
647 name: "object_type",
648 covers: &["object_type", "object_type_member"],
649 code: "function test() { let obj: { a: number; b: string } = { a: 1, b: \"x\" }; return obj.a; }",
650 function: "test",
651 category: FeatureCategory::TypeSystem,
652 requires_data: false,
653 },
654 FeatureTest {
656 name: "ident_and_keyword",
657 covers: &["ident", "keyword"],
658 code: "function test() { let myVar = 5; return myVar; }",
659 function: "test",
660 category: FeatureCategory::Module,
661 requires_data: false,
662 },
663 FeatureTest {
665 name: "block_expr",
666 covers: &["block_expr", "block_items", "block_item"],
667 code: "function test() { return { let x = 1; x + 2 }; }",
668 function: "test",
669 category: FeatureCategory::ControlFlow,
670 requires_data: false,
671 },
672 FeatureTest {
673 name: "expression_stmt",
674 covers: &["expression_stmt", "statement"],
675 code: "function test() { let x = 0; x = x + 1; return x; }",
676 function: "test",
677 category: FeatureCategory::Variable,
678 requires_data: false,
679 },
680];
681
682#[cfg(test)]
683mod tests {
684 use super::*;
685 use std::collections::BTreeSet;
686
687 #[test]
688 fn test_feature_tests_defined() {
689 assert!(!FEATURE_TESTS.is_empty());
690 let categories: BTreeSet<_> = FEATURE_TESTS.iter().map(|t| t.category).collect();
692 assert!(categories.len() >= 5);
693 }
694}