aprender_test_showcase/
lib.rs1#![cfg_attr(
34 test,
35 allow(
36 clippy::unwrap_used,
37 clippy::expect_used,
38 clippy::panic,
39 clippy::float_cmp
40 )
41)]
42#![deny(missing_docs)]
43#![deny(missing_debug_implementations)]
44
45pub mod core;
46pub mod driver;
47
48#[cfg(feature = "tui")]
49pub mod tui;
50
51pub mod wasm;
54
55#[cfg(test)]
59mod probar_tests;
60
61pub mod prelude {
63 pub use crate::core::evaluator::Evaluator;
64 pub use crate::core::history::{History, HistoryEntry};
65 pub use crate::core::parser::{AstNode, Parser, Token, Tokenizer};
66 pub use crate::core::{
67 AnomalyValidator, AnomalyViolation, CalcError, CalcResult, Calculator, Operation,
68 };
69 pub use crate::driver::{CalculatorDriver, HistoryItem};
70
71 #[cfg(feature = "tui")]
72 pub use crate::driver::TuiDriver;
73
74 pub use crate::wasm::{DomElement, DomEvent, MockDom, WasmCalculator, WasmDriver};
75}
76
77#[cfg(test)]
78mod tests {
79 use super::prelude::*;
80
81 #[test]
82 fn test_prelude_imports() {
83 let mut eval = Evaluator::new();
85 let result = eval.evaluate_str("2 + 3").unwrap();
86 assert_eq!(result, 5.0);
87 }
88
89 #[test]
90 fn test_calculator_direct() {
91 let mut calc = Calculator::new();
92 let result = calc.calculate(6.0, 7.0, Operation::Multiply).unwrap();
93 assert_eq!(result, 42.0);
94 }
95
96 #[test]
97 fn test_parser_direct() {
98 let ast = Parser::parse_str("1 + 2 * 3").unwrap();
99 let mut eval = Evaluator::new();
100 assert_eq!(eval.evaluate(&ast).unwrap(), 7.0);
101 }
102
103 #[test]
104 fn test_history_tracking() {
105 let mut history = History::new();
106 history.record("10 / 2", 5.0);
107 assert_eq!(history.len(), 1);
108 assert_eq!(history.last().unwrap().display(), "10 / 2 = 5");
109 }
110
111 #[test]
112 fn test_jidoka_validation() {
113 let validator = AnomalyValidator::with_max_magnitude(50.0);
114 let mut eval = Evaluator::with_validator(validator);
115
116 assert!(eval.evaluate_str("5 * 5").is_ok());
118
119 assert!(matches!(
121 eval.evaluate_str("10 * 10"),
122 Err(CalcError::AnomalyViolation(_))
123 ));
124 }
125
126 #[test]
127 fn test_error_handling() {
128 let mut eval = Evaluator::new();
129
130 assert!(matches!(
132 eval.evaluate_str("1 / 0"),
133 Err(CalcError::DivisionByZero)
134 ));
135
136 assert!(matches!(
138 eval.evaluate_str(""),
139 Err(CalcError::EmptyExpression)
140 ));
141
142 assert!(matches!(
144 eval.evaluate_str("1 + + 2"),
145 Err(CalcError::ParseError(_))
146 ));
147 }
148
149 #[test]
150 fn test_all_operations() {
151 let mut eval = Evaluator::new();
152
153 assert_eq!(eval.evaluate_str("10 + 5").unwrap(), 15.0);
154 assert_eq!(eval.evaluate_str("10 - 3").unwrap(), 7.0);
155 assert_eq!(eval.evaluate_str("6 * 7").unwrap(), 42.0);
156 assert_eq!(eval.evaluate_str("20 / 4").unwrap(), 5.0);
157 assert_eq!(eval.evaluate_str("17 % 5").unwrap(), 2.0);
158 assert_eq!(eval.evaluate_str("2 ^ 10").unwrap(), 1024.0);
159 }
160
161 #[test]
162 fn test_complex_expressions() {
163 let mut eval = Evaluator::new();
164
165 assert_eq!(eval.evaluate_str("2 + 3 * 4").unwrap(), 14.0);
167
168 assert_eq!(eval.evaluate_str("(2 + 3) * 4").unwrap(), 20.0);
170
171 assert_eq!(eval.evaluate_str("2 ^ 3 ^ 2").unwrap(), 512.0);
173
174 assert_eq!(eval.evaluate_str("42 * (3 + 7)").unwrap(), 420.0);
176
177 assert_eq!(eval.evaluate_str("-5 + 10").unwrap(), 5.0);
179 }
180}