diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/Cargo.toml | 2 | ||||
-rw-r--r-- | tvix/eval/src/value/arbitrary.rs | 46 | ||||
-rw-r--r-- | tvix/eval/src/value/attrs.rs | 34 | ||||
-rw-r--r-- | tvix/eval/src/value/list.rs | 23 | ||||
-rw-r--r-- | tvix/eval/src/value/mod.rs | 6 |
5 files changed, 40 insertions, 71 deletions
diff --git a/tvix/eval/Cargo.toml b/tvix/eval/Cargo.toml index 6974110290bf..24e6d33d0d1c 100644 --- a/tvix/eval/Cargo.toml +++ b/tvix/eval/Cargo.toml @@ -50,7 +50,7 @@ nix_tests = [] impure = [] # Enables Arbitrary impls for internal types (required to run tests) -arbitrary = [ "proptest", "test-strategy" ] +arbitrary = [ "proptest", "test-strategy", "imbl/proptest" ] # For debugging use only; not appropriate for production use. backtrace_overflow = [ "backtrace-on-stack-overflow" ] diff --git a/tvix/eval/src/value/arbitrary.rs b/tvix/eval/src/value/arbitrary.rs index cd7629cfb923..f0bdc06fd51d 100644 --- a/tvix/eval/src/value/arbitrary.rs +++ b/tvix/eval/src/value/arbitrary.rs @@ -1,9 +1,10 @@ //! Support for configurable generation of arbitrary nix values +use imbl::proptest::{ord_map, vector}; use proptest::{prelude::*, strategy::BoxedStrategy}; use std::ffi::OsString; -use super::{NixAttrs, NixList, NixString, Value}; +use super::{attrs::AttrsRep, NixAttrs, NixList, NixString, Value}; #[derive(Clone)] pub enum Parameters { @@ -25,6 +26,39 @@ impl Default for Parameters { } } +impl Arbitrary for NixAttrs { + type Parameters = Parameters; // <BTreeMap<NixString, Value> as Arbitrary>::Parameters; + type Strategy = BoxedStrategy<Self>; + + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + prop_oneof![ + // Empty attrs representation + Just(Self(AttrsRep::Empty)), + // KV representation (name/value pairs) + ( + any_with::<Value>(args.clone()), + any_with::<Value>(args.clone()) + ) + .prop_map(|(name, value)| Self(AttrsRep::KV { name, value })), + // Map representation + ord_map(NixString::arbitrary(), Value::arbitrary_with(args), 0..100) + .prop_map(|map| Self(AttrsRep::Im(map))) + ] + .boxed() + } +} + +impl Arbitrary for NixList { + type Parameters = <Value as Arbitrary>::Parameters; + type Strategy = BoxedStrategy<Self>; + + fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { + vector(<Value as Arbitrary>::arbitrary_with(args), 0..100) + .prop_map(NixList::from) + .boxed() + } +} + impl Arbitrary for Value { type Parameters = Parameters; type Strategy = BoxedStrategy<Self>; @@ -65,14 +99,8 @@ fn leaf_value() -> impl Strategy<Value = Value> { fn non_internal_value() -> impl Strategy<Value = Value> { leaf_value().prop_recursive(3, 5, 5, |inner| { prop_oneof![ - any_with::<NixAttrs>(( - Default::default(), - Default::default(), - Parameters::Strategy(inner.clone()) - )) - .prop_map(Value::attrs), - any_with::<NixList>((Default::default(), Parameters::Strategy(inner))) - .prop_map(Value::List) + NixAttrs::arbitrary_with(Parameters::Strategy(inner.clone())).prop_map(Value::attrs), + any_with::<NixList>(Parameters::Strategy(inner)).prop_map(Value::List) ] }) } diff --git a/tvix/eval/src/value/attrs.rs b/tvix/eval/src/value/attrs.rs index 6515fb515a5d..10d071720219 100644 --- a/tvix/eval/src/value/attrs.rs +++ b/tvix/eval/src/value/attrs.rs @@ -24,7 +24,7 @@ use super::Value; mod tests; #[derive(Clone, Debug, Deserialize)] -enum AttrsRep { +pub(super) enum AttrsRep { Empty, Im(OrdMap<NixString, Value>), @@ -92,7 +92,7 @@ impl AttrsRep { #[repr(transparent)] #[derive(Clone, Debug, Default)] -pub struct NixAttrs(AttrsRep); +pub struct NixAttrs(pub(super) AttrsRep); impl<K, V> FromIterator<(K, V)> for NixAttrs where @@ -192,36 +192,6 @@ impl<'de> Deserialize<'de> for NixAttrs { } } -#[cfg(feature = "arbitrary")] -mod arbitrary { - use super::*; - use std::collections::BTreeMap; - - use proptest::prelude::*; - use proptest::prop_oneof; - use proptest::strategy::{BoxedStrategy, Just, Strategy}; - - impl Arbitrary for NixAttrs { - type Parameters = <BTreeMap<NixString, Value> as Arbitrary>::Parameters; - - type Strategy = BoxedStrategy<Self>; - - fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { - prop_oneof![ - Just(Self(AttrsRep::Empty)), - ( - any_with::<Value>(args.2.clone()), - any_with::<Value>(args.2.clone()) - ) - .prop_map(|(name, value)| Self(AttrsRep::KV { name, value })), - any_with::<BTreeMap<NixString, Value>>(args) - .prop_map(|map| Self::from_iter(map.into_iter())) - ] - .boxed() - } - } -} - impl NixAttrs { pub fn empty() -> Self { Self(AttrsRep::Empty) diff --git a/tvix/eval/src/value/list.rs b/tvix/eval/src/value/list.rs index 6d830b7283d0..5d1daf7c9c0b 100644 --- a/tvix/eval/src/value/list.rs +++ b/tvix/eval/src/value/list.rs @@ -35,29 +35,6 @@ impl From<Vector<Value>> for NixList { } } -#[cfg(feature = "arbitrary")] -mod arbitrary { - use proptest::{ - prelude::{any_with, Arbitrary}, - strategy::{BoxedStrategy, Strategy}, - }; - - use super::*; - - impl Arbitrary for NixList { - // TODO(tazjin): im seems to implement arbitrary instances, - // but I couldn't figure out how to enable them. - type Parameters = <Vec<Value> as Arbitrary>::Parameters; - type Strategy = BoxedStrategy<Self>; - - fn arbitrary_with(args: Self::Parameters) -> Self::Strategy { - any_with::<Vec<Value>>(args) - .prop_map(NixList::from_vec) - .boxed() - } - } -} - impl NixList { pub fn len(&self) -> usize { self.0.len() diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index af8627bf9b76..9ab23043c523 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -556,12 +556,6 @@ impl From<PathBuf> for Value { } } -impl From<Vec<Value>> for Value { - fn from(val: Vec<Value>) -> Self { - Self::List(NixList::from_vec(val)) - } -} - fn type_error(expected: &'static str, actual: &Value) -> ErrorKind { ErrorKind::TypeError { expected, |