#![allow(dead_code)]
use proptest::prelude::*;
use proptest::strategy::BoxedStrategy;
pub fn arb_truncated(source: String) -> BoxedStrategy<String> {
let len = source.len();
if len <= 1 {
return Just(String::new()).boxed();
}
(1..len)
.prop_map(move |pos| {
let mut boundary = pos;
while boundary > 0 && !source.is_char_boundary(boundary) {
boundary -= 1;
}
source[..boundary].to_string()
})
.boxed()
}
pub fn arb_delimiter_swap(source: String) -> BoxedStrategy<String> {
prop_oneof![
Just(source.replace('{', "[")),
Just(source.replace('}', "]")),
Just(source.replace('(', "{")),
Just(source.replace(')', "}")),
Just(source.replace('{', "(")),
]
.prop_filter("mutation must change the source", {
let original = source.clone();
move |mutated| mutated != &original
})
.boxed()
}
pub fn arb_garbage_insertion(source: String) -> BoxedStrategy<String> {
let len = source.len();
if len == 0 {
return Just("@@@GARBAGE@@@".to_string()).boxed();
}
let garbage_options = vec![
"???".to_string(),
"@@@".to_string(),
"~~~".to_string(),
"!!!".to_string(),
"<<<>>>".to_string(),
];
(0..len, prop::sample::select(garbage_options))
.prop_map(move |(pos, garbage)| {
let mut boundary = pos;
while boundary > 0 && !source.is_char_boundary(boundary) {
boundary -= 1;
}
let mut result = source[..boundary].to_string();
result.push_str(&garbage);
result.push_str(&source[boundary..]);
result
})
.boxed()
}
pub fn arb_reserved_fragment_name() -> BoxedStrategy<String> {
Just("fragment on on SomeType { field }".to_string()).boxed()
}