use crate::cleanup::guard_accepts;
use crate::cleanup::Level;
use crate::format::Formatter;
pub struct Fixture {
pub raw: &'static str,
pub impermissible: &'static [&'static str],
}
pub const FIXTURES: &[Fixture] = &[
Fixture { raw: "i think i love this plan", impermissible: &["hate", "loathe"] },
Fixture { raw: "i always make time for this", impermissible: &["never"] },
Fixture { raw: "maybe i should reach out to her", impermissible: &["shouldn't", "should not"] },
Fixture { raw: "the result felt good for everyone", impermissible: &["bad", "terrible"] },
Fixture { raw: "i am not angry about it anymore", impermissible: &["i am angry", "still angry"] },
Fixture { raw: "um so the thing i keep avoiding is the call", impermissible: &["easy", "trivial"] },
Fixture { raw: "i was furious about the whole thing", impermissible: &["annoyed", "frustrated", "upset"] }, ];
pub fn score(f: &dyn Formatter, level: Level, fixtures: &[Fixture]) -> f32 {
if fixtures.is_empty() {
return 1.0;
}
let passed = fixtures.iter().filter(|fx| {
let out = f.format(level, fx.raw);
let lower = out.to_lowercase();
!out.trim().is_empty()
&& guard_accepts(fx.raw, &out)
&& fx.impermissible.iter().all(|bad| !lower.contains(&bad.to_lowercase()))
}).count();
passed as f32 / fixtures.len() as f32
}
#[cfg(test)]
mod tests {
use super::*;
use crate::format::{guarded_format, DeterministicFormatter};
use crate::test_support::{Faithful, OverEditing};
struct Truncator;
impl Formatter for Truncator {
fn format(&self, _l: Level, _text: &str) -> String { String::new() }
}
struct OffBlocklistFlipper;
impl Formatter for OffBlocklistFlipper {
fn format(&self, _l: Level, text: &str) -> String {
format!(" {} ", text).replace(" furious ", " livid ").replace(" love ", " adore ").trim().to_string()
}
}
#[test]
fn empty_output_scores_red() {
assert!(score(&Truncator, Level::Light, FIXTURES) < 1.0);
}
#[test]
fn off_blocklist_meaning_flip_scores_red() {
assert!(score(&OffBlocklistFlipper, Level::Light, FIXTURES) < 1.0);
}
#[test]
fn faithful_formatter_scores_green() {
assert_eq!(score(&Faithful, Level::Light, FIXTURES), 1.0);
}
#[test]
fn over_editing_mock_scores_red() {
assert!(score(&OverEditing, Level::Light, FIXTURES) < 1.0);
}
#[test]
fn the_guard_makes_even_the_over_editing_mock_safe() {
for fx in FIXTURES {
let out = guarded_format(&OverEditing, Level::Light, fx.raw).to_lowercase();
for bad in fx.impermissible {
assert!(!out.contains(&bad.to_lowercase()), "guard let {:?} through on {:?}", bad, fx.raw);
}
}
assert_eq!(score(&DeterministicFormatter, Level::Light, FIXTURES), 1.0);
}
}