#![allow(
clippy::indexing_slicing,
clippy::panic,
clippy::unwrap_used,
reason = "test code with known-structure parsed data"
)]
use crate::{json, warning};
use super::{edits, Edit, Error, Fixable};
#[derive(Debug)]
struct Removable;
impl crate::Warning for Removable {
fn id(&self) -> warning::Id {
warning::Id::from_static("removable")
}
}
impl std::fmt::Display for Removable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("This element can be removed.")
}
}
impl super::sealed::Sealed for Removable {}
impl Fixable for Removable {
fn fix(&self, element: &json::Element<'_>) -> Option<Edit> {
Some(Edit::remove(element.id()))
}
}
#[derive(Debug)]
struct Unfixable;
impl crate::Warning for Unfixable {
fn id(&self) -> warning::Id {
warning::Id::from_static("unfixable")
}
}
impl std::fmt::Display for Unfixable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("This element needs a human.")
}
}
impl super::sealed::Sealed for Unfixable {}
impl Fixable for Unfixable {
fn fix(&self, _element: &json::Element<'_>) -> Option<Edit> {
None
}
}
fn field(doc: &json::Document<'_>, key: &str) -> json::ElemId {
doc.root().find_field(key).unwrap().element().id()
}
#[test]
fn an_empty_warning_set_proposes_no_edits() {
let doc = json::parse_object(r#"{"a": 1}"#).unwrap();
let warnings = warning::Set::<Removable>::new();
assert_eq!(edits(&doc, &warnings), Ok(Vec::new()));
}
#[test]
fn a_warning_that_resolves_to_nothing_proposes_no_edits() {
let doc = json::parse_object(r#"{"a": 1}"#).unwrap();
let mut warnings = warning::Set::<Unfixable>::new();
warnings.insert(doc.root().find_field("a").unwrap().element(), Unfixable);
assert_eq!(edits(&doc, &warnings), Ok(Vec::new()));
}
#[test]
fn edits_come_back_in_document_order() {
let doc = json::parse_object(r#"{"a": 1, "b": 2, "c": 3}"#).unwrap();
let mut warnings = warning::Set::<Removable>::new();
warnings.insert(doc.root().find_field("c").unwrap().element(), Removable);
warnings.insert(doc.root().find_field("a").unwrap().element(), Removable);
assert_eq!(
edits(&doc, &warnings),
Ok(vec![
Edit::remove(field(&doc, "a")),
Edit::remove(field(&doc, "c")),
])
);
}
#[test]
fn each_warning_on_an_element_is_asked_for_an_edit() {
let doc = json::parse_object(r#"{"a": 1}"#).unwrap();
let mut warnings = warning::Set::<Removable>::new();
let element = doc.root().find_field("a").unwrap().element();
warnings.insert(element, Removable);
warnings.insert(element, Removable);
assert_eq!(
edits(&doc, &warnings),
Ok(vec![Edit::remove(element.id()), Edit::remove(element.id()),])
);
}
#[test]
fn a_warning_from_another_document_is_reported() {
let other = json::parse_object(r#"{"a": 1, "b": 2, "c": 3, "d": 4}"#).unwrap();
let doc = json::parse_object(r#"{"a": 1}"#).unwrap();
let mut warnings = warning::Set::<Removable>::new();
let stranger = other.root().find_field("d").unwrap().element();
warnings.insert(stranger, Removable);
assert_eq!(
edits(&doc, &warnings),
Err(Error::UnknownElement(stranger.id()))
);
}