use crate::{
config::{
core::ConfigIdentifier,
elements::{CustomTestGroup, TestGroup},
scripts::ScriptId,
},
reporter::events::TestSlotAssignment,
};
use chrono::{DateTime, FixedOffset, TimeZone, Utc};
use proptest::prelude::*;
use smol_str::SmolStr;
pub fn arb_duration() -> impl Strategy<Value = std::time::Duration> {
any::<u64>().prop_map(std::time::Duration::from_millis)
}
pub fn arb_datetime_fixed_offset() -> impl Strategy<Value = DateTime<FixedOffset>> {
(946684800i64..4102444800i64, -720i32..720i32).prop_map(|(secs, offset_minutes)| {
let offset_secs = offset_minutes * 60;
let offset =
FixedOffset::east_opt(offset_secs).unwrap_or_else(|| FixedOffset::east_opt(0).unwrap());
let utc = Utc
.timestamp_opt(secs, 0)
.single()
.expect("valid timestamp");
utc.with_timezone(&offset)
})
}
pub fn arb_smol_str() -> impl Strategy<Value = SmolStr> {
any::<String>().prop_map(SmolStr::new)
}
impl Arbitrary for ConfigIdentifier {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
let regular_identifier = "[a-zA-Z][a-zA-Z0-9-]{0,20}";
let tool_identifier = "@tool:[a-zA-Z][a-zA-Z0-9-]{0,10}:[a-zA-Z][a-zA-Z0-9-]{0,10}";
prop_oneof![
3 => regular_identifier
.prop_map(|s| ConfigIdentifier::new(s.into()).expect("valid identifier")),
1 => tool_identifier
.prop_map(|s| ConfigIdentifier::new(s.into()).expect("valid tool identifier")),
]
.boxed()
}
}
impl Arbitrary for ScriptId {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
any::<ConfigIdentifier>().prop_map(ScriptId).boxed()
}
}
pub fn global_slot_assignment(global_slot: u64) -> TestSlotAssignment {
TestSlotAssignment {
global_slot,
group_slot: None,
test_group: TestGroup::Global,
}
}
impl Arbitrary for TestGroup {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
prop_oneof![
1 => Just(TestGroup::Global),
3 => any::<ConfigIdentifier>()
.prop_map(|id| TestGroup::Custom(CustomTestGroup::from_identifier(id))),
]
.boxed()
}
}
impl Arbitrary for TestSlotAssignment {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
(any::<u64>(), any::<Option<u64>>(), any::<TestGroup>())
.prop_map(|(global_slot, group_slot, test_group)| TestSlotAssignment {
global_slot,
group_slot,
test_group,
})
.boxed()
}
}