Skip to main content

shape_vm/feature_tests/
pattern_tests.rs

1//! Tests for pattern-related features
2//!
3//! This module covers pattern grammar rules:
4//! - pattern_def - Pattern definitions
5//! - pattern_ref - Pattern references using find()
6//! - inline_pattern - Inline patterns in find expressions
7
8use super::{FeatureCategory, FeatureTest};
9
10pub const TESTS: &[FeatureTest] = &[
11    // === Pattern Definition ===
12    FeatureTest {
13        name: "pattern_def_basic",
14        covers: &["pattern_def", "pattern_body", "condition_list"],
15        code: r#"
16pattern simple_up {
17    data[0].close > data[0].open
18}
19
20function test() {
21    return true;
22}
23"#,
24        function: "test",
25        category: FeatureCategory::Domain,
26        requires_data: false,
27    },
28    FeatureTest {
29        name: "pattern_def_with_params",
30        covers: &[
31            "pattern_def",
32            "pattern_params",
33            "pattern_param_list",
34            "pattern_param",
35        ],
36        code: r#"
37pattern threshold_cross(level) {
38    data[0].close > level
39}
40
41function test() {
42    return true;
43}
44"#,
45        function: "test",
46        category: FeatureCategory::Domain,
47        requires_data: false,
48    },
49    FeatureTest {
50        name: "pattern_def_with_threshold",
51        covers: &["pattern_def", "threshold"],
52        code: r#"
53pattern fuzzy_up ~0.02 {
54    data[0].close > data[0].open
55}
56
57function test() {
58    return true;
59}
60"#,
61        function: "test",
62        category: FeatureCategory::Domain,
63        requires_data: false,
64    },
65    FeatureTest {
66        name: "pattern_def_with_statements",
67        covers: &["pattern_def", "pattern_statement_list", "pattern_statement"],
68        code: r#"
69pattern complex_pattern(c) {
70    let body = abs(c.close - c.open);
71    let upper_wick = c.high - max(c.open, c.close);
72    body > upper_wick * 2
73}
74
75function test() {
76    return true;
77}
78"#,
79        function: "test",
80        category: FeatureCategory::Domain,
81        requires_data: false,
82    },
83    FeatureTest {
84        name: "pattern_def_with_annotation",
85        covers: &["pattern_def", "annotations", "annotation"],
86        code: r#"
87@export
88pattern hammer(c) {
89    let body = abs(c.close - c.open);
90    let lower_wick = min(c.open, c.close) - c.low;
91    lower_wick > body * 2
92}
93
94function test() {
95    return true;
96}
97"#,
98        function: "test",
99        category: FeatureCategory::Domain,
100        requires_data: false,
101    },
102    FeatureTest {
103        name: "pattern_def_weighted_conditions",
104        covers: &["pattern_def", "condition", "weight"],
105        code: r#"
106pattern weighted_pattern {
107    data[0].close > data[0].open weight 2
108    and data[0].volume > 1000 weight 1
109}
110
111function test() {
112    return true;
113}
114"#,
115        function: "test",
116        category: FeatureCategory::Domain,
117        requires_data: false,
118    },
119    // === Pattern Reference ===
120    FeatureTest {
121        name: "pattern_ref_by_name",
122        covers: &["pattern_ref", "pattern_name"],
123        code: r#"
124function test() {
125    let p = pattern::hammer;
126    return p;
127}
128"#,
129        function: "test",
130        category: FeatureCategory::Domain,
131        requires_data: false,
132    },
133    // === Inline Pattern ===
134    FeatureTest {
135        name: "inline_pattern_basic",
136        covers: &["inline_pattern", "pattern_body"],
137        code: r#"
138function test() {
139    let inline = { data[0].close > data[0].open };
140    return true;
141}
142"#,
143        function: "test",
144        category: FeatureCategory::Domain,
145        requires_data: false,
146    },
147    FeatureTest {
148        name: "inline_pattern_with_lambda",
149        covers: &["inline_pattern", "arrow_function"],
150        code: r#"
151function test() {
152    let checker = c => c.close > c.open;
153    return checker({ close: 10, open: 5 });
154}
155"#,
156        function: "test",
157        category: FeatureCategory::Domain,
158        requires_data: false,
159    },
160];
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn test_pattern_tests_defined() {
168        assert!(!TESTS.is_empty());
169        // All tests should be in Domain category
170        for test in TESTS {
171            assert_eq!(test.category, FeatureCategory::Domain);
172        }
173    }
174}