159 lines
5.5 KiB
Rust
159 lines
5.5 KiB
Rust
use rstest::*;
|
|
use steel_decimal::ScriptParser;
|
|
use std::collections::HashSet;
|
|
|
|
#[fixture]
|
|
fn parser() -> ScriptParser {
|
|
ScriptParser::new()
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(+ 1.5 2.3)", "(decimal-add \"1.5\" \"2.3\")")]
|
|
#[case("(- 10 5)", "(decimal-sub \"10\" \"5\")")]
|
|
#[case("(* 2.5 4)", "(decimal-mul \"2.5\" \"4\")")]
|
|
#[case("(/ 15 3)", "(decimal-div \"15\" \"3\")")]
|
|
fn test_basic_arithmetic_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(^ 2 3)", "(decimal-pow \"2\" \"3\")")]
|
|
#[case("(** 2 3)", "(decimal-pow \"2\" \"3\")")]
|
|
#[case("(pow 2 3)", "(decimal-pow \"2\" \"3\")")]
|
|
#[case("(sqrt 16)", "(decimal-sqrt \"16\")")]
|
|
#[case("(ln 2.718)", "(decimal-ln \"2.718\")")]
|
|
#[case("(log 2.718)", "(decimal-ln \"2.718\")")]
|
|
#[case("(log10 100)", "(decimal-log10 \"100\")")]
|
|
#[case("(exp 1)", "(decimal-exp \"1\")")]
|
|
fn test_advanced_math_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(sin 1.57)", "(decimal-sin \"1.57\")")]
|
|
#[case("(cos 0)", "(decimal-cos \"0\")")]
|
|
#[case("(tan 0.785)", "(decimal-tan \"0.785\")")]
|
|
fn test_trigonometric_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(> 5 3)", "(decimal-gt \"5\" \"3\")")]
|
|
#[case("(< 3 5)", "(decimal-lt \"3\" \"5\")")]
|
|
#[case("(= 5 5)", "(decimal-eq \"5\" \"5\")")]
|
|
#[case("(>= 5 3)", "(decimal-gte \"5\" \"3\")")]
|
|
#[case("(<= 3 5)", "(decimal-lte \"3\" \"5\")")]
|
|
fn test_comparison_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(abs -5)", "(decimal-abs \"-5\")")]
|
|
#[case("(min 3 5)", "(decimal-min \"3\" \"5\")")]
|
|
#[case("(max 3 5)", "(decimal-max \"3\" \"5\")")]
|
|
#[case("(round 3.14159 2)", "(decimal-round \"3.14159\" \"2\")")]
|
|
fn test_utility_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("$x", "(get-var \"x\")")]
|
|
#[case("$price", "(get-var \"price\")")]
|
|
#[case("$some_variable", "(get-var \"some_variable\")")]
|
|
fn test_variable_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("42", "\"42\"")]
|
|
#[case("3.14159", "\"3.14159\"")]
|
|
#[case("-5.5", "\"-5.5\"")]
|
|
#[case("1.5e2", "\"1.5e2\"")]
|
|
#[case("2.3E-1", "\"2.3E-1\"")]
|
|
fn test_number_literal_transformation(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case(
|
|
"(+ (* 2.5 3.0) (/ 15.0 3.0))",
|
|
"(decimal-add (decimal-mul \"2.5\" \"3.0\") (decimal-div \"15.0\" \"3.0\"))"
|
|
)]
|
|
#[case(
|
|
"(sqrt (+ (* $x $x) (* $y $y)))",
|
|
"(decimal-sqrt (decimal-add (decimal-mul (get-var \"x\") (get-var \"x\")) (decimal-mul (get-var \"y\") (get-var \"y\"))))"
|
|
)]
|
|
#[case(
|
|
"(/ (+ $a $b) (- $c $d))",
|
|
"(decimal-div (decimal-add (get-var \"a\") (get-var \"b\")) (decimal-sub (get-var \"c\") (get-var \"d\")))"
|
|
)]
|
|
fn test_complex_expressions(parser: ScriptParser, #[case] input: &str, #[case] expected: &str) {
|
|
let result = parser.transform(input);
|
|
assert_eq!(result, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(+ $x $y)", vec!["x", "y"])]
|
|
#[case("(* $price $quantity)", vec!["price", "quantity"])]
|
|
#[case("(/ (+ $a $b) $c)", vec!["a", "b", "c"])]
|
|
#[case("(sqrt (+ (* $x $x) (* $y $y)))", vec!["x", "y"])]
|
|
fn test_dependency_extraction(parser: ScriptParser, #[case] input: &str, #[case] expected_deps: Vec<&str>) {
|
|
let deps = parser.extract_dependencies(input);
|
|
let expected: HashSet<String> = expected_deps.into_iter().map(|s| s.to_string()).collect();
|
|
assert_eq!(deps, expected);
|
|
}
|
|
|
|
#[rstest]
|
|
#[case("(+ 1 2)", "Addition")]
|
|
#[case("(- 5 3)", "Subtraction")]
|
|
#[case("(* 2 4)", "Multiplication")]
|
|
#[case("(/ 8 2)", "Division")]
|
|
#[case("(sin 0)", "Trigonometry")]
|
|
#[case("(sqrt 16)", "Square root")]
|
|
#[case("(> 5 3)", "Comparison")]
|
|
fn test_parser_handles_various_functions(parser: ScriptParser, #[case] input: &str, #[case] _description: &str) {
|
|
let result = parser.transform(input);
|
|
// Should not panic and should produce valid output
|
|
assert!(!result.is_empty());
|
|
assert!(result.starts_with('('));
|
|
assert!(result.ends_with(')'));
|
|
}
|
|
|
|
#[rstest]
|
|
fn test_parser_preserves_structure(parser: ScriptParser) {
|
|
let input = "(+ (- 10 5) (* 2 3))";
|
|
let result = parser.transform(input);
|
|
|
|
// Check that parentheses are balanced
|
|
let open_count = result.chars().filter(|c| *c == '(').count();
|
|
let close_count = result.chars().filter(|c| *c == ')').count();
|
|
assert_eq!(open_count, close_count);
|
|
|
|
// Check that the structure is preserved
|
|
assert!(result.contains("decimal-add"));
|
|
assert!(result.contains("decimal-sub"));
|
|
assert!(result.contains("decimal-mul"));
|
|
}
|
|
|
|
#[rstest]
|
|
fn test_parser_handles_empty_input(parser: ScriptParser) {
|
|
let result = parser.transform("");
|
|
assert_eq!(result, "");
|
|
}
|
|
|
|
#[rstest]
|
|
fn test_parser_handles_whitespace(parser: ScriptParser) {
|
|
let input = "( + 1.5 2.3 )";
|
|
let result = parser.transform(input);
|
|
assert!(result.contains("decimal-add"));
|
|
assert!(result.contains("\"1.5\""));
|
|
assert!(result.contains("\"2.3\""));
|
|
}
|