fix(ml): replace std::process::exit with Result propagation in temporal_guard tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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<TimeSeriesData, Box<dyn std::error::Error>> {
|
||||
let prices: Vec<f64> = (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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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<dyn std::error::Error>> {
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user