use symplex::prelude::*;
#[test]
fn var_creates_symbol() {
let ctx = Context::new();
let x = ctx.symbol("x");
assert_eq!(format!("{x}"), "x");
}
#[test]
fn symbol_is_alias_for_var() {
let ctx = Context::new();
let x = ctx.symbol("x");
assert_eq!(format!("{x}"), "x");
}
#[test]
fn int_creates_integer() {
let ctx = Context::new();
let five = ctx.int(5);
assert_eq!(format!("{five}"), "5");
}
#[test]
fn rational_creates_fraction() {
let ctx = Context::new();
let half = ctx.rational(1, 2);
assert_eq!(format!("{half}"), "1/2");
}
#[test]
fn global_context_expressions_interoperate() {
let ctx = Context::new();
let x = ctx.symbol("x");
let expr = &x.powi(2) + &x + 1;
let s = format!("{expr}");
assert!(s.contains("x^2"), "should contain x^2: {s}");
assert!(s.contains("x"), "should contain x: {s}");
}
#[test]
fn global_context_diff_works() {
let ctx = Context::new();
let x = ctx.symbol("x");
let deriv = x.powi(3).diff(&x);
assert_eq!(format!("{deriv}"), "3*x^2");
}
#[test]
fn global_context_integrate_works() {
let ctx = Context::new();
let x = ctx.symbol("x");
let anti = x.powi(2).integrate(&x);
assert_eq!(format!("{anti}"), "1/3*x^3");
}
#[test]
fn vars_macro_creates_symbols() {
let ctx = Context::new();
symplex::syms!(ctx; a, b, c);
let expr = &a + &b + &c;
let s = format!("{expr}");
assert!(
s.contains("a") && s.contains("b") && s.contains("c"),
"should contain a, b, c: {s}"
);
}
#[test]
fn vars_macro_trailing_comma() {
let ctx = Context::new();
symplex::syms!(ctx; x, y,);
let expr = &x * &y;
assert_eq!(format!("{expr}"), "x*y");
}
#[test]
fn maclaurin_sin() {
let ctx = Context::new();
let x = ctx.symbol("x");
let s = x.sin().maclaurin(&x, 4);
let result = s.expand().eval();
let text = format!("{result}");
assert!(text.contains("x"), "should have x term: {text}");
assert!(text.contains("x^3"), "should have x^3 term: {text}");
}
#[test]
fn maclaurin_exp() {
let ctx = Context::new();
let x = ctx.symbol("x");
let s = x.exp().maclaurin(&x, 3);
let result = s.expand().eval();
let text = format!("{result}");
assert!(text.contains("1"), "should have constant term: {text}");
assert!(text.contains("x"), "should have x term: {text}");
assert!(text.contains("x^2"), "should have x^2 term: {text}");
}
#[test]
fn maclaurin_polynomial_is_exact() {
let ctx = Context::new();
let x = ctx.symbol("x");
let poly = &x.powi(2) + &x * 3 + 7;
let s = poly.maclaurin(&x, 5);
assert_eq!(format!("{s}"), format!("{poly}"));
}
#[test]
fn subs_i64_basic() {
let ctx = Context::new();
let x = ctx.symbol("x");
let expr = x.powi(2);
let result = expr.subs_i64(&x, 3);
assert_eq!(format!("{result}"), "9");
}
#[test]
fn subs_i64_in_polynomial() {
let ctx = Context::new();
let x = ctx.symbol("x");
let expr = &x.powi(2) + &x * 2 + 1;
let result = expr.subs_i64(&x, 3);
assert_eq!(format!("{result}"), "16");
}
#[test]
fn subs_i64_zero() {
let ctx = Context::new();
let x = ctx.symbol("x");
let expr = &x.powi(2) + 1;
let result = expr.subs_i64(&x, 0);
assert_eq!(format!("{result}"), "1");
}
#[test]
fn subs_i64_negative() {
let ctx = Context::new();
let x = ctx.symbol("x");
let expr = &x + 5;
let result = expr.subs_i64(&x, -3);
assert_eq!(format!("{result}"), "2");
}
#[test]
fn display_inverse_as_fraction() {
let ctx = Context::new();
let x = ctx.symbol("x");
let result = x.powi(-1);
assert_eq!(format!("{result}"), "1/x");
}
#[test]
fn display_division_uses_fraction() {
let ctx = Context::new();
let x = ctx.symbol("x");
let y = ctx.symbol("y");
let result = &x / &y;
let s = format!("{result}");
assert!(s == "x/y", "should display as x/y: {s}");
}
#[test]
fn display_negative_coeff_as_subtraction() {
let ctx = Context::new();
let x = ctx.symbol("x");
let term1 = x.clone();
let term2 = &x.powi(3) * &ctx.rational(-1, 6);
let expr = &term1 + &term2;
let s = format!("{expr}");
assert!(!s.contains("+ -"), "should not have '+ -' pattern: {s}");
}