#![allow(clippy::approx_constant)]
use mathlex::latex::ToLatex;
use mathlex::{parse, parse_latex};
fn assert_roundtrip_text(input: &str) {
let expr1 = parse(input).unwrap_or_else(|e| {
panic!("Failed to parse first time: {}\nInput: {}", e, input);
});
let output = expr1.to_string();
let expr2 = parse(&output).unwrap_or_else(|e| {
panic!(
"Failed to parse serialized output: {}\nOriginal input: {}\nSerialized: {}",
e, input, output
);
});
assert_eq!(
expr1, expr2,
"ASTs don't match after round-trip\nOriginal input: {}\nSerialized: {}\nFirst AST: {:?}\nSecond AST: {:?}",
input, output, expr1, expr2
);
}
fn assert_roundtrip_latex(input: &str) {
let expr1 = parse_latex(input).unwrap_or_else(|e| {
panic!("Failed to parse LaTeX first time: {}\nInput: {}", e, input);
});
let output = expr1.to_latex();
let expr2 = parse_latex(&output).unwrap_or_else(|e| {
panic!(
"Serialized LaTeX cannot be parsed back:\n Original input: {}\n Serialized: {}\n Parse error: {}",
input, output, e
);
});
assert_eq!(
expr1, expr2,
"ASTs don't match after LaTeX round-trip\nOriginal input: {}\nSerialized: {}\nFirst AST: {:?}\nSecond AST: {:?}",
input, output, expr1, expr2
);
}
#[test]
fn test_text_integer() {
assert_roundtrip_text("42");
assert_roundtrip_text("-17");
assert_roundtrip_text("0");
}
#[test]
fn test_text_float() {
assert_roundtrip_text("3.14");
assert_roundtrip_text("-2.5");
}
#[test]
fn test_text_variable() {
assert_roundtrip_text("x");
assert_roundtrip_text("alpha");
}
#[test]
fn test_text_constant() {
assert_roundtrip_text("pi");
assert_roundtrip_text("e");
assert_roundtrip_text("i");
assert_roundtrip_text("inf");
}
#[test]
fn test_text_arithmetic_simple() {
assert_roundtrip_text("1 + 2");
assert_roundtrip_text("5 - 3");
assert_roundtrip_text("2 * 3");
assert_roundtrip_text("10 / 5");
assert_roundtrip_text("2 ^ 3");
}
#[test]
fn test_text_arithmetic_precedence() {
assert_roundtrip_text("1 + 2 * 3");
assert_roundtrip_text("2 * 3 + 4");
assert_roundtrip_text("(1 + 2) * 3");
assert_roundtrip_text("2 * (3 + 4)");
}
#[test]
fn test_text_arithmetic_associativity() {
assert_roundtrip_text("5 - 3 - 1");
assert_roundtrip_text("10 / 2 / 5");
assert_roundtrip_text("5 - (3 - 1)");
assert_roundtrip_text("2 ^ (3 ^ 4)");
}
#[test]
fn test_text_unary_operations() {
assert_roundtrip_text("-5");
assert_roundtrip_text("+3");
assert_roundtrip_text("n!");
}
#[test]
fn test_text_functions_basic() {
assert_roundtrip_text("sin(x)");
assert_roundtrip_text("cos(theta)");
assert_roundtrip_text("tan(pi)");
assert_roundtrip_text("exp(1)");
}
#[test]
fn test_text_functions_multiple_args() {
assert_roundtrip_text("log(2, 8)");
assert_roundtrip_text("max(1, 2, 3)");
assert_roundtrip_text("min(x, y)");
}
#[test]
fn test_text_functions_nested() {
assert_roundtrip_text("sin(cos(x))");
assert_roundtrip_text("log(2, exp(x))");
assert_roundtrip_text("sqrt(sin(x) + cos(x))");
}
#[test]
fn test_text_rational() {
assert_roundtrip_text("1/2");
assert_roundtrip_text("a/b");
assert_roundtrip_text("(x + 1)/(y - 2)");
}
#[test]
fn test_text_complex() {
assert_roundtrip_text("3 + 4i");
assert_roundtrip_text("0 + 1i");
}
#[test]
fn test_text_equation() {
assert_roundtrip_text("x = 5");
assert_roundtrip_text("y = 2 * x + 1");
assert_roundtrip_text("a + b = c + d");
}
#[test]
fn test_text_inequality() {
assert_roundtrip_text("x < 5");
assert_roundtrip_text("y <= 10");
assert_roundtrip_text("z > 0");
assert_roundtrip_text("w >= -5");
assert_roundtrip_text("a != b");
}
#[test]
fn test_text_complex_nested() {
assert_roundtrip_text("(a + b) * (c - d) / e ^ f");
assert_roundtrip_text("n + 1!");
assert_roundtrip_text("log(2, x ^ 2 + 1)");
}
#[test]
fn test_latex_integer() {
assert_roundtrip_latex("42");
assert_roundtrip_latex("-17");
assert_roundtrip_latex("0");
}
#[test]
fn test_latex_float() {
assert_roundtrip_latex("3.14");
assert_roundtrip_latex("-2.5");
}
#[test]
fn test_latex_variable() {
assert_roundtrip_latex("x");
}
#[test]
fn test_latex_greek_variables() {
assert_roundtrip_latex(r"\alpha");
assert_roundtrip_latex(r"\beta");
assert_roundtrip_latex(r"\theta");
assert_roundtrip_latex(r"\pi");
}
#[test]
fn test_latex_variable_subscript() {
assert_roundtrip_latex("x_1");
assert_roundtrip_latex("x_{10}");
assert_roundtrip_latex(r"\alpha_i");
}
#[test]
fn test_latex_constant() {
assert_roundtrip_latex(r"\pi");
assert_roundtrip_latex("e");
assert_roundtrip_latex("i");
assert_roundtrip_latex(r"\infty");
}
#[test]
fn test_latex_arithmetic_simple() {
assert_roundtrip_latex("1 + 2");
assert_roundtrip_latex("5 - 3");
assert_roundtrip_latex("2 * 3");
assert_roundtrip_latex("2 ^ 3");
}
#[test]
fn test_latex_frac() {
assert_roundtrip_latex(r"\frac{1}{2}");
assert_roundtrip_latex(r"\frac{a}{b}");
assert_roundtrip_latex(r"\frac{x + 1}{y - 2}");
}
#[test]
fn test_latex_frac_nested() {
assert_roundtrip_latex(r"\frac{\frac{a}{b}}{\frac{c}{d}}");
assert_roundtrip_latex(r"\frac{a + b}{c}");
}
#[test]
fn test_latex_sqrt() {
assert_roundtrip_latex(r"\sqrt{x}");
assert_roundtrip_latex(r"\sqrt{2}");
}
#[test]
fn test_latex_power() {
assert_roundtrip_latex("x^{2}");
assert_roundtrip_latex("x^{n}");
assert_roundtrip_latex("e^{x}");
}
#[test]
fn test_latex_functions_basic() {
assert_roundtrip_latex(r"\sin\left(x\right)");
assert_roundtrip_latex(r"\cos\left(\theta\right)");
assert_roundtrip_latex(r"\tan\left(\pi\right)");
assert_roundtrip_latex(r"\exp\left(1\right)");
}
#[test]
fn test_latex_functions_nested() {
assert_roundtrip_latex(r"\sin\left(\cos\left(x\right)\right)");
}
#[test]
fn test_latex_equation() {
assert_roundtrip_latex("x = 5");
assert_roundtrip_latex("y = 2 * x + 1");
}
#[test]
fn test_latex_inequality() {
assert_roundtrip_latex("x < 5");
assert_roundtrip_latex(r"y \leq 10");
assert_roundtrip_latex("z > 0");
assert_roundtrip_latex(r"w \geq -5");
assert_roundtrip_latex(r"a \neq b");
}
#[test]
fn test_latex_derivative_first_order() {
assert_roundtrip_latex(r"\frac{d}{d*x}f");
assert_roundtrip_latex(r"\frac{d}{d*t}y");
}
#[test]
fn test_latex_derivative_higher_order() {
assert_roundtrip_latex(r"\frac{d^2}{d*x^2}f");
assert_roundtrip_latex(r"\frac{d^3}{d*t^3}y");
}
#[test]
fn test_latex_partial_derivative() {
assert_roundtrip_latex(r"\frac{\partial}{\partial*x}f");
assert_roundtrip_latex(r"\frac{\partial^2}{\partial*y^2}f");
}
#[test]
fn test_latex_integral_indefinite() {
assert_roundtrip_latex(r"\int x dx");
assert_roundtrip_latex(r"\int \sin\left(x\right) dx");
}
#[test]
fn test_latex_integral_definite() {
assert_roundtrip_latex(r"\int_0^1 x dx");
assert_roundtrip_latex(r"\int_0^{\pi} \sin\left(x\right) dx");
}
#[test]
fn test_latex_limit() {
assert_roundtrip_latex(r"\lim_{x \to 0}f");
assert_roundtrip_latex(r"\lim_{x \to 0^-}f");
assert_roundtrip_latex(r"\lim_{x \to 0^+}f");
assert_roundtrip_latex(r"\lim_{x \to \infty}\frac{1}{x}");
}
#[test]
fn test_latex_sum() {
assert_roundtrip_latex(r"\sum_{i=1}^{n}i");
assert_roundtrip_latex(r"\sum_{k=0}^{10}k^{2}");
}
#[test]
fn test_latex_product() {
assert_roundtrip_latex(r"\prod_{i=1}^{n}i");
assert_roundtrip_latex(r"\prod_{j=1}^{5}j + 1");
}
#[test]
fn test_latex_vector() {
assert_roundtrip_latex(r"\begin{pmatrix} 1 \end{pmatrix}");
assert_roundtrip_latex(r"\begin{pmatrix} 1 \\ 2 \\ 3 \end{pmatrix}");
}
#[test]
fn test_latex_matrix() {
assert_roundtrip_latex(r"\begin{pmatrix} 1 \end{pmatrix}");
assert_roundtrip_latex(r"\begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix}");
assert_roundtrip_latex(r"\begin{pmatrix} 1 & 2 \\ 3 & 4 \\ 5 & 6 \end{pmatrix}");
}
#[test]
fn test_latex_complex_nested() {
assert_roundtrip_latex(r"\frac{a + b}{c - d}");
assert_roundtrip_latex(r"\frac{d}{d*x}\sin\left(x^{2}\right)");
assert_roundtrip_latex(r"\sum_{i=1}^{n}\frac{1}{i}");
}
#[test]
fn test_latex_quadratic_formula() {
assert_roundtrip_latex(r"\frac{-b + \sqrt{b^{2} - 4 * a * c}}{2 * a}");
}
#[test]
fn test_latex_integral_complex() {
assert_roundtrip_latex(r"\int_0^{\pi} \sin\left(x\right)^{2} dx");
}
#[test]
fn test_text_deeply_nested_operations() {
assert_roundtrip_text("((((1 + 2) * 3) - 4) / 5)");
}
#[test]
fn test_text_mixed_operations() {
assert_roundtrip_text("sin(x) + cos(y) * tan(z)");
assert_roundtrip_text("log(2, x) ^ 2 + sqrt(y)");
}
#[test]
fn test_latex_mixed_fractions_and_powers() {
assert_roundtrip_latex(r"\frac{a^{2} + b^{2}}{c^{2} + d^{2}}");
}
#[test]
fn test_latex_complex_calculus() {
assert_roundtrip_latex(r"\frac{d}{d*x}\int_0^x \sin\left(t\right) dt");
}
#[test]
fn test_latex_cdot_simple() {
assert_roundtrip_latex(r"a \cdot b");
assert_roundtrip_latex(r"2 \cdot 3");
}
#[test]
fn test_latex_times_simple() {
assert_roundtrip_latex(r"a \times b");
assert_roundtrip_latex(r"2 \times 3");
}
#[test]
fn test_latex_cdot_complex() {
assert_roundtrip_latex(r"2 \cdot x + 3");
assert_roundtrip_latex(r"(a + b) \cdot (c - d)");
assert_roundtrip_latex(r"x \cdot y \cdot z");
}
#[test]
fn test_latex_times_complex() {
assert_roundtrip_latex(r"2 \times x + 3");
assert_roundtrip_latex(r"(a + b) \times (c - d)");
assert_roundtrip_latex(r"x \times y \times z");
}
#[test]
fn test_latex_cdot_precedence() {
assert_roundtrip_latex(r"a + b \cdot c");
assert_roundtrip_latex(r"a \cdot b + c");
assert_roundtrip_latex(r"a \cdot b^{2}");
}
#[test]
fn test_latex_times_precedence() {
assert_roundtrip_latex(r"a + b \times c");
assert_roundtrip_latex(r"a \times b + c");
assert_roundtrip_latex(r"a \times b^{2}");
}