#![warn(clippy::shadow_unrelated)]
#![allow(clippy::derive_partial_eq_without_eq)]
mod test_helpers;
use proptest::{
arbitrary::{any, any_with, Arbitrary},
collection::size_range,
prop_oneof,
strategy::{Just, LazyJust, Strategy},
};
use std::fmt::Debug;
use test_helpers::*;
use test_strategy::Arbitrary;
#[test]
fn unit_struct() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct;
assert_arbitrary(LazyJust::new(|| TestStruct));
}
#[test]
fn tuple_struct_no_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct();
assert_arbitrary(LazyJust::new(TestStruct));
}
#[test]
fn struct_no_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {}
assert_arbitrary(LazyJust::new(|| TestStruct {}));
}
#[test]
fn struct_no_attr_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
x: u16,
}
assert_arbitrary(any::<u16>().prop_map(|x| TestStruct { x }));
}
#[test]
fn struct_no_attr_field_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
x: u16,
y: u8,
}
assert_arbitrary((any::<u16>(), any::<u8>()).prop_map(|(x, y)| TestStruct { x, y }));
}
#[test]
fn struct_field_raw_ident() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
r#x: u16,
}
assert_arbitrary(any::<u16>().prop_map(|x| TestStruct { x }));
}
#[test]
fn struct_field_raw_keyword_ident() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
r#fn: u16,
}
assert_arbitrary(any::<u16>().prop_map(|r#fn| TestStruct { r#fn }));
}
#[test]
fn struct_over_12_field() {
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
a0: u32,
a1: u32,
a2: u32,
a3: u32,
a4: u32,
a5: u32,
a6: u32,
a7: u32,
a8: u32,
a9: u32,
a10: u32,
a11: u32,
a12: u32,
}
}
#[test]
fn tuple_struct_no_attr_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct(u16);
assert_arbitrary(any::<u16>().prop_map(TestStruct));
}
#[test]
fn tuple_struct_no_attr_field_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct(u16, u8);
assert_arbitrary((any::<u16>(), any::<u8>()).prop_map(|(x, y)| TestStruct(x, y)));
}
#[test]
fn strategy_struct() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..16u16)]
x: u16,
}
assert_arbitrary((1..16u16).prop_map(|x| TestStruct { x }));
}
#[test]
fn strategy_struct_field_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..16u16)]
x: u16,
#[strategy(10..20u8)]
y: u8,
}
assert_arbitrary((1..16u16, 10..20u8).prop_map(|(x, y)| TestStruct { x, y }));
}
#[test]
fn strategy_rank2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
x: u32,
#[strategy(0..#x)]
y: u32,
}
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_map(|(y, x)| TestStruct { x, y }),
);
}
#[test]
fn strategy_rank3() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
x: u32,
#[strategy(0..#x)]
y: u32,
#[strategy(0..#y*2+1)]
z: u32,
}
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_flat_map(|(y, x)| (0..y * 2 + 1, Just(x), Just(y)))
.prop_map(|(z, x, y)| TestStruct { x, y, z }),
);
}
#[test]
fn tuple_struct_strategy() {
#[derive(Arbitrary, Debug, PartialEq)]
struct X(#[strategy(1..10u32)] u32);
assert_arbitrary((1..10u32).prop_map(X));
}
#[test]
fn strategy_underline() {
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..16u16)]
_x: u16,
}
}
#[test]
fn strategy_rev() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(0..#x)]
y: u32,
#[strategy(1..10u32)]
x: u32,
}
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_map(|(y, x)| TestStruct { x, y }),
);
}
#[test]
fn strategy_tuple_struct() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct(#[strategy(1..10u32)] u32, #[strategy(0..#0)] u32);
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_map(|(y, x)| TestStruct(x, y)),
);
}
#[test]
fn strategy_multiple_dependency() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(0..10)]
x: i32,
#[strategy(0..20)]
y: i32,
#[strategy(0..#x*#y+1)]
z: i32,
}
assert_arbitrary(
(0..10, 0..20)
.prop_flat_map(|(x, y)| (0..x * y + 1, Just(x), Just(y)))
.prop_map(|(z, x, y)| TestStruct { x, y, z }),
);
}
#[test]
fn strategy_cross_dependency() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(0..10)]
a: i32,
#[strategy(0..20)]
b: i32,
#[strategy(0..30)]
c: i32,
#[strategy(0..#a * #b + 1)]
x: i32,
#[strategy(0..#b + #c + 10)]
y: i32,
}
assert_arbitrary(
(0..10, 0..20, 0..30)
.prop_flat_map(|(a, b, c)| (0..a * b + 1, 0..b + c + 10, Just(a), Just(b), Just(c)))
.prop_map(|(x, y, a, b, c)| TestStruct { a, b, c, x, y }),
);
}
#[test]
fn strategy_by_ref() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[by_ref]
#[strategy(1..10u32)]
x: u32,
#[strategy(0..*#x)]
y: u32,
}
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_map(|(y, x)| TestStruct { x, y }),
);
}
#[test]
fn strategy_raw_keyword_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
r#fn: u32,
}
assert_arbitrary((1..10u32).prop_map(|r#fn| TestStruct { r#fn }));
}
#[test]
fn strategy_raw_keyword_sharp_val() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
r#fn: u32,
#[strategy(0..#fn)]
y: u32,
}
assert_arbitrary(
(1..10u32)
.prop_flat_map(|x| (0..x, Just(x)))
.prop_map(|(y, r#fn)| TestStruct { r#fn, y }),
);
}
#[test]
fn any_struct_field() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[any]
x: u16,
}
assert_arbitrary(any::<u16>().prop_map(|x| TestStruct { x }));
}
#[test]
fn any_with_args_expr() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[any(size_range(0..16).lift())]
x: Vec<u16>,
}
assert_arbitrary(any_with::<Vec<u16>>(size_range(0..16).lift()).prop_map(|x| TestStruct { x }));
}
mod sub_mod {
#[allow(dead_code)]
#[derive(Default)]
pub struct TestArgsNoConstruct {
a: u32,
}
impl TestArgsNoConstruct {
pub fn new() -> Self {
Self { a: 0 }
}
}
}
#[test]
fn any_with_args_expr_private_constructor() {
#[allow(dead_code)]
#[derive(Arbitrary, Debug)]
#[arbitrary(args = sub_mod::TestArgsNoConstruct)]
struct Inner {
#[allow(dead_code)]
x: u32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug)]
struct TestInput {
#[any(sub_mod::TestArgsNoConstruct::new())]
#[allow(dead_code)]
inner: Inner,
}
}
#[test]
fn any_with_args_struct_field() {
#[derive(Default)]
struct TestArgs {
a_max: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct Inner {
#[strategy(0..args.a_max)]
a: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
struct Outer {
#[any(a_max = 50)]
inner: Inner,
}
assert_arbitrary((0..50).prop_map(|a| Outer { inner: Inner { a } }));
}
#[test]
fn any_with_args_enum_field() {
#[derive(Default)]
struct TestArgs {
a_max: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
enum Inner {
A {
#[strategy(0..args.a_max)]
a: i32,
},
}
#[derive(Arbitrary, Debug, PartialEq)]
struct Outer {
#[any(a_max = 50)]
inner: Inner,
}
assert_arbitrary((0..50).prop_map(|a| Outer {
inner: Inner::A { a },
}));
}
#[test]
fn any_with_args_field_x2() {
#[derive(Default)]
struct TestArgs {
a_max1: i32,
a_max2: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct Inner {
#[strategy(0..args.a_max1 + args.a_max2)]
a: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
struct Outer {
#[any(a_max1 = 50, a_max2 = 10)]
inner: Inner,
}
assert_arbitrary((0..60).prop_map(|a| Outer { inner: Inner { a } }));
}
#[test]
fn any_with_args_expr_field() {
#[derive(Default)]
struct TestArgs {
a_max1: i32,
a_max2: i32,
}
impl TestArgs {
fn new() -> Self {
Self {
a_max1: 10,
a_max2: 20,
}
}
}
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct Inner {
#[strategy(0..args.a_max1 + args.a_max2)]
a: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
struct Outer {
#[any(TestArgs::new(), a_max2 = 30)]
inner: Inner,
}
assert_arbitrary((0..40).prop_map(|a| Outer { inner: Inner { a } }));
}
#[test]
fn any_with_keyword() {
#[derive(Default)]
struct TestArgs {
r#fn: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct Inner {
#[strategy(0..args.r#fn)]
a: i32,
}
#[derive(Arbitrary, Debug, PartialEq)]
struct Outer {
#[any(fn = 50)]
inner: Inner,
}
assert_arbitrary((0..50).prop_map(|a| Outer { inner: Inner { a } }));
}
#[test]
fn enum_unit_variant_1() {
#[derive(Arbitrary, Debug, PartialEq)]
enum TestEnum {
X,
}
assert_arbitrary(LazyJust::new(|| TestEnum::X));
}
#[test]
fn enum_unit_variant_2() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
enum TestEnum {
X,
Y,
}
assert_arbitrary(prop_oneof![Just(TestEnum::X), Just(TestEnum::Y)]);
}
#[test]
fn enum_weight() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
enum TestEnum {
#[weight(1)]
X,
#[weight(2)]
Y,
}
assert_arbitrary(prop_oneof![1=>Just(TestEnum::X), 2=>Just(TestEnum::Y)]);
}
#[test]
fn enum_weight_0() {
#[derive(Debug, PartialEq, Clone)]
struct NotArbitrary;
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq, Clone)]
enum TestEnum {
X,
#[weight(0)]
Y(NotArbitrary),
}
assert_arbitrary(Just(TestEnum::X));
}
#[test]
fn filter_struct_field_fn() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
#[filter(is_even)]
x: u32,
}
fn is_even(value: &u32) -> bool {
value % 2 == 0
}
assert_arbitrary(
(1..10u32)
.prop_filter("is_even", is_even)
.prop_map(|x| TestStruct { x }),
);
}
#[test]
fn filter_struct_field_2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
#[filter(is_even)]
x: u32,
#[strategy(1..10u32)]
#[filter(is_odd)]
y: u32,
}
fn is_even(value: &u32) -> bool {
value % 2 == 0
}
fn is_odd(value: &u32) -> bool {
value % 2 != 0
}
assert_arbitrary(
(
(1..10u32).prop_filter("is_even", is_even),
(1..10u32).prop_filter("is_odd", is_odd),
)
.prop_map(|(x, y)| TestStruct { x, y }),
);
}
#[test]
fn filter_struct_filed_independent_and_dependent() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(0..10u32)]
#[filter(|x| x % 3 == 0)]
a: u32,
#[strategy(0..10u32)]
#[filter(|x| x % 3 == 1)]
b: u32,
#[strategy(0..=#b)]
#[filter(|x| x % 3 == 2)]
c: u32,
}
let a = (0..10u32).prop_filter("", |&a| a % 3 == 0);
let bc = (0..10u32)
.prop_filter("", |&b| b % 3 == 1)
.prop_flat_map(|b| (Just(b), (0..=b)))
.prop_filter("", |(_b, c)| c % 3 == 2);
let abc = (a, bc).prop_map(|(a, (b, c))| TestStruct { a, b, c });
assert_arbitrary(abc);
}
#[test]
fn filter_struct_field_fn_dependency() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
a: u32,
#[filter(is_larger_than(#a))]
b: u32,
}
fn is_larger_than(t: u32) -> impl Fn(&u32) -> bool {
move |&value| value > t
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("is_larger_than(a)", |&(a, b)| is_larger_than(a)(&b))
.prop_map(|(a, b)| TestStruct { a, b }),
);
}
#[test]
fn filter_struct_field_fn_dependency_closure() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
a: u32,
#[filter(|&b| b > #a)]
b: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("b > a", |&(a, b)| b > a)
.prop_map(|(a, b)| TestStruct { a, b }),
);
}
#[test]
fn filter_struct_field_sharp_val() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
#[filter(is_even(&#x))]
x: u32,
}
fn is_even(value: &u32) -> bool {
value % 2 == 0
}
assert_arbitrary(
(1..10u32)
.prop_filter("is_even", is_even)
.prop_map(|x| TestStruct { x }),
);
}
#[test]
fn filter_tuple_struct_field_sharp_val() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct(
#[strategy(1..10u32)]
#[filter(is_even(�))]
u32,
);
fn is_even(value: &u32) -> bool {
value % 2 == 0
}
assert_arbitrary(
(1..10u32)
.prop_filter("is_even", is_even)
.prop_map(TestStruct),
);
}
#[test]
fn filter_struct_field_closure() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
#[filter(|val| val % 2 == 0)]
x: u32,
}
assert_arbitrary(
(1..10u32)
.prop_filter("is_even", |val| val % 2 == 0)
.prop_map(|x| TestStruct { x }),
);
}
#[test]
fn filter_struct_sharp_vals() {
#[derive(Arbitrary, Debug, PartialEq)]
#[filter(#x > #y)]
struct TestStruct {
x: u32,
y: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("x > y", |&(x, y)| x > y)
.prop_map(|(x, y)| TestStruct { x, y }),
);
}
#[test]
fn filter_struct_sharp_self() {
#[derive(Arbitrary, Debug, PartialEq)]
#[filter(#self.x > #self.y)]
struct TestStruct {
x: u32,
y: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("x > y", |&(x, y)| x > y)
.prop_map(|(x, y)| TestStruct { x, y }),
);
}
#[test]
fn filter_struct_fn() {
#[derive(Arbitrary, Debug, PartialEq)]
#[filter(|s| s.x > s.y)]
struct TestStruct {
x: u32,
y: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("x > y", |&(x, y)| x > y)
.prop_map(|(x, y)| TestStruct { x, y }),
);
}
#[test]
fn filter_enum_fn() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
#[filter(Self::is_valid)]
enum TestEnum {
A(i32),
B(i32),
}
impl TestEnum {
fn is_valid(&self) -> bool {
match self {
Self::A(x) => x % 2 == 0,
Self::B(x) => x % 2 != 0,
}
}
}
assert_arbitrary(
prop_oneof![
any::<i32>().prop_map(TestEnum::A),
any::<i32>().prop_map(TestEnum::B),
]
.prop_filter("is_valid", TestEnum::is_valid),
);
}
#[test]
fn filter_enum_sharp_self() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
#[filter(#self.is_valid())]
enum TestEnum {
A(i32),
B(i32),
}
impl TestEnum {
fn is_valid(&self) -> bool {
match self {
Self::A(x) => x % 2 == 0,
Self::B(x) => x % 2 != 0,
}
}
}
assert_arbitrary(
prop_oneof![
any::<i32>().prop_map(TestEnum::A),
any::<i32>().prop_map(TestEnum::B),
]
.prop_filter("is_valid", TestEnum::is_valid),
);
}
#[test]
fn filter_variant() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
enum TestEnum {
#[filter(#x > #y)]
A {
x: i32,
y: i32,
},
B(i32),
}
assert_arbitrary(prop_oneof![
(any::<i32>(), any::<i32>())
.prop_filter("x > y", |&(x, y)| x > y)
.prop_map(|(x, y)| TestEnum::A { x, y }),
any::<i32>().prop_map(TestEnum::B),
]);
}
#[test]
fn filter_raw_keyword() {
#[derive(Arbitrary, Debug, PartialEq)]
#[filter(#fn > #y)]
struct TestStruct {
r#fn: u32,
y: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("fn > y", |&(r#fn, y)| r#fn > y)
.prop_map(|(r#fn, y)| TestStruct { r#fn, y }),
);
}
#[test]
fn filter_with_whence() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct {
#[strategy(1..10u32)]
#[filter("is_even", is_even)]
x: u32,
}
fn is_even(value: &u32) -> bool {
value % 2 == 0
}
assert_arbitrary(
(1..10u32)
.prop_filter("is_even", is_even)
.prop_map(|x| TestStruct { x }),
);
}
#[test]
fn filter_with_by_ref() {
#[derive(Arbitrary, Debug, PartialEq)]
#[filter(#x > *#y)]
struct TestStruct {
x: u32,
#[by_ref]
y: u32,
}
assert_arbitrary(
(any::<u32>(), any::<u32>())
.prop_filter("x > y", |&(x, y)| x > y)
.prop_map(|(x, y)| TestStruct { x, y }),
);
}
#[test]
fn args_struct() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
x_max: u32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[strategy(0..args.x_max)]
x: u32,
}
}
#[test]
fn args_with_strategy_sharp_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
y: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[strategy(0..10)]
x: i32,
#[strategy(0..#x + args.y)]
y: i32,
}
}
#[test]
fn args_with_strategy_sharp_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
a: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[strategy(0..10)]
x: i32,
#[strategy(0..#x + args.a)]
y: i32,
#[strategy(0..#y + args.a)]
z: i32,
}
}
#[test]
fn args_with_struct_filter_sharp_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#x % args.m != 0)]
struct TestStruct {
x: i32,
}
}
#[test]
fn args_with_struct_filter_sharp_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#x % args.m != 0)]
#[filter(#x % args.m != 1)]
struct TestStruct {
x: i32,
}
}
#[test]
fn args_with_struct_filter_sharp_self() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#self.x % args.m != 0)]
struct TestStruct {
x: i32,
}
}
#[test]
fn args_with_struct_filter_sharp_self_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#self.x % args.m != 0)]
#[filter(#self.x % args.m != 1)]
struct TestStruct {
x: i32,
}
}
#[test]
fn args_with_struct_filter_fn() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(is_valid_fn(args.m))]
struct TestStruct {
x: i32,
}
fn is_valid_fn(_: i32) -> impl Fn(&TestStruct) -> bool {
|_| true
}
}
#[test]
fn args_with_struct_filter_fn_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(is_valid_fn(args.m))]
#[filter(is_valid_fn(args.m + 1))]
struct TestStruct {
x: i32,
}
fn is_valid_fn(_: i32) -> impl Fn(&TestStruct) -> bool {
|_| true
}
}
#[test]
fn args_with_enum_filter_sharp_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#self.is_valid(args.m))]
enum TestEnum {
A { x: i32 },
B,
}
impl TestEnum {
fn is_valid(&self, m: i32) -> bool {
match self {
Self::A { x } => x % m != 0,
Self::B => true,
}
}
}
}
#[test]
fn args_with_enum_filter_sharp_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
#[filter(#self.is_valid(args.m))]
#[filter(#self.is_valid(args.m + 1))]
enum TestEnum {
A { x: i32 },
B,
}
impl TestEnum {
fn is_valid(&self, m: i32) -> bool {
match self {
Self::A { x } => x % m != 0,
Self::B => true,
}
}
}
}
#[test]
fn args_with_variant_filter_sharp_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
enum TestEnum {
#[filter(#x % args.m != 0)]
A {
x: i32,
},
B,
}
}
#[test]
fn args_with_variant_filter_sharp_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
enum TestEnum {
#[filter(#x % args.m != 0)]
#[filter(#x % args.m != 1)]
A {
x: i32,
},
B,
}
}
#[test]
fn args_with_field_filter_sharp_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[filter(#x % args.m != 0)]
x: i32,
}
}
#[test]
fn args_with_field_filter_sharp_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[filter(#x % args.m != 0)]
#[filter(#x % args.m != 1)]
x: i32,
}
}
#[test]
fn args_with_field_filter_fn() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[filter(is_larger_than(args.m))]
x: i32,
}
fn is_larger_than(t: i32) -> impl Fn(&i32) -> bool {
move |x: &i32| *x > t
}
}
#[test]
fn args_with_field_filter_fn_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[filter(is_larger_than(args.m))]
#[filter(is_larger_than(args.m + 1))]
x: i32,
}
fn is_larger_than(t: i32) -> impl Fn(&i32) -> bool {
move |x: &i32| *x > t
}
}
#[test]
fn args_map() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
x: i32,
}
}
#[test]
fn args_map_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
x: i32,
#[map(|y: i32| y + args.m)]
y: i32,
}
}
#[test]
fn args_map_filter_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
#[filter(#x > args.m)]
x: i32,
}
}
#[test]
fn args_map_filter_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
#[filter(#x > args.m)]
#[filter(#x > args.m + 1)]
x: i32,
}
}
#[test]
fn args_map_filter_fn_val() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
#[filter(|&x: &i32| x > args.m)]
x: i32,
}
}
#[test]
fn args_map_filter_fn_val_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
#[map(|x: i32| x + args.m)]
#[filter(|&x: &i32| x > args.m)]
#[filter(|&x: &i32| x > args.m + 1)]
x: i32,
}
}
#[test]
fn args_flat_map_x2() {
#[allow(dead_code)]
#[derive(Default)]
struct TestArgs {
m: i32,
}
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(args = TestArgs)]
struct TestStruct {
a0: i32,
a1: i32,
#[strategy(#a0..#a1 + args.m)]
b0: i32,
#[strategy(#a0..#a1 + args.m)]
b1: i32,
}
}
#[test]
fn auto_bound_tuple_struct() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct<T>(T);
assert_arbitrary(any::<u16>().prop_map(TestStruct));
assert_arbitrary(any::<u32>().prop_map(TestStruct));
}
#[test]
fn auto_bound_tuple_enum() {
#[derive(Arbitrary, Debug, PartialEq)]
enum TestEnum<T> {
A(T),
}
assert_arbitrary(any::<u16>().prop_map(TestEnum::A));
assert_arbitrary(any::<u32>().prop_map(TestEnum::A));
}
#[test]
fn auto_bound_any_attribute() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct<T>(#[any(std::default::Default::default())] T);
assert_arbitrary(any::<u16>().prop_map(TestStruct));
assert_arbitrary(any::<u32>().prop_map(TestStruct));
}
#[test]
fn auto_bound_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
struct TestStruct<T1, T2>(T1, T2);
assert_arbitrary((any::<u16>(), any::<u32>()).prop_map(|(x, y)| TestStruct(x, y)));
}
#[test]
fn auto_bound_map_input() {
#[allow(dead_code)]
#[derive(Debug, PartialEq, Clone)]
struct Wrapped<T>(T);
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T: Clone, ..))]
struct TestStruct<T> {
#[by_ref]
#[map(|t: T| Wrapped(t))]
t: Wrapped<T>,
}
}
#[test]
fn manual_bound_type() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T))]
struct TestStruct<T> {
#[strategy(any::<T>())]
x: T,
}
assert_arbitrary(any::<u16>().prop_map(|x| TestStruct { x }));
assert_arbitrary(any::<u32>().prop_map(|x| TestStruct { x }));
}
#[test]
fn manual_bound_type_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T1, T2))]
struct TestStruct<T1, T2> {
#[strategy(any::<T1>())]
x: T1,
#[strategy(any::<T2>())]
y: T2,
}
assert_arbitrary((any::<u16>(), any::<u32>()).prop_map(|(x, y)| TestStruct { x, y }));
}
#[test]
fn manual_bound_type_with_auto_bound() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T1, ..))]
struct TestStruct<T1, T2> {
#[strategy(any::<T1>())]
x: T1,
y: T2,
}
assert_arbitrary((any::<u16>(), any::<u32>()).prop_map(|(x, y)| TestStruct { x, y }));
}
#[test]
fn manual_bound_predicate() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T : Arbitrary + 'static))]
struct TestStruct<T> {
#[strategy(any::<T>())]
x: T,
}
assert_arbitrary(any::<u16>().prop_map(|x| TestStruct { x }));
assert_arbitrary(any::<u32>().prop_map(|x| TestStruct { x }));
}
#[test]
fn manual_bound_predicate_x2() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T1 : Arbitrary + 'static, T2 : Arbitrary + 'static))]
struct TestStruct<T1, T2> {
#[strategy(any::<T1>())]
x: T1,
#[strategy(any::<T2>())]
y: T2,
}
assert_arbitrary((any::<u16>(), any::<u32>()).prop_map(|(x, y)| TestStruct { x, y }));
}
#[test]
fn manual_bound_field() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T : Copy + Arbitrary + 'static))]
struct Inner<T>(T);
#[derive(Arbitrary, Debug, PartialEq)]
pub struct Outer<T> {
#[arbitrary(bound(T : Debug + Copy + Arbitrary + 'static))]
x: Inner<T>,
}
assert_arbitrary(any::<u16>().prop_map(|x| Outer { x: Inner(x) }));
}
#[test]
fn manual_bound_variant() {
#[derive(Arbitrary, Debug, PartialEq)]
#[arbitrary(bound(T : Copy + Arbitrary + 'static))]
pub struct Inner<T>(T);
#[derive(Arbitrary, Debug, PartialEq)]
pub enum Outer<T> {
#[arbitrary(bound(T : Debug + Copy + Arbitrary + 'static))]
X(Inner<T>),
}
assert_arbitrary(any::<u16>().prop_map(|x| Outer::X(Inner(x))));
}
#[test]
fn enum_with_variant_named_parameters() {
#[deny(warnings)]
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq, Clone)]
enum MyEnum {
Parameters,
SomethingElse,
}
}
#[test]
fn map() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[map(|x: u32| x + 1)]
x: u32,
}
assert_arbitrary(any::<u32>().prop_map(|x| X { x: x + 1 }));
}
#[test]
fn map_dependency() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
a: u32,
#[map(|x: u32| x ^ #a)]
b: u32,
}
assert_arbitrary((any::<u32>(), any::<u32>()).prop_map(|x| X {
a: x.0,
b: x.0 ^ x.1,
}));
}
#[test]
fn map_dependency_by_ref() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[by_ref]
a: u32,
#[map(|x: u32| x ^ *#a)]
b: u32,
}
assert_arbitrary((any::<u32>(), any::<u32>()).prop_map(|x| X {
a: x.0,
b: x.0 ^ x.1,
}));
}
#[test]
fn map_filter() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[map(|x: u32| x + 1)]
#[filter(#x % 2 == 0)]
x: u32,
}
assert_arbitrary(
any::<u32>()
.prop_map(|x| x + 1)
.prop_filter("", |x| x % 2 == 0)
.prop_map(|x| X { x }),
);
}
#[test]
fn map_strategy() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(1..10u32)]
#[map(|x: u32| x * 2)]
x: u32,
}
assert_arbitrary((1..10u32).prop_map(|x| X { x: x * 2 }));
}
#[test]
fn map_strategy_infer() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(1..10u32)]
#[map(|x| x * 2)]
x: u32,
}
assert_arbitrary((1..10u32).prop_map(|x| X { x: x * 2 }));
}
#[test]
fn map_strategy_any() {
fn x2(x: u32) -> u32 {
x * 2
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[map(x2)]
x: u32,
}
assert_arbitrary((any::<u32>()).prop_map(|x| X { x: x * 2 }));
}
#[test]
fn map_strategy_any_with() {
fn x2(x: A) -> u32 {
x.0 * 2
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
#[arbitrary(args = u32)]
struct A(#[strategy(0..*args)] u32);
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[any(10)]
#[map(x2)]
x: u32,
}
assert_arbitrary((0..10u32).prop_map(|x| X { x: x * 2 }));
}
#[test]
fn map_strategy_any_with_setter() {
fn x2(x: A) -> u32 {
x.0 * 2
}
#[derive(Default)]
struct Arg {
val: u32,
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
#[arbitrary(args = Arg)]
struct A(#[strategy(0..args.val)] u32);
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[any(val = 10)]
#[map(x2)]
x: u32,
}
assert_arbitrary((0..10u32).prop_map(|x| X { x: x * 2 }));
}
#[test]
fn map_strategy_any_dependency() {
fn xor(arg: u32) -> impl Fn(u32) -> u32 {
move |x| x ^ arg
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
a: u32,
#[map(xor(#a))]
b: u32,
}
assert_arbitrary((any::<u32>(), any::<u32>()).prop_map(|x| X {
a: x.0,
b: x.0 ^ x.1,
}));
}
#[test]
fn map_strategy_any_dependency_by_ref() {
fn xor(arg: u32) -> impl Fn(u32) -> u32 {
move |x| x ^ arg
}
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[by_ref]
a: u32,
#[map(xor(*#a))]
b: u32,
}
assert_arbitrary((any::<u32>(), any::<u32>()).prop_map(|x| X {
a: x.0,
b: x.0 ^ x.1,
}));
}
#[test]
fn map_with_by_ref() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[by_ref]
#[map(|x: u32| x + 1)]
x: u32,
}
assert_arbitrary(any::<u32>().prop_map(|x| X { x: x + 1 }));
}
#[test]
fn map_with_by_ref_and_dependency() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
x: u32,
#[by_ref]
#[map(|y: u32| #x ^ y)]
y: u32,
}
assert_arbitrary((any::<u32>(), any::<u32>()).prop_map(|(x, y)| X { x, y: x ^ y }));
}
#[test]
fn map_7_field() {
#[allow(dead_code)]
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[map(|x: u32| x + 1)]
a1: u32,
#[map(|x: u32| x + 2)]
a2: u32,
#[map(|x: u32| x + 3)]
a3: u32,
#[map(|x: u32| x + 4)]
a4: u32,
#[map(|x: u32| x + 5)]
a5: u32,
#[map(|x: u32| x + 6)]
a6: u32,
#[map(|x: u32| x + 7)]
a7: u32,
}
}
#[test]
fn depend_on_map() {
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(0..5u32)]
#[map(|x: u32| x + 5)]
a: u32,
#[strategy(0..#a)]
b: u32,
}
assert_arbitrary(
(0..5u32)
.prop_flat_map(|x| (Just(x + 5), 0..x + 5))
.prop_map(|x| X { a: x.0, b: x.1 }),
);
}
#[test]
fn index() {
use proptest::sample::Index;
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(1..20usize)]
a: usize,
#[map(|i: Index| i.index(#a))]
b: usize,
}
assert_arbitrary((1..20usize, any::<Index>()).prop_map(|x| X {
a: x.0,
b: x.1.index(x.0),
}));
}
#[test]
fn filter_with_strategy_and_map_0() {
use proptest::sample::Index;
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(10..100usize)]
a: usize,
#[strategy(0..#a)]
x: usize,
#[map(|i: Index|i.index(#a))]
#[filter(#y % 2 == 0)]
y: usize,
}
let s = (10..100usize, any::<Index>())
.prop_flat_map(|x| (0..x.0, Just(x.1.index(x.0)), Just(x.0), Just(x.1)))
.prop_map(|x| X {
a: x.2,
x: x.0,
y: x.1,
})
.prop_filter("", |x| x.y % 2 == 0);
assert_arbitrary(s);
}
#[test]
fn filter_with_strategy_and_map_1() {
use proptest::sample::Index;
#[derive(Arbitrary, Debug, PartialEq, Clone)]
struct X {
#[strategy(10..100usize)]
a: usize,
#[strategy(0..#a)]
x: usize,
#[map(|i: Index|i.index(#a))]
#[filter(#y % 2 == 1)]
y: usize,
}
let s = (10..100usize, any::<Index>())
.prop_flat_map(|x| (0..x.0, Just(x.1.index(x.0)), Just(x.0), Just(x.1)))
.prop_map(|x| X {
a: x.2,
x: x.0,
y: x.1,
})
.prop_filter("", |x| x.y % 2 == 1);
assert_arbitrary(s);
}
#[test]
fn contained_dependency() {
#[derive(Debug, Arbitrary, Clone, PartialEq, Eq)]
pub struct X {
#[strategy(0..100u32)]
pub a: u32,
#[strategy(0..100u32)]
pub b: u32,
#[strategy(0..100u32)]
pub c: u32,
#[strategy(Just(#b + #c))]
pub x: u32,
#[strategy(Just(#a + #b + #c))]
pub y: u32,
}
assert_eq_strategy(
any::<X>(),
(0..100u32, 0..100u32, 0..100u32)
.prop_flat_map(|(a, b, c)| {
let x = b + c;
let y = a + b + c;
Just((a, b, c, x, y))
})
.prop_map(|(a, b, c, x, y)| X { a, b, c, x, y }),
);
}
#[test]
#[allow(unused)]
fn args_in_any() {
#[derive(Arbitrary, Debug)]
#[arbitrary(args = u32)]
struct A(#[strategy(0..*args)] u32);
#[derive(Arbitrary, Debug)]
#[arbitrary(args = u32)]
struct X {
#[any(*args)]
a: A,
}
#[derive(Arbitrary, Debug)]
#[arbitrary(args = u32)]
struct Y(#[any(*args)] A);
}
macro_rules! macro_rules_arbitrary {
($item:item) => {
#[derive(Debug, Arbitrary)]
$item
};
}
macro_rules_arbitrary! {
#[allow(unused)]
struct MacroRulesArbitrary(#[strategy(0..2)] i32);
}