use arbitrary::*;
use contrafact::{facts::*, utils::random_generator, *};
#[derive(Arbitrary, Debug, Clone, PartialEq, Eq, std::hash::Hash)]
enum Color {
Cyan,
Magenta,
Yellow,
Black,
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct Link {
prev: u32,
author: String,
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct Wrapper {
color: Color,
link: Link,
}
fn chain_fact<'a>(author: String) -> impl Fact<'a, Link> {
facts![
lens1("Link::author", |o: &mut Link| &mut o.author, eq(author),),
lens1(
"Link::prev",
|o: &mut Link| &mut o.prev,
consecutive_int("increasing prev", 0),
),
]
}
fn wrapper_fact<'a>(author: String, valid_colors: &'a [Color]) -> impl Fact<'a, Wrapper> {
facts![
lens1(
"Wrapper::color",
|o: &mut Wrapper| &mut o.color,
in_slice("valid color", valid_colors),
),
lens1(
"Wrapper::link",
|o: &mut Wrapper| &mut o.link,
chain_fact(author),
),
]
}
#[test]
fn test_link() {
observability::test_run().ok();
let mut g = random_generator();
const NUM: u32 = 10;
let author = "alice".to_string();
let fact = move || vec_of_length(NUM as usize, chain_fact(author.clone()));
let chain = fact().build(&mut g);
dbg!(&chain);
fact().check(&chain).unwrap();
assert!(chain.iter().all(|c| c.author == "alice"));
assert_eq!(chain.iter().last().unwrap().prev, NUM - 1);
}
#[test]
fn test_wrapper() {
observability::test_run().ok();
let mut g = random_generator();
const NUM: u32 = 10;
let author = "alice".to_string();
let fact = move || {
vec_of_length(
NUM as usize,
wrapper_fact(author.clone(), &[Color::Cyan, Color::Magenta]),
)
};
let chain = fact().build(&mut g);
dbg!(&chain);
fact().check(&chain).unwrap();
assert!(chain.iter().all(|c| c.link.author == "alice"));
assert!(chain.iter().all(|c| c.color != Color::Black));
assert_eq!(chain.iter().last().unwrap().link.prev, NUM - 1);
assert!(chain.iter().any(|c| c.color == Color::Magenta));
}