use crate::{CapabilityId, Config, Reason, Row};
use std::collections::BTreeMap;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum Verdict {
Exact,
EquallyCorrectButDifferent,
Wrong,
Missing,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Controls {
pub positive_passed: bool,
pub known_bad_failed: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ControlsNotRun(pub Controls);
impl fmt::Display for ControlsNotRun {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"an exact result is not recorded as on without both controls (positive passed: {}, known-bad failed: {})",
self.0.positive_passed, self.0.known_bad_failed
)
}
}
impl std::error::Error for ControlsNotRun {}
impl Verdict {
pub fn into_row(
self,
subject: CapabilityId,
backend: impl Into<String>,
version: impl Into<String>,
config: Config,
metadata: Config,
controls: Controls,
) -> Result<Row, ControlsNotRun> {
let (enabled, reason, note) = match self {
Verdict::Exact => {
if !(controls.positive_passed && controls.known_bad_failed) {
return Err(ControlsNotRun(controls));
}
(true, None, "")
}
Verdict::EquallyCorrectButDifferent => (
false,
Some(Reason::Wrong),
"equally correct but different: widen the test only if stricter than the contract, else mint a leaf",
),
Verdict::Wrong => (false, Some(Reason::Wrong), ""),
Verdict::Missing => (false, Some(Reason::Missing), ""),
};
Ok(Row {
subject_kind: "capability".to_string(),
subject,
backend: backend.into(),
version: version.into(),
config,
enabled,
reason,
metadata,
note: note.to_string(),
extra: BTreeMap::new(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
fn row(v: Verdict, c: Controls) -> Result<Row, ControlsNotRun> {
v.into_row(
CapabilityId::new("kv.put_if_absent").unwrap(),
"sqlite",
"3.46",
Config::new(),
Config::new().with("test", "kv::put_if_absent_race"),
c,
)
}
const BOTH: Controls = Controls {
positive_passed: true,
known_bad_failed: true,
};
#[test]
fn exact_is_on_only_with_both_controls() {
let r = row(Verdict::Exact, BOTH).unwrap();
assert!(r.enabled && r.reason.is_none());
let no_known_bad = Controls {
known_bad_failed: false,
..BOTH
};
assert_eq!(
row(Verdict::Exact, no_known_bad),
Err(ControlsNotRun(no_known_bad))
);
let no_positive = Controls {
positive_passed: false,
..BOTH
};
assert!(row(Verdict::Exact, no_positive).is_err());
}
#[test]
fn everything_else_is_off_with_the_right_reason_and_needs_no_controls() {
let none = Controls {
positive_passed: false,
known_bad_failed: false,
};
assert_eq!(
row(Verdict::Wrong, none).unwrap().reason,
Some(Reason::Wrong)
);
assert_eq!(
row(Verdict::Missing, none).unwrap().reason,
Some(Reason::Missing)
);
let e = row(Verdict::EquallyCorrectButDifferent, none).unwrap();
assert!(!e.enabled && e.reason == Some(Reason::Wrong) && e.note.contains("mint a leaf"));
}
}