use symplex::prelude::*;
#[test]
fn floor_large_rational() {
let ctx = Context::new();
let result = ctx.rational(100, 7).floor().eval();
assert_eq!(format!("{result}"), "14");
}
#[test]
fn floor_just_below_integer() {
let ctx = Context::new();
let result = ctx.rational(99, 10).floor().eval();
assert_eq!(format!("{result}"), "9");
}
#[test]
fn floor_negative_just_above_integer() {
let ctx = Context::new();
let result = ctx.rational(-99, 10).floor().eval();
assert_eq!(format!("{result}"), "-10");
}
#[test]
fn ceiling_large_rational() {
let ctx = Context::new();
let result = ctx.rational(100, 7).ceiling().eval();
assert_eq!(format!("{result}"), "15");
}
#[test]
fn ceiling_negative_just_below_integer() {
let ctx = Context::new();
let result = ctx.rational(-99, 10).ceiling().eval();
assert_eq!(format!("{result}"), "-9");
}
#[test]
fn ceiling_exact_integer_unchanged() {
let ctx = Context::new();
let result = ctx.rational(10, 2).ceiling().eval();
assert_eq!(format!("{result}"), "5");
}
#[test]
fn rem_positive_integers() {
let ctx = Context::new();
let result = ctx.int(7).rem(&ctx.int(3)).eval();
assert_eq!(format!("{result}"), "1");
}
#[test]
fn rem_negative_dividend() {
let ctx = Context::new();
let result = ctx.int(-7).rem(&ctx.int(3)).eval();
assert_eq!(format!("{result}"), "2");
}
#[test]
fn sum_cubes_1_to_4() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(3);
let one = ctx.int(1);
let four = ctx.int(4);
let s = Ex::symbolic_sum(&body, &k, &one, &four);
let result = s.eval();
assert_eq!(format!("{result}"), "100");
}
#[test]
fn sum_constants() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = ctx.int(2);
let one = ctx.int(1);
let five = ctx.int(5);
let s = Ex::symbolic_sum(&body, &k, &one, &five);
let result = s.eval();
assert_eq!(format!("{result}"), "10");
}
#[test]
fn sum_empty_range() {
let ctx = Context::new();
let k = ctx.symbol("k");
let five = ctx.int(5);
let one = ctx.int(1);
let s = Ex::symbolic_sum(&k, &k, &five, &one);
let result = s.eval();
assert_eq!(format!("{result}"), "0");
}
#[test]
fn product_2_to_4() {
let ctx = Context::new();
let k = ctx.symbol("k");
let two = ctx.int(2);
let four = ctx.int(4);
let p = Ex::symbolic_product(&k, &k, &two, &four);
let result = p.eval();
assert_eq!(format!("{result}"), "24");
}
#[test]
fn product_squares_1_to_3() {
let ctx = Context::new();
let k = ctx.symbol("k");
let body = k.powi(2);
let one = ctx.int(1);
let three = ctx.int(3);
let p = Ex::symbolic_product(&body, &k, &one, &three);
let result = p.eval();
assert_eq!(format!("{result}"), "36");
}
#[test]
fn product_empty_range_is_one() {
let ctx = Context::new();
let k = ctx.symbol("k");
let five = ctx.int(5);
let one = ctx.int(1);
let p = Ex::symbolic_product(&k, &k, &five, &one);
let result = p.eval();
assert_eq!(format!("{result}"), "1");
}
#[test]
fn tree_roundtrip_floor() {
let ctx = Context::new();
let x = ctx.symbol("x");
let fl = x.floor();
let tree = fl.to_tree();
let json = serde_json::to_string(&tree).unwrap();
let tree2: symplex::tree::ExprTree = serde_json::from_str(&json).unwrap();
assert_eq!(tree, tree2);
}
#[test]
fn tree_roundtrip_min_max() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let m = x.min_with(&y);
let tree = m.to_tree();
let json = serde_json::to_string(&tree).unwrap();
let tree2: symplex::tree::ExprTree = serde_json::from_str(&json).unwrap();
assert_eq!(tree, tree2);
}