Skip to content

Commit

Permalink
arbitrary json
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q committed May 2, 2024
1 parent c3be34b commit 9153a66
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 49 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ venv/

*.DS_Store
*.egg-info

# Local overrides for devenv shell
./devenv.local.nix
7 changes: 3 additions & 4 deletions hugr/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,17 +553,16 @@ impl FromIterator<ExtensionId> for ExtensionSet {

#[cfg(test)]
mod test {
use std::collections::HashSet;

use proptest::prelude::*;
use proptest::{collection::hash_set, prelude::*};

use crate::extension::ExtensionId;
impl Arbitrary for super::ExtensionSet {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
let vars = any::<HashSet<usize>>();
let extensions = any::<HashSet<ExtensionId>>();
let vars = hash_set(0..10usize, 0..3);
let extensions = hash_set(any::<ExtensionId>(), 0..3);
(vars, extensions)
.prop_map(|(vars, extensions)| {
let mut r = Self::new();
Expand Down
78 changes: 50 additions & 28 deletions hugr/src/hugr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ pub(crate) mod test {

pub(crate) mod proptest {
use lazy_static::lazy_static;
use proptest::collection::vec;
use proptest::strategy::Strategy;

use proptest::prelude::*;
Expand All @@ -360,6 +361,7 @@ pub(crate) mod test {
static ref ANY_IDENT_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(r"[[:alpha:]]{1,3}").unwrap(),
string_regex(crate::hugr::ident::PATH_COMPONENT_NICE_REGEX_STR).unwrap(),
string_regex(crate::hugr::ident::PATH_COMPONENT_REGEX_STR).unwrap(),
].sboxed()
Expand All @@ -368,40 +370,42 @@ pub(crate) mod test {
static ref ANY_NONEMPTY_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(r".+").unwrap(),
string_regex(r"[[:alpha:]]{1,3}").unwrap(),
string_regex(r"[[:alpha:]]+").unwrap(),
string_regex(r".+").unwrap(),
].sboxed()
};

static ref ANY_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(r"[[:alpha:]]{0,3}").unwrap(),
string_regex(r"[[:alpha:]]*").unwrap(),
string_regex(r".*").unwrap(),
].sboxed()
};

// static ref ANY_SERDE_YAML_VALUE: SBoxedStrategy<serde_yaml::Value> = {
// use serde_yaml::value::{Tag, TaggedValue, Value};
// proptest::collection::vec;
// prop_oneof![
// Just(Value::Null),
// any::<bool>().prop_map_into(),
// any::<u64>().prop_map_into(),
// any::<i64>().prop_map_into(),
// any::<f64>().prop_map_into(),
// Just(Value::Number(3.into())),
// any_string().prop_map_into(),
// ].sboxed().prop_recursive(
// 3, // No more than 3 branch levels deep
// 32, // Target around 32 total elements
// 3, // Each collection is up to 3 elements long
// |element| prop_oneof![
// (any_string().prop_map(Tag::new), element.clone()).prop_map(|(tag, value)| Value::Tagged(Box::new(TaggedValue { tag, value }))),
// proptest::collection::vec(element.clone(), 0..3).prop_map_into(),
// ]
// ).sboxed()
// };
static ref ANY_SERDE_YAML_VALUE_LEAF: SBoxedStrategy<serde_yaml::Value> = {
use serde_yaml::value::Value;
prop_oneof![
Just(Value::Null),
any::<bool>().prop_map_into(),
any::<u64>().prop_map_into(),
any::<i64>().prop_map_into(),
// any::<f64>().prop_map_into(),
Just(Value::Number(3.into())),
any_string().prop_map_into(),
].sboxed()
};
// .prop_recursive(
// 3, // No more than 3 branch levels deep
// 32, // Target around 32 total elements
// 3, // Each collection is up to 3 elements long
// |element| prop_oneof![
// (any_string().prop_map(Tag::new), element.clone()).prop_map(|(tag, value)| Value::Tagged(Box::new(TaggedValue { tag, value }))),
// proptest::collection::vec(element.clone(), 0..3).prop_map_into(),
// ]
// ).sboxed()
}

pub fn any_nonempty_string() -> SBoxedStrategy<String> {
Expand All @@ -416,13 +420,31 @@ pub(crate) mod test {
ANY_IDENT_STRING.clone()
}

// pub fn any_string() -> SBoxedStrategy<String> {
// ANY_STRING.clone()
// }
pub fn any_string() -> SBoxedStrategy<String> {
ANY_STRING.clone()
}

// pub fn any_serde_yaml_value() -> SBoxedStrategy<serde_yaml::Value> {
// ANY_SERDE_YAML_VALUE.clone()
// }
pub fn any_serde_yaml_value() -> impl Strategy<Value = serde_yaml::Value> {
// use serde_yaml::value::{Tag, TaggedValue, Value};
ANY_SERDE_YAML_VALUE_LEAF
.clone()
.prop_recursive(
3, // No more than 3 branch levels deep
32, // Target around 32 total elements
3, // Each collection is up to 3 elements long
|element| {
prop_oneof![
// TaggedValue doesn't roundtrip through JSON
// (any_nonempty_string().prop_map(Tag::new), element.clone()).prop_map(|(tag, value)| Value::Tagged(Box::new(TaggedValue { tag, value }))),
proptest::collection::vec(element.clone(), 0..3).prop_map_into(),
vec((any_string().prop_map_into(), element.clone()), 0..3).prop_map(
|x| x.into_iter().collect::<serde_yaml::Mapping>().into()
)
]
},
)
.boxed()
}
}

#[test]
Expand Down
9 changes: 6 additions & 3 deletions hugr/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,8 @@ pub(crate) fn check_typevar_decl(

#[cfg(test)]
pub(crate) mod test {
use self::custom::test::CustomTypeArbitraryParameters;

use super::*;
use proptest::prelude::*;

Expand Down Expand Up @@ -490,11 +492,12 @@ pub(crate) mod test {
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(depth: Self::Parameters) -> Self::Strategy {
prop_oneof![
any_with::<CustomType>(depth).prop_map(Self::Extension),
any::<AliasDecl>().prop_map(Self::Alias),
any::<(usize, TypeBound)>().prop_map(|(us, tb)| Self::Variable(us, tb)),
any_with::<FunctionType>(depth).prop_map(|x| Self::Function(Box::new(x))),
any::<AliasDecl>().prop_map(Self::Alias),
any_with::<SumType>(depth).prop_map(Self::Sum),
any_with::<CustomType>(CustomTypeArbitraryParameters::new(depth))
.prop_map(Self::Extension),
any_with::<FunctionType>(depth).prop_map(|x| Self::Function(Box::new(x))),
]
.boxed()
}
Expand Down
33 changes: 28 additions & 5 deletions hugr/src/types/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,33 +139,56 @@ impl From<CustomType> for Type {
}

#[cfg(test)]
mod test {
pub mod test {
use lazy_static::lazy_static;
use proptest::prelude::*;

use crate::{
extension::ExtensionId,
types::{TypeArg, TypeBound},
types::{test::TypeDepth, TypeArg, TypeBound},
};

lazy_static! {
static ref NICE_ID_REGEX: regex_syntax::hir::Hir =
regex_syntax::parse(r"[[:alpha:]]+").unwrap();
static ref ID_REGEX: regex_syntax::hir::Hir = regex_syntax::parse(r".+").unwrap();
}

#[derive(Default)]
pub struct CustomTypeArbitraryParameters(TypeDepth, Option<TypeBound>);

impl From<TypeDepth> for CustomTypeArbitraryParameters {
fn from(v: TypeDepth) -> Self {
Self::new(v)
}
}

impl CustomTypeArbitraryParameters {
pub fn with_bound(mut self, bound: TypeBound) -> Self {
self.1 = Some(bound);
self
}

pub fn new(depth: TypeDepth) -> Self {
Self(depth, None)
}
}

impl Arbitrary for super::CustomType {
type Parameters = crate::types::test::TypeDepth;
type Parameters = CustomTypeArbitraryParameters;
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(depth: Self::Parameters) -> Self::Strategy {
fn arbitrary_with(
CustomTypeArbitraryParameters(depth, mb_bound): Self::Parameters,
) -> Self::Strategy {
use crate::hugr::test::proptest::any_nonempty_string;
use proptest::collection::vec;
let extension = any::<ExtensionId>();
let bound = mb_bound.map_or(any::<TypeBound>().boxed(), |x| Just(x).boxed());
let args = if depth.leaf() {
Just(vec![]).boxed()
} else {
vec(any_with::<TypeArg>(depth.descend()), 0..3).boxed()
};
let bound = any::<TypeBound>();
(any_nonempty_string(), args, extension, bound)
.prop_map(|(id, args, extension, bound)| Self::new(id, args, extension, bound))
.boxed()
Expand Down
19 changes: 10 additions & 9 deletions hugr/src/types/type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ pub enum TypeArgError {
#[cfg(test)]
mod test {
use crate::extension::ExtensionSet;
use crate::hugr::test::proptest::any_serde_yaml_value;
use crate::types::custom::test::CustomTypeArbitraryParameters;
use crate::types::type_param::TypeArgVariable;
use crate::types::{CustomType, Type, TypeBound};
use proptest::prelude::*;
Expand All @@ -388,14 +390,13 @@ mod test {
type Parameters = crate::types::test::TypeDepth;
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(depth: Self::Parameters) -> Self::Strategy {
any_with::<CustomType>(depth)
.prop_filter_map("Type bound is not Eq", |ct| {
if ct.bound() == TypeBound::Eq {
Some(CustomTypeArg::new(ct, serde_yaml::Value::Null).unwrap())
} else {
None
}
})
(
any_with::<CustomType>(
CustomTypeArbitraryParameters::new(depth).with_bound(TypeBound::Eq),
),
any_serde_yaml_value(),
)
.prop_map(|(ct, value)| CustomTypeArg::new(ct, value.clone()).unwrap())
.boxed()
}
}
Expand All @@ -422,7 +423,7 @@ mod test {
any::<super::UpperBound>()
.prop_map(|bound| Self::BoundedNat { bound })
.boxed(),
any_with::<CustomType>(depth)
any_with::<CustomType>(depth.into())
.prop_map(|ty| Self::Opaque { ty })
.boxed(),
]);
Expand Down

0 comments on commit 9153a66

Please sign in to comment.