#![allow(clippy::unwrap_used, clippy::expect_used)]
use driver_lang::{DriverError, Pipeline, Session, Severity, Stage};
use proptest::prelude::*;
fn severity_strategy() -> impl Strategy<Value = Severity> {
prop_oneof![
Just(Severity::Error),
Just(Severity::Warning),
Just(Severity::Note),
]
}
proptest! {
#[test]
fn prop_error_count_tracks_error_emissions(severities in prop::collection::vec(severity_strategy(), 0..64)) {
let expected_errors = severities.iter().filter(|s| s.is_error()).count();
let mut session = Session::new(());
for &severity in &severities {
match severity {
Severity::Error => { session.error("e"); }
Severity::Warning => { session.warn("w"); }
Severity::Note => { session.note("n"); }
}
}
prop_assert_eq!(session.error_count(), expected_errors);
prop_assert_eq!(session.diagnostics().len(), severities.len());
prop_assert_eq!(session.has_errors(), expected_errors > 0);
prop_assert_eq!(session.abort_if_errors().is_err(), expected_errors > 0);
}
#[test]
fn prop_take_diagnostics_drains_all_and_resets(errors in 0usize..32, warnings in 0usize..32) {
let mut session = Session::new(());
for _ in 0..errors { session.error("e"); }
for _ in 0..warnings { session.warn("w"); }
let drained = session.take_diagnostics();
prop_assert_eq!(drained.len(), errors + warnings);
prop_assert_eq!(session.diagnostics().len(), 0);
prop_assert_eq!(session.error_count(), 0);
prop_assert!(!session.has_errors());
}
}
struct Double;
impl Stage<()> for Double {
type Input = Vec<i64>;
type Output = Vec<i64>;
fn name(&self) -> &'static str {
"double"
}
fn run(&mut self, input: Vec<i64>, _s: &mut Session<()>) -> Result<Vec<i64>, DriverError> {
Ok(input.into_iter().map(|x| x * 2).collect())
}
}
struct Sum;
impl Stage<()> for Sum {
type Input = Vec<i64>;
type Output = i64;
fn name(&self) -> &'static str {
"sum"
}
fn run(&mut self, input: Vec<i64>, _s: &mut Session<()>) -> Result<i64, DriverError> {
Ok(input.iter().sum())
}
}
proptest! {
#[test]
fn prop_pipeline_matches_manual_composition(values in prop::collection::vec(any::<i32>(), 0..256)) {
let widened: Vec<i64> = values.iter().map(|&v| v as i64).collect();
let expected: i64 = widened.iter().map(|&v| v * 2).sum();
let mut driver = Pipeline::new(Double).then(Sum);
let mut session = Session::new(());
let got = driver.run(widened, &mut session).unwrap();
prop_assert_eq!(got, expected);
prop_assert!(session.diagnostics().is_empty());
}
}