runifold-testkit 0.5.4

Deterministic runtime testing and Agent quality evaluation for Runifold
Documentation
use super::{EvaluationCaseResult, EvaluationError, EvaluationFailureStage};

pub(super) fn ensure_not_empty(field: &'static str, value: &str) -> Result<(), EvaluationError> {
    if value.trim().is_empty() {
        return Err(EvaluationError::EmptyField { field });
    }
    Ok(())
}

pub(super) fn validate_case_metrics(case: &EvaluationCaseResult) -> Result<(), EvaluationError> {
    if case.metrics.is_some()
        && case
            .failures
            .iter()
            .any(|failure| failure.stage == EvaluationFailureStage::Target)
    {
        return Err(EvaluationError::InconsistentReport {
            message: "target failure cannot contain successful execution metrics",
        });
    }
    if let Some(metrics) = &case.metrics {
        metrics.validate()?;
    }
    Ok(())
}

pub(super) fn ensure_ratio(field: &'static str, value: f64) -> Result<(), EvaluationError> {
    if !value.is_finite() || !(0.0..=1.0).contains(&value) {
        return Err(EvaluationError::InvalidRatio { field, value });
    }
    Ok(())
}

pub(super) fn ensure_non_negative(field: &'static str, value: f64) -> Result<(), EvaluationError> {
    if !value.is_finite() || value < 0.0 {
        return Err(EvaluationError::InvalidMetric { field, value });
    }
    Ok(())
}

pub(super) fn ensure_close(
    actual: f64,
    expected: f64,
    message: &'static str,
) -> Result<(), EvaluationError> {
    const REPORT_RATIO_TOLERANCE: f64 = 1e-12;
    if (actual - expected).abs() > REPORT_RATIO_TOLERANCE {
        return Err(EvaluationError::InconsistentReport { message });
    }
    Ok(())
}