use symplex::units::constants;
use symplex::units::*;
#[test]
fn e_mc_squared_symbolic_display() {
let ctx = symplex::prelude::Context::new();
let m = Mass::symbol(&ctx, "m");
let c = constants::speed_of_light(&ctx);
let e = Energy::from_ex(m.inner() * c.inner() * c.inner());
let display = format!("{}", e.inner());
assert!(
display.contains("c"),
"Should display symbolically with c: {display}"
);
}
#[test]
fn e_mc_squared_numerical() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
let m = Mass::constant(&ctx, 1);
let e = Energy::from_ex(m.inner() * c.inner() * c.inner());
let val = e.eval_f64().unwrap();
let expected = 299792458.0_f64.powi(2);
assert!(
(val - expected).abs() / expected < 1e-10,
"E = {val}, expected {expected}"
);
}
#[test]
fn photon_energy_e_equals_hf() {
let ctx = symplex::prelude::Context::new();
let h = constants::planck_constant(&ctx);
let h_qty: Qty<AngularMomentumDim> = h.into();
let f_qty: Qty<FrequencyDim> = Qty::from_ex(ctx.symbol("f"));
let e_qty = h_qty * f_qty;
let e: Energy = e_qty.into();
let display = format!("{}", e.inner());
assert!(display.contains("h"), "E=hf should contain h: {display}");
}
#[test]
fn thermal_energy_kb_t() {
let ctx = symplex::prelude::Context::new();
let kb = constants::boltzmann_constant(&ctx);
let t_qty = Qty::<TemperatureDim>::from_ex(ctx.symbol("T"));
let e_thermal = kb * t_qty;
let e: Energy = e_thermal.into();
let display = format!("{}", e.inner());
assert!(display.contains("k_B"), "should contain k_B: {display}");
}
#[test]
fn constant_derivative_is_zero() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
let h = constants::planck_constant(&ctx);
symplex::syms!(ctx; x);
let dc = c.inner().diff(&x);
let dh = h.inner().diff(&x);
assert!(
dc.is_zero().unwrap_or(false) || format!("{}", dc) == "0",
"d/dx(c) should be 0, got {dc}"
);
assert!(
dh.is_zero().unwrap_or(false) || format!("{}", dh) == "0",
"d/dx(h) should be 0, got {dh}"
);
}
#[test]
fn gravitational_force() {
let ctx = symplex::prelude::Context::new();
let g_const = constants::gravitational_constant(&ctx);
symplex::syms!(ctx; m1, m2, r);
let f_expr = g_const.inner() * &m1 * &m2 / &r.powi(2);
let display = format!("{}", f_expr);
assert!(
display.contains("G"),
"F=Gm1m2/r² should contain G: {display}"
);
}
#[test]
fn speed_of_light_value() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
let val = c.eval_f64().unwrap();
assert!(
(val - 299_792_458.0).abs() < 1.0,
"c should be 299792458 m/s, got {val}"
);
}
#[test]
fn planck_constant_value() {
let ctx = symplex::prelude::Context::new();
let h = constants::planck_constant(&ctx);
let val = h.eval_f64().unwrap();
let expected = 6.62607015e-34;
assert!(
(val - expected).abs() / expected < 1e-10,
"h should be ~6.626e-34, got {val}"
);
}
#[test]
fn boltzmann_constant_value() {
let ctx = symplex::prelude::Context::new();
let kb = constants::boltzmann_constant(&ctx);
let val = kb.eval_f64().unwrap();
let expected = 1.380649e-23;
assert!(
(val - expected).abs() / expected < 1e-10,
"k_B should be ~1.381e-23, got {val}"
);
}
#[test]
fn elementary_charge_value() {
let ctx = symplex::prelude::Context::new();
let e = constants::elementary_charge(&ctx);
let val = e.eval_f64().unwrap();
let expected = 1.602176634e-19;
assert!(
(val - expected).abs() / expected < 1e-10,
"e should be ~1.602e-19, got {val}"
);
}
#[test]
fn standard_gravity_value() {
let ctx = symplex::prelude::Context::new();
let g = constants::standard_gravity(&ctx);
let val = g.eval_f64().unwrap();
assert!(
(val - 9.80665).abs() < 1e-10,
"gā should be 9.80665, got {val}"
);
}
#[test]
fn avogadro_constant_value() {
let ctx = symplex::prelude::Context::new();
let na = constants::avogadro_constant(&ctx);
let val = na.eval_f64().unwrap();
let expected = 6.02214076e23;
assert!(
(val - expected).abs() / expected < 1e-10,
"N_A should be ~6.022e23, got {val}"
);
}
#[test]
fn constant_in_product_preserves_symbol() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
symplex::syms!(ctx; x);
let cx = c.inner() * &x;
let display = format!("{}", cx);
assert!(
display.contains("c"),
"c*x should display with c symbol: {display}"
);
}
#[test]
fn constant_survives_simplify() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
symplex::syms!(ctx; x, y);
let expr = c.inner() * &x + c.inner() * &y;
let simplified = expr.simplify();
let display = format!("{}", simplified);
assert!(
display.contains("c"),
"simplify should preserve c: {display}"
);
}
#[test]
fn constant_diff_in_product() {
let ctx = symplex::prelude::Context::new();
let c = constants::speed_of_light(&ctx);
symplex::syms!(ctx; x);
let cx = c.inner() * &x;
let d = cx.diff(&x);
let display = format!("{}", d);
assert!(
display.contains("c"),
"d/dx(c*x) should contain c: {display}"
);
}
#[test]
fn multiple_constants_in_expression() {
let ctx = symplex::prelude::Context::new();
let h = constants::planck_constant(&ctx);
let c = constants::speed_of_light(&ctx);
let product = h.inner() * c.inner();
let display = format!("{}", product);
assert!(
display.contains("h") && display.contains("c"),
"h*c should contain both symbols: {display}"
);
}
#[test]
fn gravitational_constant_value() {
let ctx = symplex::prelude::Context::new();
let g = constants::gravitational_constant(&ctx);
let val = g.eval_f64().unwrap();
let expected = 6.67430e-11;
assert!(
(val - expected).abs() / expected < 1e-4,
"G should be ~6.674e-11, got {val}"
);
}