#![allow(clippy::unwrap_used)]
use pretty_lang::Doc;
use proptest::prelude::*;
const WIDE: usize = 1_000_000;
fn arb_doc_and_flat() -> impl Strategy<Value = (Doc, String)> {
let leaf = prop_oneof![
Just((Doc::nil(), String::new())),
"[a-z0-9]{0,6}".prop_map(|s| (Doc::text(s.clone()), s)),
Just((Doc::line(), String::from(" "))),
Just((Doc::softline(), String::new())),
];
leaf.prop_recursive(6, 128, 4, |inner| {
prop_oneof![
(inner.clone(), inner.clone()).prop_map(|((a, fa), (b, fb))| (a.append(b), fa + &fb)),
(-4isize..8, inner.clone()).prop_map(|(n, (d, f))| (d.nest(n), f)),
inner.prop_map(|(d, f)| (d.group(), f)),
]
})
}
fn arb_doc() -> impl Strategy<Value = Doc> {
let leaf = prop_oneof![
Just(Doc::nil()),
"[a-z0-9]{0,6}".prop_map(Doc::text),
Just(Doc::line()),
Just(Doc::softline()),
Just(Doc::hardline()),
];
leaf.prop_recursive(6, 128, 4, |inner| {
prop_oneof![
(inner.clone(), inner.clone()).prop_map(|(a, b)| a.append(b)),
(-4isize..8, inner.clone()).prop_map(|(n, d)| d.nest(n)),
inner.prop_map(Doc::group),
]
})
}
proptest! {
#[test]
fn prop_grouped_wide_equals_flat_oracle((doc, flat) in arb_doc_and_flat()) {
prop_assert_eq!(doc.group().render(WIDE), flat);
}
#[test]
fn prop_grouped_wide_has_no_newline((doc, _flat) in arb_doc_and_flat()) {
prop_assert!(!doc.group().render(WIDE).contains('\n'));
}
#[test]
fn prop_render_never_panics(doc in arb_doc(), width in 0usize..120) {
let _ = doc.render(width);
}
#[test]
fn prop_render_into_matches_render(doc in arb_doc(), width in 0usize..120) {
let mut buf = String::new();
doc.render_into(width, &mut buf).unwrap();
prop_assert_eq!(buf, doc.render(width));
}
#[test]
fn prop_group_is_idempotent(doc in arb_doc(), width in 0usize..80) {
let once = doc.clone().group().render(width);
let twice = doc.group().group().render(width);
prop_assert_eq!(once, twice);
}
#[test]
fn prop_append_is_associative(
a in arb_doc(), b in arb_doc(), c in arb_doc(), width in 0usize..80
) {
let left = a.clone().append(b.clone()).append(c.clone()).render(width);
let right = a.append(b.append(c)).render(width);
prop_assert_eq!(left, right);
}
}