use crate::snapshot::{Snapshot, SnapshotContents, TextSnapshotKind};
pub trait Comparator: Send + Sync + 'static {
fn matches(&self, reference: &Snapshot, test: &Snapshot) -> bool;
fn matches_fully(&self, reference: &Snapshot, test: &Snapshot) -> bool {
self.matches(reference, test)
}
fn dyn_clone(&self) -> Box<dyn Comparator>;
}
#[derive(Clone)]
pub struct DefaultComparator;
impl Comparator for DefaultComparator {
fn matches(&self, reference: &Snapshot, test: &Snapshot) -> bool {
reference.contents() == test.contents()
&& reference.metadata().snapshot_kind == test.metadata().snapshot_kind
}
fn matches_fully(&self, reference: &Snapshot, test: &Snapshot) -> bool {
match (reference.contents(), test.contents()) {
(SnapshotContents::Text(ref_contents), SnapshotContents::Text(test_contents)) => {
let contents_match_exact = ref_contents.matches_latest(test_contents);
match ref_contents.kind {
TextSnapshotKind::File => {
reference.metadata().trim_for_persistence()
== test.metadata().trim_for_persistence()
&& contents_match_exact
}
TextSnapshotKind::Inline => contents_match_exact,
}
}
_ => self.matches(reference, test),
}
}
fn dyn_clone(&self) -> Box<dyn Comparator> {
Box::new(self.clone())
}
}
#[cfg(test)]
mod test {
use super::DefaultComparator;
use crate::comparator::Comparator;
use crate::snapshot::{
MetaData, Snapshot, SnapshotContents, TextSnapshotContents, TextSnapshotKind,
};
const TEXT: &str =
"The sky above the port was the color of a television, tuned to a dead channel.";
#[test]
fn default_comparator_matches() {
let comparator = DefaultComparator;
let a = Snapshot::from_components(
String::from("test"),
None,
MetaData::default(),
SnapshotContents::Text(TextSnapshotContents::new(
String::from(TEXT),
TextSnapshotKind::Inline,
)),
);
let b = a.clone();
assert!(comparator.matches(&a, &b));
assert!(comparator.matches_fully(&a, &b));
}
#[test]
fn default_comparator_matches_fully() {
let comparator = DefaultComparator;
let a = Snapshot::from_components(
String::from("test"),
None,
MetaData::default(),
SnapshotContents::Text(TextSnapshotContents::new(
String::from(TEXT),
TextSnapshotKind::File,
)),
);
let mut b = Snapshot::from_components(
String::from("test"),
None,
MetaData::default(),
SnapshotContents::Text(TextSnapshotContents::new(
String::from(TEXT),
TextSnapshotKind::Inline,
)),
);
b.metadata.description = Some(String::from("wintermute"));
assert!(comparator.matches(&a, &b));
assert!(comparator.matches_fully(&a, &a));
assert!(!comparator.matches_fully(&a, &b));
}
}