From adc84889391e7fe6523060d5b02d3a3f37be2f44 Mon Sep 17 00:00:00 2001 From: kingchenc Date: Sun, 24 May 2026 00:48:35 +0200 Subject: [PATCH] test: 100% coverage for ema + historical_volatility + kama + linreg_angle + mass_index (#24) * test(ema): cover period accessor + warmup/name metadata Codecov flagged 9 lines in crates/wickra-core/src/indicators/ema.rs (file at 94.03%): const accessor period (74-77), Indicator-impl warmup_period (123-125), name (131-133). ema.rs now at 151/151. * test(historical_volatility): cover periods/value accessors + name metadata Codecov flagged 9 lines in crates/wickra-core/src/indicators/historical_volatility.rs (file at 93.87%): const accessors periods (80-83), value (85-88) and Indicator-impl name (153-155). historical_volatility.rs now at 147/147. * test(kama): cover periods accessor + warmup/name metadata Codecov flagged 9 lines in crates/wickra-core/src/indicators/kama.rs (file at 91.26%): accessor periods (65-67), Indicator-impl warmup_period (115-117), name (123-125). kama.rs now at 103/103. * test(linreg_angle): cover period accessor + warmup/name metadata Codecov flagged 9 lines in crates/wickra-core/src/indicators/linreg_angle.rs (file at 88.15%): const accessor period (50-52), Indicator-impl warmup_period (67-69), name (75-77). linreg_angle.rs now at 76/76. * test(mass_index): cover periods/value accessors + name metadata Codecov flagged 9 lines in crates/wickra-core/src/indicators/mass_index.rs (file at 91.42%): const accessors periods (80-82), value (85-87) and Indicator-impl name (134-136). mass_index.rs now at 105/105. --- crates/wickra-core/src/indicators/ema.rs | 12 ++++++++++++ .../src/indicators/historical_volatility.rs | 15 +++++++++++++++ crates/wickra-core/src/indicators/kama.rs | 14 ++++++++++++++ crates/wickra-core/src/indicators/linreg_angle.rs | 11 +++++++++++ crates/wickra-core/src/indicators/mass_index.rs | 15 +++++++++++++++ 5 files changed, 67 insertions(+) diff --git a/crates/wickra-core/src/indicators/ema.rs b/crates/wickra-core/src/indicators/ema.rs index ace731ee..bcbcde4d 100644 --- a/crates/wickra-core/src/indicators/ema.rs +++ b/crates/wickra-core/src/indicators/ema.rs @@ -165,6 +165,18 @@ mod tests { assert!(matches!(Ema::new(0), Err(Error::PeriodZero))); } + /// Cover the const accessor `period` (74-77) and the Indicator-impl + /// `warmup_period` (123-125) + `name` (131-133). `alpha` and `value` + /// are exercised by other tests and downstream consumers; only the + /// three metadata methods were dead. + #[test] + fn accessors_and_metadata() { + let ema = Ema::new(14).unwrap(); + assert_eq!(ema.period(), 14); + assert_eq!(ema.warmup_period(), 14); + assert_eq!(ema.name(), "EMA"); + } + #[test] fn warmup_returns_none_until_seed() { let mut ema = Ema::new(3).unwrap(); diff --git a/crates/wickra-core/src/indicators/historical_volatility.rs b/crates/wickra-core/src/indicators/historical_volatility.rs index 7b97b3c8..3563c066 100644 --- a/crates/wickra-core/src/indicators/historical_volatility.rs +++ b/crates/wickra-core/src/indicators/historical_volatility.rs @@ -173,6 +173,21 @@ mod tests { )); } + /// Cover the const accessors `periods` / `value` (80-88) and the + /// Indicator-impl `name` body (153-155). Existing tests inspect HV + /// output but never query the metadata. + #[test] + fn accessors_and_metadata() { + let mut hv = HistoricalVolatility::new(20, 252).unwrap(); + assert_eq!(hv.periods(), (20, 252)); + assert_eq!(hv.name(), "HistoricalVolatility"); + assert_eq!(hv.value(), None); + for i in 1..=hv.warmup_period() { + hv.update(100.0 + f64::from(u32::try_from(i).unwrap())); + } + assert!(hv.value().is_some()); + } + #[test] fn new_rejects_period_one() { assert!(matches!( diff --git a/crates/wickra-core/src/indicators/kama.rs b/crates/wickra-core/src/indicators/kama.rs index a10740cd..5ddb3ca4 100644 --- a/crates/wickra-core/src/indicators/kama.rs +++ b/crates/wickra-core/src/indicators/kama.rs @@ -131,6 +131,20 @@ mod tests { use crate::traits::BatchExt; use approx::assert_relative_eq; + /// Cover the `periods` accessor (65-67) and the Indicator-impl + /// `warmup_period` (115-117) + `name` (123-125). Existing tests + /// inspect KAMA output but never query the metadata. + #[test] + fn accessors_and_metadata() { + let k = Kama::classic(); + let (er, fast, slow) = k.periods(); + assert_eq!(er, 10); + assert!((fast - 2.0 / (2.0 + 1.0)).abs() < 1e-12); + assert!((slow - 2.0 / (30.0 + 1.0)).abs() < 1e-12); + assert_eq!(k.warmup_period(), 11); + assert_eq!(k.name(), "KAMA"); + } + #[test] fn constant_series_yields_constant_kama() { let mut k = Kama::classic(); diff --git a/crates/wickra-core/src/indicators/linreg_angle.rs b/crates/wickra-core/src/indicators/linreg_angle.rs index 6198c197..a4a032a7 100644 --- a/crates/wickra-core/src/indicators/linreg_angle.rs +++ b/crates/wickra-core/src/indicators/linreg_angle.rs @@ -138,6 +138,17 @@ mod tests { assert!(LinRegAngle::new(2).is_ok()); } + /// Cover the const accessor `period` (50-52) and the Indicator-impl + /// `warmup_period` (67-69) + `name` (75-77). Existing tests inspect + /// angle output but never query the metadata. + #[test] + fn accessors_and_metadata() { + let a = LinRegAngle::new(14).unwrap(); + assert_eq!(a.period(), 14); + assert_eq!(a.warmup_period(), 14); + assert_eq!(a.name(), "LinRegAngle"); + } + #[test] fn reset_clears_state() { let mut angle = LinRegAngle::new(5).unwrap(); diff --git a/crates/wickra-core/src/indicators/mass_index.rs b/crates/wickra-core/src/indicators/mass_index.rs index 5ffb32f6..a6a29605 100644 --- a/crates/wickra-core/src/indicators/mass_index.rs +++ b/crates/wickra-core/src/indicators/mass_index.rs @@ -153,6 +153,21 @@ mod tests { assert!(matches!(MassIndex::new(9, 0), Err(Error::PeriodZero))); } + /// Cover the const accessors `periods` / `value` (80-87) and the + /// Indicator-impl `name` body (134-136). `warmup_period` is already + /// covered by `warmup_period_formula`. + #[test] + fn accessors_and_metadata() { + let mut mi = MassIndex::new(9, 25).unwrap(); + assert_eq!(mi.periods(), (9, 25)); + assert_eq!(mi.name(), "MassIndex"); + assert_eq!(mi.value(), None); + for i in 0..mi.warmup_period() { + mi.update(candle(100.0, 2.0, i64::try_from(i).unwrap())); + } + assert!(mi.value().is_some()); + } + #[test] fn warmup_period_formula() { let mi = MassIndex::new(9, 25).unwrap();