use symplex::prelude::*;
#[test]
fn formal_diff_creates_node() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let dy = y.formal_diff(&x);
let s = format!("{dy}");
assert!(s != "0", "formal_diff should not evaluate: {s}");
}
#[test]
fn formal_diff_in_expression() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let dy = y.formal_diff(&x);
let expr = &dy + &y; let s = format!("{expr}");
assert!(s.contains("y"), "should contain y: {s}");
}
#[test]
fn formal_diff_via_expr_macro() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let dy = expr!(ctx, diff(y, x));
let s = format!("{dy}");
assert!(s != "0", "expr!(ctx, diff(y,x)) should not evaluate: {s}");
}
#[test]
fn dsolve_simple_separable() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let dy = y.formal_diff(&x);
let ode = &dy - &x; let sol = ode
.try_solve_ode(&y, &x)
.expect("dsolve should handle y' - x = 0");
let s = format!("{sol}");
assert!(s.contains("C1"), "should have constant: {s}");
assert!(s.contains("x"), "should contain x: {s}");
}
#[test]
fn dsolve_exponential_decay() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let dy = y.formal_diff(&x);
let ode = &dy + &(&y * 2); let sol = ode
.try_solve_ode(&y, &x)
.expect("dsolve should handle y' + 2y = 0");
let s = format!("{sol}");
assert!(s.contains("exp"), "should contain exp: {s}");
assert!(s.contains("C1"), "should have constant: {s}");
}
#[test]
fn dsolve_via_expr_macro() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let ode = expr!(ctx, diff(y, x) + 2 * y); let sol = ode
.try_solve_ode(&y, &x)
.expect("dsolve should handle y' + 2y = 0 via expr macro");
let s = format!("{sol}");
assert!(s.contains("exp") || s.contains("C1"), "solution: {s}");
}
#[test]
fn dsolve_dy_equals_zero() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let ode = y.formal_diff(&x); let sol = ode
.try_solve_ode(&y, &x)
.expect("dsolve should handle y' = 0");
let s = format!("{sol}");
assert!(s.contains("C1"), "should be constant: {s}");
}
#[test]
fn factorial_via_method() {
let ctx = Context::new();
let result = ctx.int(5).factorial().eval();
assert_eq!(format!("{result}"), "120");
}
#[test]
fn factorial_100_via_method() {
let ctx = Context::new();
let result = ctx.int(100).factorial().eval();
let s = format!("{result}");
assert!(
s.starts_with("933262154"),
"100! starts wrong: {}",
&s[..20]
);
assert_eq!(s.len(), 158, "100! should have 158 digits");
}
#[test]
fn binomial_via_method() {
let ctx = Context::new();
let result = ctx.int(10).binomial(&ctx.int(3)).eval();
assert_eq!(format!("{result}"), "120");
}
#[test]
fn factorial_via_expr_macro() {
let ctx = Context::new();
let result = expr!(ctx, factorial(5)).eval();
assert_eq!(format!("{result}"), "120");
}
#[test]
fn binomial_via_expr_macro() {
let ctx = Context::new();
let result = expr!(ctx, C(10, 3)).eval();
assert_eq!(format!("{result}"), "120");
}
#[test]
fn binomial_via_binomial_name() {
let ctx = Context::new();
let result = expr!(ctx, binomial(10, 5)).eval();
assert_eq!(format!("{result}"), "252");
}
#[test]
fn neg_infinity_exists() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
assert_eq!(format!("{neg_inf}"), "-oo");
}
#[test]
fn limit_at_neg_infinity() {
let ctx = Context::new();
let x = ctx.symbol("x");
let result = (1 / &x).limit(&x, &ctx.neg_infinity());
assert_eq!(format!("{result}"), "0");
}
#[test]
fn ode_via_eq_macro() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let ode = expr!(ctx, diff(y, x) + y);
let sol = ode
.try_solve_ode(&y, &x)
.expect("dsolve should handle y' + y = 0");
let s = format!("{sol}");
assert!(s.contains("exp") || s.contains("C1"), "ODE solution: {s}");
}
#[test]
fn factorial_in_expression() {
let ctx = Context::new();
let n = ctx.symbol("n");
let expr = n.factorial();
let s = format!("{expr}");
assert!(s.contains("!"), "should display as n!: {s}");
}
#[test]
fn binomial_display() {
let ctx = Context::new();
let n = ctx.symbol("n");
let k = ctx.symbol("k");
let expr = n.binomial(&k);
let s = format!("{expr}");
assert!(
s.contains("C(") || s.contains("n") && s.contains("k"),
"got: {s}"
);
}