use refprop::{Fluid, FluidApi, UnitSystem};
fn density_at(f: &impl FluidApi, t: f64, p: f64) -> f64 {
f.get("D", "T", t, "P", p).unwrap()
}
fn critical_temp(f: &dyn FluidApi) -> f64 {
f.critical_point().unwrap().temperature
}
#[test]
fn generic_get_with_fluid() {
let fluid = Fluid::with_units("R134A", UnitSystem::engineering()).unwrap();
let d = density_at(&fluid, 25.0, 10.0);
assert!(d > 0.0, "density should be positive, got {d:.4}");
}
#[test]
fn dyn_dispatch_with_fluid() {
let fluid = Fluid::with_units("R134A", UnitSystem::engineering()).unwrap();
let tc = critical_temp(&fluid);
assert!(
(tc - 101.06).abs() < 1.0,
"R134A Tc ≈ 101 °C via dyn FluidApi, got {tc:.4}"
);
}
fn exercise_all_methods(f: &impl FluidApi) {
let d = f.get("D", "T", 25.0, "P", 5.0).unwrap();
assert!(d > 0.0);
let tp = f.props_tp(25.0, 5.0).unwrap();
assert!(tp.temperature > 24.0 && tp.temperature < 26.0);
let ph = f.props_ph(5.0, tp.enthalpy).unwrap();
assert!((ph.temperature - 25.0).abs() < 0.5);
let ps = f.props_ps(5.0, tp.entropy).unwrap();
assert!((ps.temperature - 25.0).abs() < 0.5);
let td = f.props_td(25.0, tp.density).unwrap();
assert!((td.pressure - 5.0).abs() < 0.1);
let th = f.props_th(25.0, tp.enthalpy).unwrap();
assert!((th.pressure - 5.0).abs() < 0.1);
let ts = f.props_ts(25.0, tp.entropy).unwrap();
assert!((ts.pressure - 5.0).abs() < 0.1);
let pd = f.props_pd(5.0, tp.density).unwrap();
assert!((pd.temperature - 25.0).abs() < 0.5);
let dh = f.props_dh(tp.density, tp.enthalpy).unwrap();
assert!((dh.temperature - 25.0).abs() < 0.5);
let ds = f.props_ds(tp.density, tp.entropy).unwrap();
assert!((ds.temperature - 25.0).abs() < 0.5);
let hs = f.props_hs(tp.enthalpy, tp.entropy).unwrap();
assert!((hs.temperature - 25.0).abs() < 0.5);
let tq = f.props_tq(0.0, 0.0).unwrap();
assert!(tq.quality.abs() < 1.0);
let pq = f.props_pq(tq.pressure, 100.0).unwrap();
assert!((pq.quality - 100.0).abs() < 1.0);
let sat_t = f.saturation_t(0.0).unwrap();
assert!(sat_t.pressure > 0.0);
assert!(sat_t.density_liquid > sat_t.density_vapor);
let sat_p = f.saturation_p(sat_t.pressure).unwrap();
assert!((sat_p.temperature - 0.0).abs() < 0.5);
let trn = f.transport(25.0, tp.density).unwrap();
assert!(trn.viscosity > 0.0, "viscosity must be positive");
assert!(
trn.thermal_conductivity > 0.0,
"thermal conductivity must be positive"
);
let crit = f.critical_point().unwrap();
assert!(crit.pressure > 0.0);
assert!(crit.density > 0.0);
let info = f.info().unwrap();
assert!(info.molar_mass > 0.0);
assert!(info.gas_constant > 8.0 && info.gas_constant < 8.5);
let _conv = f.converter();
}
#[test]
fn fluid_api_all_methods() {
let fluid = Fluid::with_units("R134A", UnitSystem::engineering()).unwrap();
exercise_all_methods(&fluid);
}
#[test]
fn fluid_api_is_object_safe() {
let fluid = Fluid::with_units("R134A", UnitSystem::engineering()).unwrap();
let boxed: Box<dyn FluidApi> = Box::new(fluid);
let d = boxed.get("D", "T", 25.0, "P", 5.0).unwrap();
assert!(d > 0.0);
let sat = boxed.saturation_t(0.0).unwrap();
assert!(sat.pressure > 0.0);
}
#[test]
fn trait_and_inherent_give_same_result() {
let fluid = Fluid::with_units("R134A", UnitSystem::engineering()).unwrap();
let d_direct = fluid.get("D", "T", 25.0, "P", 5.0).unwrap();
let d_trait = FluidApi::get(&fluid, "D", "T", 25.0, "P", 5.0).unwrap();
assert!(
(d_direct - d_trait).abs() < 1e-10,
"Inherent ({d_direct}) and trait ({d_trait}) should be identical"
);
}