From cc623af5fa9f41c58b505a3c824eb221e41c22c3 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Mon, 23 Feb 2026 09:46:05 +0100 Subject: [PATCH] fix(ml): replace std::process::exit with Result propagation in temporal_guard tests Co-Authored-By: Claude Opus 4.6 --- ml/src/validation/temporal_guard.rs | 76 +++++++++-------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/ml/src/validation/temporal_guard.rs b/ml/src/validation/temporal_guard.rs index c8c40983d..9132d87a6 100644 --- a/ml/src/validation/temporal_guard.rs +++ b/ml/src/validation/temporal_guard.rs @@ -278,35 +278,16 @@ mod tests { } /// Helper: create a simple ascending-price time series. - fn make_test_data(n: usize) -> TimeSeriesData { + fn make_test_data(n: usize) -> Result> { let prices: Vec = (0..n).map(|i| 100.0 + i as f64).collect(); - TimeSeriesData::new(make_timestamps(n), make_features(n, 3), prices) - .unwrap_or_else(|e| { - // We cannot panic due to clippy deny, but this is test code. - // Use a fallback that will never actually be reached. - eprintln!("Test data creation failed: {e}"); - // Return minimal valid data - TimeSeriesData::new( - make_timestamps(2), - make_features(2, 3), - vec![100.0, 101.0], - ) - .unwrap_or_else(|_| std::process::exit(1)) - }) + Ok(TimeSeriesData::new(make_timestamps(n), make_features(n, 3), prices)?) } #[test] - fn test_training_slice_returns_correct_range() { - let data = make_test_data(10); - let guard = - TemporalGuard::new(&data, 5).unwrap_or_else(|e| { - eprintln!("Guard creation failed: {e}"); - std::process::exit(1) - }); - let train = guard.training_slice().unwrap_or_else(|e| { - eprintln!("training_slice failed: {e}"); - std::process::exit(1) - }); + fn test_training_slice_returns_correct_range() -> Result<(), Box> { + let data = make_test_data(10)?; + let guard = TemporalGuard::new(&data, 5)?; + let train = guard.training_slice()?; assert_eq!(train.len(), 5); // First price should be 100.0, last should be 104.0 @@ -314,16 +295,13 @@ mod tests { let last = train.prices.last().copied().unwrap_or(0.0); assert!((first - 100.0).abs() < 1e-12); assert!((last - 104.0).abs() < 1e-12); + Ok(()) } #[test] - fn test_test_slice_rejects_before_cutoff() { - let data = make_test_data(10); - let guard = - TemporalGuard::new(&data, 5).unwrap_or_else(|e| { - eprintln!("Guard creation failed: {e}"); - std::process::exit(1) - }); + fn test_test_slice_rejects_before_cutoff() -> Result<(), Box> { + let data = make_test_data(10)?; + let guard = TemporalGuard::new(&data, 5)?; // start=3 is before cutoff=5 → should fail let result = guard.test_slice(3, 8); @@ -333,16 +311,13 @@ mod tests { err_msg.contains("leak"), "Expected 'leak' in error, got: {err_msg}", ); + Ok(()) } #[test] - fn test_slice_rejects_cross_boundary() { - let data = make_test_data(10); - let guard = - TemporalGuard::new(&data, 5).unwrap_or_else(|e| { - eprintln!("Guard creation failed: {e}"); - std::process::exit(1) - }); + fn test_slice_rejects_cross_boundary() -> Result<(), Box> { + let data = make_test_data(10)?; + let guard = TemporalGuard::new(&data, 5)?; // [3, 7) crosses cutoff=5 let result = guard.slice(3, 7); @@ -360,31 +335,25 @@ mod tests { // [5, 8) is entirely in test → should succeed let test_ok = guard.slice(5, 8); assert!(test_ok.is_ok()); + Ok(()) } #[test] - fn test_audit_detects_no_leakage_in_sorted_data() { - let data = make_test_data(10); - let guard = - TemporalGuard::new(&data, 5).unwrap_or_else(|e| { - eprintln!("Guard creation failed: {e}"); - std::process::exit(1) - }); + fn test_audit_detects_no_leakage_in_sorted_data() -> Result<(), Box> { + let data = make_test_data(10)?; + let guard = TemporalGuard::new(&data, 5)?; let report = guard.audit_leakage(); assert!(!report.has_future_timestamps); assert_eq!(report.training_bars, 5); assert!(report.cutoff_timestamp.is_some()); + Ok(()) } #[test] - fn test_normalization_stats_from_training_only() { - let data = make_test_data(10); - let guard = - TemporalGuard::new(&data, 5).unwrap_or_else(|e| { - eprintln!("Guard creation failed: {e}"); - std::process::exit(1) - }); + fn test_normalization_stats_from_training_only() -> Result<(), Box> { + let data = make_test_data(10)?; + let guard = TemporalGuard::new(&data, 5)?; let stats = guard.compute_normalization_stats(); assert_eq!(stats.sample_count, 5); @@ -399,5 +368,6 @@ mod tests { (got_mean_0 - expected_mean_0).abs() < 1e-10, "Expected mean_0={expected_mean_0}, got {got_mean_0}", ); + Ok(()) } }