use super::super::*;
use crate::types::Value;
fn approx(a: Value, b: f64, tol: f64) -> bool {
if let Value::Number(n) = a { (n - b).abs() < tol } else { false }
}
#[test]
fn negative_pv_gives_positive_payment() {
let args = [Value::Number(0.1), Value::Number(5.0), Value::Number(-1000.0)];
let result = pmt_fn(&args);
assert!(matches!(result, Value::Number(n) if n > 0.0));
}
#[test]
fn very_small_rate() {
let args = [Value::Number(1e-10), Value::Number(12.0), Value::Number(1200.0)];
let result = pmt_fn(&args);
assert!(approx(result, -100.0, 0.1));
}
#[test]
fn fv_defaults_to_zero() {
let args3 = [Value::Number(0.05), Value::Number(10.0), Value::Number(1000.0)];
let args4 = [Value::Number(0.05), Value::Number(10.0), Value::Number(1000.0), Value::Number(0.0)];
let r3 = pmt_fn(&args3);
let r4 = pmt_fn(&args4);
assert_eq!(r3, r4);
}
#[test]
fn denom_zero_returns_num() {
let args = [Value::Number(0.001), Value::Number(1000.0), Value::Number(1000.0)];
let result = pmt_fn(&args);
assert!(matches!(result, Value::Number(_)));
}
#[test]
fn rate_zero_pv_and_fv() {
let args = [
Value::Number(0.0),
Value::Number(5.0),
Value::Number(100.0),
Value::Number(50.0),
];
assert_eq!(pmt_fn(&args), Value::Number(-30.0));
}