cubek_test_utils/test_mode/
result.rs

1//! Kernel Test Workflow
2//!
3//! 1. **Execution**  
4//!    - Kernel runs or fails to compile [`ExecutionOutcome`].
5//!      - `Executed`: ran (correctness not checked).  
6//!      - `CompileError`: did not compile.
7//!
8//! 2. **Validation**  
9//!    - Check correctness of the executed kernel [`ValidationResult`].
10//!      - `Pass`: result matches reference.  
11//!      - `Fail`: result incorrect.  
12//!      - `Skipped`: could not decide.
13//!
14//! 3. **Test Outcome**  
15//!    - Combines execution + validation [`TestOutcome`].
16//!
17//! 4. **Policy Decision**  
18//!    - Applies test mode to decide if the test passes [`TestDecision`].
19//!      - `Accept`: test passes.  
20//!      - `Reject(String)`: test fails.  
21//!    - Call [`TestDecision::enforce`] to actually fail the test.
22
23use crate::current_test_mode;
24use std::fmt::Display;
25
26#[derive(Debug)]
27/// Whether a kernel was executed (without regard to correctness)
28/// or failed to compile.
29pub enum ExecutionOutcome {
30    /// The kernel was executed successfully (correctness not checked)
31    Executed,
32    /// The kernel could not compile
33    CompileError(String),
34}
35
36#[derive(Debug)]
37/// The result of correctness validation for a kernel execution.
38pub enum ValidationResult {
39    /// The kernel passed the correctness test
40    Pass,
41    /// The kernel failed the correctness test
42    Fail(String),
43    /// The correctness test could not determine pass/fail
44    Skipped(String),
45}
46
47#[derive(Debug)]
48/// The overall outcome of a test, combining execution and validation.
49/// Either the kernel was validated or failed to compile.
50pub enum TestOutcome {
51    /// The kernel was executed and validation was performed
52    Validated(ValidationResult),
53    /// The kernel could not compile
54    CompileError(String),
55}
56
57impl TestOutcome {
58    /// Apply the current test mode to this outcome and fail the test if rejected.
59    ///
60    /// This is a convenience wrapper around
61    /// `current_test_mode().decide(self).enforce()`.
62    ///
63    /// # Example
64    ///
65    /// ```ignore
66    /// let outcome = assert_equals_approx(&actual, &expected, 0.001).as_test_outcome();
67    /// outcome.enforce(); // panics if TestMode rejects it
68    /// ```
69    pub fn enforce(self) {
70        current_test_mode().decide(self).enforce();
71    }
72}
73
74#[derive(Debug)]
75/// The final policy-based verdict of a test, after applying the test mode.
76/// Determines whether the test should be considered passing or failing.
77pub enum TestDecision {
78    /// The test is accepted (passes)
79    Accept,
80    /// The test is rejected (fails)
81    Reject(String),
82}
83
84impl TestDecision {
85    /// Actually asserts the test according to the decision.
86    /// Panics if the test is rejected.
87    pub fn enforce(self) {
88        match self {
89            TestDecision::Accept => {}
90            TestDecision::Reject(reason) => panic!("Test failed: {}", reason),
91        }
92    }
93}
94
95impl ValidationResult {
96    /// Convert a `ValidationResult` into a `TestOutcome`.
97    pub fn as_test_outcome(self) -> TestOutcome {
98        TestOutcome::Validated(self)
99    }
100}
101
102impl<E: Display> From<Result<(), E>> for ExecutionOutcome {
103    fn from(result: Result<(), E>) -> Self {
104        match result {
105            Ok(_) => ExecutionOutcome::Executed,
106            Err(err) => ExecutionOutcome::CompileError(format!("Test did not run: {}", err)),
107        }
108    }
109}