use crate::engine;
use crate::resolve::{Context, Options};
use crate::types::{DimensionKind, Entity, Rule};
type ExampleCheck = Box<dyn Fn(&Entity) -> bool>;
pub struct Corpus {
pub context: Context,
pub examples: Vec<(Vec<String>, ExampleCheck)>,
}
impl Corpus {
pub fn new(context: Context) -> Self {
Corpus {
context,
examples: Vec::new(),
}
}
pub fn add<F>(&mut self, texts: Vec<&str>, check: F)
where
F: Fn(&Entity) -> bool + 'static,
{
let texts: Vec<String> = texts.into_iter().map(String::from).collect();
self.examples.push((texts, Box::new(check)));
}
}
pub fn check_corpus(corpus: &Corpus, rules: &[Rule], dims: &[DimensionKind]) -> Vec<String> {
let options = Options { with_latent: false };
let mut failures = Vec::new();
for (texts, check) in &corpus.examples {
for text in texts {
let entities = engine::parse_and_resolve(text, rules, &corpus.context, &options, dims);
let any_match = entities.iter().any(check);
if !any_match {
let dim_str = dims
.iter()
.map(|d| format!("{:?}", d))
.collect::<Vec<_>>()
.join(", ");
failures.push(format!(
"FAIL: \"{}\" - expected match for [{}], got {} entities: {:?}",
text,
dim_str,
entities.len(),
entities
.iter()
.map(|e| format!("{}({:?})", e.value.dim_kind(), e.value))
.collect::<Vec<_>>()
));
}
}
}
failures
}