use crate::engine::fold::expr_match::fold_expr_match;
use toasty_core::stmt::{Expr, ExprMatch, MatchArm, Value};
#[test]
fn constant_subject_matches_arm() {
let mut expr = ExprMatch {
subject: Box::new(Expr::from(1i64)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::from("a"),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("b"),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(matches!(result, Some(Expr::Value(Value::String(ref s))) if s == "b"));
}
#[test]
fn constant_subject_no_matching_arm_folds_to_else() {
let mut expr = ExprMatch {
subject: Box::new(Expr::from(99i64)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::from("a"),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("b"),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(matches!(result, Some(Expr::Value(Value::Null))));
}
#[test]
fn non_constant_subject_not_simplified() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::from("a"),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("b"),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(result.is_none());
}
#[test]
fn uniform_arms_and_else_folds_to_single_expr() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::arg(1),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::arg(1),
},
],
else_expr: Box::new(Expr::arg(1)),
};
let result = fold_expr_match(&mut expr);
assert_eq!(result, Some(Expr::arg(1)));
}
#[test]
fn uniform_arms_but_different_else_not_simplified() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::arg(1),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::arg(1),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(result.is_none());
}
#[test]
fn non_uniform_arms_not_simplified() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::arg(1),
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::arg(2),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(result.is_none());
}
#[test]
fn empty_arms_not_simplified() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(result.is_none());
}
#[test]
fn false_arm_expr_not_dropped() {
let mut expr = ExprMatch {
subject: Box::new(Expr::arg(0)),
arms: vec![
MatchArm {
pattern: Value::from(0i64),
expr: Expr::FALSE,
},
MatchArm {
pattern: Value::from(1i64),
expr: Expr::from("b"),
},
],
else_expr: Box::new(Expr::null()),
};
let result = fold_expr_match(&mut expr);
assert!(result.is_none());
assert_eq!(expr.arms.len(), 2, "false-valued arm must not be dropped");
}