diff --git a/crates/wickra-core/src/indicators/aroon_oscillator.rs b/crates/wickra-core/src/indicators/aroon_oscillator.rs index c5f360d0..56d586ff 100644 --- a/crates/wickra-core/src/indicators/aroon_oscillator.rs +++ b/crates/wickra-core/src/indicators/aroon_oscillator.rs @@ -107,6 +107,21 @@ mod tests { assert!(AroonOscillator::new(0).is_err()); } + /// Cover the const accessors `period` / `value` (57-64) and the + /// Indicator-impl `name` body (90-92). `warmup_period` is covered + /// already by `warmup_period_matches_aroon`. + #[test] + fn accessors_and_metadata() { + let mut osc = AroonOscillator::new(7).unwrap(); + assert_eq!(osc.period(), 7); + assert_eq!(osc.name(), "AroonOscillator"); + assert_eq!(osc.value(), None); + for i in 0..8 { + osc.update(candle(100.0 + f64::from(i), 90.0, 95.0, i64::from(i))); + } + assert!(osc.value().is_some()); + } + #[test] fn pure_uptrend_yields_plus_100() { // Every bar a fresh high, no fresh low: AroonUp = 100, AroonDown = 0. diff --git a/crates/wickra-core/src/indicators/atr.rs b/crates/wickra-core/src/indicators/atr.rs index e9267f6c..da61f37e 100644 --- a/crates/wickra-core/src/indicators/atr.rs +++ b/crates/wickra-core/src/indicators/atr.rs @@ -151,6 +151,21 @@ mod tests { assert!(matches!(Atr::new(0), Err(Error::PeriodZero))); } + /// Cover the const accessors `period` / `value` (54-62) and the + /// Indicator-impl `name` body (103-105). Existing tests inspect + /// numeric ATR output but never query the metadata. + #[test] + fn accessors_and_metadata() { + let mut atr = Atr::new(14).unwrap(); + assert_eq!(atr.period(), 14); + assert_eq!(atr.name(), "ATR"); + assert_eq!(atr.value(), None); + for _ in 0..14 { + atr.update(c(11.0, 9.0, 10.0)); + } + assert!(atr.value().is_some()); + } + #[test] fn warmup_emits_on_period_th_candle() { let candles = vec![ diff --git a/crates/wickra-core/src/indicators/awesome_oscillator.rs b/crates/wickra-core/src/indicators/awesome_oscillator.rs index 0fce501f..5d02b656 100644 --- a/crates/wickra-core/src/indicators/awesome_oscillator.rs +++ b/crates/wickra-core/src/indicators/awesome_oscillator.rs @@ -118,6 +118,17 @@ mod tests { assert!(AwesomeOscillator::new(0, 5).is_err()); } + /// Cover the const accessor `periods` (59-61) and the Indicator-impl + /// `warmup_period` (83-85) + `name` (91-93). Existing tests never + /// inspect these metadata methods. + #[test] + fn accessors_and_metadata() { + let ao = AwesomeOscillator::classic(); + assert_eq!(ao.periods(), (5, 34)); + assert_eq!(ao.warmup_period(), 34); + assert_eq!(ao.name(), "AwesomeOscillator"); + } + #[test] fn batch_equals_streaming() { let candles: Vec = (0..50) diff --git a/crates/wickra-core/src/indicators/cci.rs b/crates/wickra-core/src/indicators/cci.rs index adc70a51..05a843cf 100644 --- a/crates/wickra-core/src/indicators/cci.rs +++ b/crates/wickra-core/src/indicators/cci.rs @@ -138,6 +138,17 @@ mod tests { assert!(Cci::with_factor(20, -1.0).is_err()); } + /// Cover the const accessor `period` (68-70) and the Indicator-impl + /// `warmup_period` (102-104) + `name` (110-112). Existing tests never + /// inspect these metadata methods. + #[test] + fn accessors_and_metadata() { + let cci = Cci::new(20).unwrap(); + assert_eq!(cci.period(), 20); + assert_eq!(cci.warmup_period(), 20); + assert_eq!(cci.name(), "CCI"); + } + #[test] fn batch_equals_streaming() { let candles: Vec = (0..60) diff --git a/crates/wickra-core/src/indicators/wma.rs b/crates/wickra-core/src/indicators/wma.rs index 1a696f0e..6cb10429 100644 --- a/crates/wickra-core/src/indicators/wma.rs +++ b/crates/wickra-core/src/indicators/wma.rs @@ -154,6 +154,17 @@ mod tests { assert!(matches!(Wma::new(0), Err(Error::PeriodZero))); } + /// Cover the const accessor `period` (56-58) and the Indicator-impl + /// `warmup_period` (111-113) + `name` (119-121). Existing tests never + /// inspect these metadata methods. + #[test] + fn accessors_and_metadata() { + let wma = Wma::new(7).unwrap(); + assert_eq!(wma.period(), 7); + assert_eq!(wma.warmup_period(), 7); + assert_eq!(wma.name(), "WMA"); + } + #[test] fn warmup_returns_none() { let mut wma = Wma::new(3).unwrap(); @@ -179,11 +190,11 @@ mod tests { let mut wma = Wma::new(7).unwrap(); let got = wma.batch(&prices); let want = wma_naive(&prices, 7); - for (g, w) in got.iter().zip(want.iter()) { - match (g, w) { - (None, None) => {} - (Some(a), Some(b)) => assert_relative_eq!(*a, *b, epsilon = 1e-9), - _ => panic!("warmup mismatch"), + for (i, (g, w)) in got.iter().zip(want.iter()).enumerate() { + // Same warmup — emission shape must agree at every index. + assert_eq!(g.is_some(), w.is_some(), "warmup mismatch at index {i}"); + if let (Some(a), Some(b)) = (g, w) { + assert_relative_eq!(*a, *b, epsilon = 1e-9); } } }