mathlex 0.4.1

Mathematical expression parser for LaTeX and plain text notation, producing a language-agnostic AST
Documentation
//! Relation (equation and inequality) tests.

use super::*;

mod relations {
    use super::*;

    #[test]
    fn test_parse_simple_equation() {
        let expr = parse("x = 5").unwrap();
        match &expr.kind {
            ExprKind::Equation { left, right } => {
                assert_eq!(**left, Expression::variable("x".to_string()));
                assert_eq!(**right, Expression::integer(5));
            }
            _ => panic!("Expected Equation variant"),
        }
    }

    #[test]
    fn test_parse_inequality_less_than() {
        let expr = parse("x < 5").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Lt);
                assert_eq!(**left, Expression::variable("x".to_string()));
                assert_eq!(**right, Expression::integer(5));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_greater_than() {
        let expr = parse("x > 0").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Gt);
                assert_eq!(**left, Expression::variable("x".to_string()));
                assert_eq!(**right, Expression::integer(0));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_less_equal() {
        let expr = parse("x <= 3").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Le);
                assert_eq!(**left, Expression::variable("x".to_string()));
                assert_eq!(**right, Expression::integer(3));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_greater_equal() {
        let expr = parse("x >= -1").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, .. } => {
                assert_eq!(*op, InequalityOp::Ge);
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_not_equal() {
        let expr = parse("x != 0").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Ne);
                assert_eq!(**left, Expression::variable("x".to_string()));
                assert_eq!(**right, Expression::integer(0));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_unicode_le() {
        let expr = parse("x ≤ 3").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, .. } => {
                assert_eq!(*op, InequalityOp::Le);
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_unicode_ge() {
        let expr = parse("x ≥ -1").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, .. } => {
                assert_eq!(*op, InequalityOp::Ge);
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_inequality_unicode_ne() {
        let expr = parse("a ≠ b").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, .. } => {
                assert_eq!(*op, InequalityOp::Ne);
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_parse_complex_equation() {
        let expr = parse("2*x + 1 = 5").unwrap();
        match &expr.kind {
            ExprKind::Equation { left, right } => {
                assert!(matches!(
                    (**left).kind,
                    ExprKind::Binary {
                        op: BinaryOp::Add,
                        ..
                    }
                ));
                assert_eq!(**right, Expression::integer(5));
            }
            _ => panic!("Expected Equation variant"),
        }
    }

    #[test]
    fn test_parse_complex_inequality() {
        let expr = parse("a + b < c + d").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Lt);
                assert!(matches!(
                    (**left).kind,
                    ExprKind::Binary {
                        op: BinaryOp::Add,
                        ..
                    }
                ));
                assert!(matches!(
                    (**right).kind,
                    ExprKind::Binary {
                        op: BinaryOp::Add,
                        ..
                    }
                ));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }

    #[test]
    fn test_chained_relation_error() {
        let result = parse("a < b < c");
        assert!(result.is_err());
        if let Err(e) = result {
            let error_msg = e.to_string();
            assert!(error_msg.contains("chained relations"));
        }
    }

    #[test]
    fn test_relation_precedence_over_addition() {
        let expr = parse("2 + 3 = 5").unwrap();
        match &expr.kind {
            ExprKind::Equation { left, right } => {
                assert!(matches!(
                    (**left).kind,
                    ExprKind::Binary {
                        op: BinaryOp::Add,
                        ..
                    }
                ));
                assert_eq!(**right, Expression::integer(5));
            }
            _ => panic!("Expected Equation variant"),
        }
    }

    #[test]
    fn test_relation_with_parentheses() {
        let expr = parse("(x + 1) > y").unwrap();
        match &expr.kind {
            ExprKind::Inequality { op, left, right } => {
                assert_eq!(*op, InequalityOp::Gt);
                assert!(matches!(
                    (**left).kind,
                    ExprKind::Binary {
                        op: BinaryOp::Add,
                        ..
                    }
                ));
                assert_eq!(**right, Expression::variable("y".to_string()));
            }
            _ => panic!("Expected Inequality variant"),
        }
    }
}