use super::*;
#[test]
fn test_power_simple() {
let expr = parse_latex("x^2").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::variable("x".to_string()));
assert_eq!(**right, Expression::integer(2));
}
_ => panic!("Expected binary power"),
}
}
#[test]
fn test_power_braced() {
let expr = parse_latex("x^{10}").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::variable("x".to_string()));
assert_eq!(**right, Expression::integer(10));
}
_ => panic!("Expected binary power"),
}
}
#[test]
fn test_power_expression_simple() {
let expr = parse_latex("x^{n+1}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("x".to_string()));
assert!(matches!(
right.kind,
ExprKind::Binary {
op: BinaryOp::Add,
..
}
));
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_expression_complex() {
let expr = parse_latex("x^{2*n+1}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("x".to_string()));
match &right.kind {
ExprKind::Binary {
op: BinaryOp::Add,
left: add_left,
..
} => {
assert!(matches!(
add_left.kind,
ExprKind::Binary {
op: BinaryOp::Mul,
..
}
));
}
_ => panic!("Expected addition in exponent"),
}
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_nested() {
let expr = parse_latex("x^{y^z}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("x".to_string()));
match &right.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left: inner_left,
right: inner_right,
} => {
assert_eq!(**inner_left, Expression::variable("y".to_string()));
assert_eq!(**inner_right, Expression::variable("z".to_string()));
}
_ => panic!("Expected nested power"),
}
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_triple_nested() {
let expr = parse_latex("a^{b^{c^d}}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("a".to_string()));
match &right.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
right: r1,
..
} => {
assert!(matches!(
r1.kind,
ExprKind::Binary {
op: BinaryOp::Pow,
..
}
));
}
_ => panic!("Expected nested powers"),
}
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_of_number() {
let expr = parse_latex("2^3").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::integer(2));
assert_eq!(**right, Expression::integer(3));
}
_ => panic!("Expected binary power"),
}
}
#[test]
fn test_power_negative_exponent() {
let expr = parse_latex("x^{-1}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("x".to_string()));
match &right.kind {
ExprKind::Unary {
op: crate::ast::UnaryOp::Neg,
operand,
} => {
assert_eq!(**operand, Expression::integer(1));
}
_ => panic!("Expected unary negation"),
}
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_fraction_exponent() {
let expr = parse_latex(r"x^{\frac{1}{2}}").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert_eq!(**left, Expression::variable("x".to_string()));
assert!(matches!(
right.kind,
ExprKind::Binary {
op: BinaryOp::Div,
..
}
));
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_greek_letter() {
let expr = parse_latex(r"x^\alpha").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::variable("x".to_string()));
assert_eq!(**right, Expression::variable("alpha".to_string()));
}
_ => panic!("Expected binary power"),
}
}
#[test]
fn test_subscript_simple() {
let expr = parse_latex("x_1").unwrap();
assert_eq!(expr, Expression::variable("x_1".to_string()));
}
#[test]
fn test_subscript_braced() {
let expr = parse_latex("x_{12}").unwrap();
assert_eq!(expr, Expression::variable("x_12".to_string()));
}
#[test]
fn test_subscript_variable() {
let expr = parse_latex("x_i").unwrap();
assert_eq!(expr, Expression::variable("x_i".to_string()));
}
#[test]
fn test_subscript_letter() {
let expr = parse_latex("x_n").unwrap();
assert_eq!(expr, Expression::variable("x_n".to_string()));
}
#[test]
fn test_subscript_braced_variable() {
let expr = parse_latex("x_{m*a*x}").unwrap();
assert_eq!(expr, Expression::variable("x_mtimesatimesx".to_string()));
}
#[test]
fn test_subscript_zero() {
let expr = parse_latex("x_0").unwrap();
assert_eq!(expr, Expression::variable("x_0".to_string()));
}
#[test]
fn test_subscript_three_digits() {
let expr = parse_latex("x_{123}").unwrap();
assert_eq!(expr, Expression::variable("x_123".to_string()));
}
#[test]
fn test_subscript_then_superscript() {
let result = parse_latex("x_i^n");
assert!(result.is_err());
}
#[test]
fn test_superscript_then_subscript() {
let result = parse_latex("x^n_i");
assert!(result.is_err());
}
#[test]
fn test_subscript_and_superscript_braced() {
let result = parse_latex("x_{i}^{n}");
assert!(result.is_err());
}
#[test]
fn test_subscript_expression_addition() {
let expr = parse_latex("x_{i+1}").unwrap();
assert_eq!(expr, Expression::variable("x_iplus1".to_string()));
}
#[test]
fn test_subscript_expression_subtraction() {
let expr = parse_latex("a_{n-1}").unwrap();
assert_eq!(expr, Expression::variable("a_nminus1".to_string()));
}
#[test]
fn test_subscript_expression_multiplication() {
let expr = parse_latex("x_{2*i}").unwrap();
assert_eq!(expr, Expression::variable("x_2timesi".to_string()));
}
#[test]
fn test_subscript_expression_complex() {
let expr = parse_latex("x_{i+2*j}").unwrap();
assert_eq!(expr, Expression::variable("x_iplus2timesj".to_string()));
}
#[test]
fn test_subscript_expression_nested() {
let expr = parse_latex("x_{(i+1)*2}").unwrap();
assert_eq!(expr, Expression::variable("x_iplus1times2".to_string()));
}
#[test]
fn test_subscript_power_combined_complex() {
let result = parse_latex("x_{i+1}^{2}");
assert!(result.is_err());
}
#[test]
fn test_power_in_addition() {
let expr = parse_latex("x^2 + y^2").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Add,
left,
right,
} => {
assert!(matches!(
left.kind,
ExprKind::Binary {
op: BinaryOp::Pow,
..
}
));
assert!(matches!(
right.kind,
ExprKind::Binary {
op: BinaryOp::Pow,
..
}
));
}
_ => panic!("Expected addition"),
}
}
#[test]
fn test_power_in_multiplication() {
let expr = parse_latex("2 * x^2").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Mul,
left,
right,
} => {
assert_eq!(**left, Expression::integer(2));
assert!(matches!(
right.kind,
ExprKind::Binary {
op: BinaryOp::Pow,
..
}
));
}
_ => panic!("Expected multiplication"),
}
}
#[test]
fn test_power_of_sum() {
let expr = parse_latex("(x+y)^2").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert!(matches!(
left.kind,
ExprKind::Binary {
op: BinaryOp::Add,
..
}
));
assert_eq!(**right, Expression::integer(2));
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_power_of_product() {
let expr = parse_latex("(x*y)^n").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Pow,
left,
right,
} => {
assert!(matches!(
left.kind,
ExprKind::Binary {
op: BinaryOp::Mul,
..
}
));
assert_eq!(**right, Expression::variable("n".to_string()));
}
_ => panic!("Expected power expression"),
}
}
#[test]
fn test_subscript_expression_with_negative() {
let expr = parse_latex("x_{-1}").unwrap();
assert_eq!(expr, Expression::variable("x_neg1".to_string()));
}
#[test]
fn test_subscript_expression_division() {
let expr = parse_latex("x_{n/2}").unwrap();
assert_eq!(expr, Expression::variable("x_ndiv2".to_string()));
}
#[test]
fn test_subscript_expression_power() {
let expr = parse_latex("x_{i^2}").unwrap();
assert_eq!(expr, Expression::variable("x_ipow2".to_string()));
}
#[test]
fn test_multiple_subscripts_in_expression() {
let expr = parse_latex("x_1 + x_2 + x_3").unwrap();
match &expr.kind {
ExprKind::Binary {
op: BinaryOp::Add,
left,
right,
} => {
match &left.kind {
ExprKind::Binary {
op: BinaryOp::Add,
left: ll,
right: lr,
} => {
assert_eq!(**ll, Expression::variable("x_1".to_string()));
assert_eq!(**lr, Expression::variable("x_2".to_string()));
}
_ => panic!("Expected addition"),
}
assert_eq!(**right, Expression::variable("x_3".to_string()));
}
_ => panic!("Expected addition"),
}
}
#[test]
fn test_power_zero() {
let expr = parse_latex("x^0").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::variable("x".to_string()));
assert_eq!(**right, Expression::integer(0));
}
_ => panic!("Expected binary power"),
}
}
#[test]
fn test_power_one() {
let expr = parse_latex("x^1").unwrap();
match &expr.kind {
ExprKind::Binary { op, left, right } => {
assert_eq!(*op, BinaryOp::Pow);
assert_eq!(**left, Expression::variable("x".to_string()));
assert_eq!(**right, Expression::integer(1));
}
_ => panic!("Expected binary power"),
}
}