Skip to content

Commit

Permalink
Add proptest strategy for generating Schema for dense arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
rroelke committed Mar 21, 2024
1 parent ad8d1f7 commit d52c7df
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 29 deletions.
13 changes: 11 additions & 2 deletions tiledb/test/src/datatype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ pub fn arbitrary() -> impl Strategy<Value = tiledb::Datatype> {
]
}

/// Choose an arbitrary datatype which satisifes the CAPIConverter trait
/// Choose an arbitrary datatype which is implemented
/// (satisfies CAPIConv, and has cases in fn_typed)
// TODO: make sure to keep this list up to date as we add more types
pub fn arbitrary_conv() -> impl Strategy<Value = tiledb::Datatype> {
pub fn arbitrary_implemented() -> impl Strategy<Value = tiledb::Datatype> {
prop_oneof![
Just(tiledb::Datatype::Int8),
Just(tiledb::Datatype::Int16),
Expand All @@ -65,3 +66,11 @@ pub fn arbitrary_conv() -> impl Strategy<Value = tiledb::Datatype> {
Just(tiledb::Datatype::Float64),
]
}

pub fn arbitrary_for_dense_dimension() -> impl Strategy<Value = tiledb::Datatype>
{
arbitrary_implemented().prop_filter(
"Type is not a valid dimension type for dense arrays",
|dt| dt.is_allowed_dimension_type_dense(),
)
}
50 changes: 34 additions & 16 deletions tiledb/test/src/dimension.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use num_traits::{Bounded, Num};
use proptest::prelude::*;
use std::fmt::Debug;
use tiledb::array::{Dimension, DimensionBuilder};
use tiledb::array::{ArrayType, Dimension, DimensionBuilder};
use tiledb::context::Context;
use tiledb::fn_typed;
use tiledb::Result as TileDBResult;
use tiledb::{fn_typed, Datatype};

use crate::strategy::LifetimeBoundStrategy;

Expand Down Expand Up @@ -75,32 +75,50 @@ where
})
}

pub fn arbitrary_for_type(
context: &Context,
datatype: Datatype,
) -> impl Strategy<Value = TileDBResult<Dimension>> {
fn_typed!(arbitrary_range_and_extent, datatype =>
(crate::attribute::arbitrary_name(), arbitrary_range_and_extent).prop_map(move |(name, values)| {
DimensionBuilder::new(context, name.as_ref(), datatype, &values.0, &values.1)
.map(|b| b.build())
}).bind())
}

pub fn arbitrary(
context: &Context,
array_type: ArrayType,
) -> impl Strategy<Value = TileDBResult<Dimension>> {
(
crate::datatype::arbitrary_conv(),
crate::attribute::arbitrary_name(),
)
.prop_flat_map(|(dt, name)| {
fn_typed!(arbitrary_range_and_extent, dt =>
(Just(dt), Just(name), arbitrary_range_and_extent).prop_map(|(dt, name, values)| {
DimensionBuilder::new(context, name.as_ref(), dt, &values.0, &values.1)
.map(|b| b.build())
}).bind())
})
match array_type {
ArrayType::Dense => {
crate::datatype::arbitrary_for_dense_dimension().boxed()
}
ArrayType::Sparse => crate::datatype::arbitrary_implemented().boxed(),
}
.prop_flat_map(|dt| arbitrary_for_type(context, dt))
}

#[cfg(test)]
mod tests {
use super::*;

/// Test that the arbitrary dimension construction always succeeds
/// Test that the arbitrary dimension dense array construction always succeeds
#[test]
fn dimension_arbitrary_dense() {
let ctx = Context::new().expect("Error creating context");

proptest!(|(maybe_dimension in arbitrary(&ctx, ArrayType::Dense))| {
maybe_dimension.expect("Error constructing arbitrary dimension");
});
}

/// Test that the arbitrary dimension sparse array construction always succeeds
#[test]
fn dimension_arbitrary() {
fn dimension_arbitrary_sparse() {
let ctx = Context::new().expect("Error creating context");

proptest!(|(maybe_dimension in arbitrary(&ctx))| {
proptest!(|(maybe_dimension in arbitrary(&ctx, ArrayType::Sparse))| {
maybe_dimension.expect("Error constructing arbitrary dimension");
});
}
Expand Down
28 changes: 19 additions & 9 deletions tiledb/test/src/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,30 @@ pub fn arbitrary(
const MAX_DIMENSIONS: usize = 8;

match array_type {
ArrayType::Dense => unimplemented!(),
ArrayType::Dense => crate::datatype::arbitrary_for_dense_dimension()
.prop_flat_map(|dimension_type| {
proptest::collection::vec(
crate::dimension::arbitrary_for_type(
context,
dimension_type,
),
MIN_DIMENSIONS..=MAX_DIMENSIONS,
)
})
.bind(),
ArrayType::Sparse => proptest::collection::vec(
crate::dimension::arbitrary(context),
crate::dimension::arbitrary(context, array_type),
MIN_DIMENSIONS..=MAX_DIMENSIONS,
)
.prop_map(|dimensions| {
let mut d = DomainBuilder::new(context)?;
for dim in dimensions {
d = d.add_dimension(dim?)?;
}
Ok(d.build())
})
.bind(),
}
.prop_map(|dimensions| {
let mut d = DomainBuilder::new(context)?;
for dim in dimensions {
d = d.add_dimension(dim?)?;
}
Ok(d.build())
})
}

#[cfg(test)]
Expand Down
3 changes: 1 addition & 2 deletions tiledb/test/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use tiledb::context::Context;
use tiledb::Result as TileDBResult;

pub fn arbitrary_array_type() -> impl Strategy<Value = ArrayType> {
// TODO: implement Domain scenario for Dense arrays
Just(ArrayType::Sparse)
prop_oneof![Just(ArrayType::Dense), Just(ArrayType::Sparse),]
}

pub fn arbitrary(
Expand Down

0 comments on commit d52c7df

Please sign in to comment.