use pretty_assertions::assert_eq;
use crate::{
Parser,
parser::{FailureSite, Recovery, Repair, Site},
tests::{corpus::corpus, recovery::Canonical}
};
#[derive(Debug, Default)]
struct Decline<'src>
{
sites: Vec<FailureSite<'src>>
}
impl<'src> Recovery<'src> for Decline<'src>
{
fn repair(&mut self, site: &FailureSite<'src>) -> Repair
{
self.sites.push(site.clone());
Repair::Stop
}
}
#[test]
fn test_declining_recovery_matches_parse()
{
for input in corpus()
{
let expected = Parser::parse(input);
let mut policy = Decline::default();
let actual = Parser::parse_recovering(input, &mut policy);
assert_eq!(actual, expected, "input: {:?}", input);
match expected
{
Ok(_) => assert_eq!(policy.sites, vec![], "input: {:?}", input),
Err(error) =>
{
let position = error.errors[0].0.location_offset();
let leading = error
.errors
.iter()
.take_while(|(span, _)| span.location_offset() == position)
.cloned()
.collect::<Vec<_>>();
assert_eq!(policy.sites.len(), 1, "input: {:?}", input);
assert_eq!(
policy.sites[0].error.errors, leading,
"input: {:?}",
input
);
}
}
}
}
#[test]
fn test_canonical_recovery_matches_edited_parse()
{
for input in corpus()
{
let mut policy = Canonical::new(input);
match Parser::parse_recovering(input, &mut policy)
{
Ok(recovered) =>
{
let corrected = policy.corrected();
let parsed = Parser::parse(&corrected).unwrap_or_else(|e| {
panic!(
"input {:?} corrected to {:?}, which fails: {}",
input, corrected, e
)
});
assert_eq!(
recovered.to_string(),
parsed.to_string(),
"input {:?} corrected to {:?}",
input,
corrected
);
},
Err(_) => assert!(
matches!(
policy.sites.last(),
Some(FailureSite {
site: Site::LeadingComma,
..
})
),
"input {:?} failed to recover at {:?}",
input,
policy.sites.last()
)
}
}
}