rig_core/test_utils/
observations.rs1use crate::observe::{Action, Observation, ObservationTrace, Reason};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct Divergence {
10 pub index: usize,
13 pub expected: Option<Observation>,
15 pub actual: Option<Observation>,
17}
18
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21#[serde(tag = "comparison", rename_all = "snake_case")]
22pub enum Comparison {
23 Equal,
25 Diverged(Divergence),
27 Incomparable {
29 reason: Reason,
31 },
32}
33
34pub fn compare(expected: &ObservationTrace, actual: &ObservationTrace) -> Comparison {
39 if !expected.is_complete() {
40 return Comparison::Incomparable {
41 reason: Reason::with_detail(
42 "incomplete_expected",
43 format!("the expected trace dropped {} facts", expected.dropped),
44 ),
45 };
46 }
47 if !actual.is_complete() {
48 return Comparison::Incomparable {
49 reason: Reason::with_detail(
50 "incomplete_actual",
51 format!("the actual trace dropped {} facts", actual.dropped),
52 ),
53 };
54 }
55 let semantic = |observation: &Observation| {
56 let mut observation = observation.clone();
57 observation.at = None;
58 if let Action::Adapter { observation } = &mut observation.action {
59 observation.analysis = None;
60 }
61 observation
62 };
63 let longest = expected.observations.len().max(actual.observations.len());
64 for index in 0..longest {
65 let left = expected.observations.get(index).map(semantic);
66 let right = actual.observations.get(index).map(semantic);
67 if left != right {
68 return Comparison::Diverged(Divergence {
69 index,
70 expected: left,
71 actual: right,
72 });
73 }
74 }
75 Comparison::Equal
76}