use proptest::prelude::*;
use sloop::flow::StageKind;
use crate::support::splice;
const SEED: &str = "stages:\n - name: build\n kind: agent\n verdict: reported\n - name: test\n kind: exec\n cmd: [cargo, test]\n on_fail:\n agent: fix the tests\n attempts: 2\n - name: merge\n kind: merge\n";
proptest! {
#[test]
fn arbitrary_text_never_panics(contents in prop_oneof![
".*",
r#"[-a-z0-9\[\]{}:,&*#?|>'" \n]*"#,
(1..400usize).prop_map(|depth| "[".repeat(depth)),
(1..200usize).prop_map(|depth| "a:\n".repeat(depth)),
]) {
if let Ok(flow) = sloop::flow::parse("fuzz", &contents) {
let names: std::collections::HashSet<_> =
flow.stages.iter().map(|stage| &stage.name).collect();
prop_assert_eq!(names.len(), flow.stages.len());
prop_assert_eq!(flow.stages.first().map(|s| &s.kind), Some(&StageKind::Agent));
for stage in &flow.stages[..flow.stages.len() - 1] {
prop_assert!(stage.kind != StageKind::Merge, "merge stage must be last");
}
}
}
#[test]
fn damaged_valid_files_never_panic(
position in 0..SEED.len(),
replaced in 0..24usize,
injected in prop_oneof![".{0,16}", r#"[-\[\]{}:,&*#?|>'" ]{0,8}"#],
) {
let contents = splice(SEED, position, replaced, &injected);
let _ = sloop::flow::parse("fuzz", &contents);
}
}