persistant_blob/
contract.rs1use crate::BlobBackend;
10use crate::conformance::{Certified, Leaf, certify_leaves};
11use persistant_core::choose::{Eligibility, LeafFailure};
12use persistant_core::{Config, Reason};
13
14pub fn evaluate(rows: &[Certified], required: &[Leaf]) -> Eligibility {
16 let mut out: Vec<LeafFailure> = Vec::new();
17 for leaf in required.iter().copied() {
18 if out.iter().any(|e| e.leaf == leaf.id()) {
19 continue;
20 }
21 match rows.iter().find(|c| c.leaf == leaf) {
22 Some(c) if c.row.enabled => {}
23 Some(c) => out.push(LeafFailure {
24 leaf: leaf.id().to_string(),
25 reason: c.row.reason.unwrap_or(Reason::Untested),
26 note: c.row.note.clone(),
27 }),
28 None => out.push(LeafFailure {
29 leaf: leaf.id().to_string(),
30 reason: Reason::Untested,
31 note: "no test ran for this leaf".to_string(),
32 }),
33 }
34 }
35 if out.is_empty() {
36 Eligibility::Eligible
37 } else {
38 Eligibility::Excluded(out)
39 }
40}
41
42pub async fn check<B: BlobBackend>(target: &B, required: &[Leaf]) -> Eligibility {
44 let rows = certify_leaves(target, &Config::new(), &Config::new(), required).await;
45 evaluate(&rows, required)
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use crate::{Defect, MemoryBlob};
52
53 #[tokio::test]
54 async fn a_correct_backend_is_eligible() {
55 let leaves = [Leaf::Read, Leaf::Write, Leaf::CreateExclusive];
56 assert_eq!(
57 check(&MemoryBlob::new(), &leaves).await,
58 Eligibility::Eligible
59 );
60 }
61
62 #[tokio::test]
63 async fn a_defective_backend_is_excluded_as_wrong_and_the_control_passes() {
64 let r = check(
65 &MemoryBlob::with_defect(Defect::DeleteIsIgnored),
66 &[Leaf::Delete],
67 )
68 .await;
69 assert!(
70 matches!(&r, Eligibility::Excluded(ex) if ex[0].reason == Reason::Wrong && ex[0].leaf == "blob.delete"),
71 "{r:?}"
72 );
73 assert_eq!(
74 check(&MemoryBlob::new(), &[Leaf::Delete]).await,
75 Eligibility::Eligible
76 );
77 }
78
79 #[test]
80 fn a_required_leaf_with_no_row_is_untested_not_a_pass() {
81 let r = evaluate(&[], &[Leaf::Read]);
82 assert!(matches!(&r, Eligibility::Excluded(ex) if ex[0].reason == Reason::Untested));
83 assert_eq!(evaluate(&[], &[]), Eligibility::Eligible);
84 }
85}