1use std::fmt;
37
38#[derive(Default)]
39pub struct TestResult {
40 pub passed: i32,
41 pub failed: i32,
42 pub skipped: i32,
43}
44
45impl TestResult {
46 pub fn new() -> Self {
47 Self::default()
48 }
49
50 pub fn add_passed(&mut self) {
51 self.passed += 1;
52 }
53
54 pub fn add_failed(&mut self) {
55 self.failed += 1;
56 }
57
58 pub fn add_skipped(&mut self) {
59 self.skipped += 1;
60 }
61
62 pub fn total(&self) -> i32 {
63 self.passed + self.failed + self.skipped
64 }
65
66 pub fn compliance_rate(&self) -> f64 {
67 if self.passed + self.failed > 0 {
68 (self.passed as f64 / (self.passed + self.failed) as f64) * 100.0
69 } else {
70 0.0
71 }
72 }
73}
74
75impl fmt::Display for TestResult {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 writeln!(f, "=== Final Results ===")?;
78 writeln!(f, "Passed: {}", self.passed)?;
79 writeln!(f, "Failed: {}", self.failed)?;
80 writeln!(f, "Skipped: {}", self.skipped)?;
81 writeln!(f, "Total: {}", self.total())?;
82 writeln!(f, "Compliance Rate: {:.1}%", self.compliance_rate())?;
83
84 if self.failed == 0 {
85 writeln!(f, "🎉 All implemented features are compliant!")?;
86 } else {
87 writeln!(f, "⚠️ Some features need improvements.")?;
88 }
89 Ok(())
90 }
91}
92
93#[derive(Default)]
94pub struct TestRunner {
95 pub engine: crate::api::Engine,
96}
97
98impl TestRunner {
99 pub fn new() -> Self {
100 Self::default()
101 }
102
103 pub fn run_test(&mut self, _test_name: &str, code: &str, expected: &str) -> TestResult {
104 let mut result = TestResult::new();
105
106 match self.engine.evaluate(code) {
107 Ok(eval_result) => {
108 let result_str = eval_result.to_string();
109 if result_str == expected {
110 result.add_passed();
111 } else {
112 result.add_failed();
113 }
114 }
115 Err(_) => {
116 result.add_skipped();
117 }
118 }
119
120 result
121 }
122
123 pub fn run_tests(&mut self, tests: Vec<(&str, &str, &str)>) -> TestResult {
124 let mut total_result = TestResult::new();
125
126 for (test_name, code, expected) in tests {
127 let test_result = self.run_test(test_name, code, expected);
128 total_result.passed += test_result.passed;
129 total_result.failed += test_result.failed;
130 total_result.skipped += test_result.skipped;
131 }
132
133 total_result
134 }
135}
136
137#[derive(Default)]
138pub struct E2ETestRunner {
139 pub engine: crate::api::Engine,
140}
141
142impl E2ETestRunner {
143 pub fn new() -> Self {
144 Self::default()
145 }
146
147 pub fn run_e2e_test(&mut self, _test_name: &str, code: &str, expected: &str) -> TestResult {
148 let mut result = TestResult::new();
149
150 match self.engine.evaluate(code) {
151 Ok(eval_result) => {
152 let result_str = eval_result.to_string();
153 if result_str == expected {
154 result.add_passed();
155 } else {
156 result.add_failed();
157 }
158 }
159 Err(_error) => {
160 result.add_failed();
161 }
162 }
163
164 result
165 }
166
167 pub fn run_e2e_tests(&mut self, tests: Vec<(&str, &str, &str)>) -> TestResult {
168 let mut total_result = TestResult::new();
169
170 for (test_name, code, expected) in tests {
171 let test_result = self.run_e2e_test(test_name, code, expected);
172 total_result.passed += test_result.passed;
173 total_result.failed += test_result.failed;
174 total_result.skipped += test_result.skipped;
175 }
176
177 total_result
178 }
179}
180
181pub fn get_test_header(title: &str) -> String {
182 format!("\n=== {title} ===")
183}
184
185pub fn get_test_summary(result: &TestResult) -> String {
186 format!("{result}")
187}