diff --git a/tiledb/api/src/array/schema.rs b/tiledb/api/src/array/schema.rs index 6aa8d47c..442214e1 100644 --- a/tiledb/api/src/array/schema.rs +++ b/tiledb/api/src/array/schema.rs @@ -9,7 +9,7 @@ use crate::array::{Attribute, Domain, Layout}; use crate::context::Context; use crate::Result as TileDBResult; -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum ArrayType { Dense, Sparse, diff --git a/tiledb/test/src/attribute.rs b/tiledb/test/src/attribute.rs index d46e6ef8..90d7b7b2 100644 --- a/tiledb/test/src/attribute.rs +++ b/tiledb/test/src/attribute.rs @@ -5,6 +5,10 @@ use tiledb::context::Context; pub fn arbitrary_name() -> impl Strategy { proptest::string::string_regex("[a-zA-Z0-9_]*") .expect("Error creating attribute name strategy") + .prop_filter( + "Attribute names may not begin with reserved prefix", + |name| !name.starts_with("__"), + ) } pub fn arbitrary(context: &Context) -> impl Strategy { diff --git a/tiledb/test/src/domain.rs b/tiledb/test/src/domain.rs index 0e1a2a28..ddd92ed4 100644 --- a/tiledb/test/src/domain.rs +++ b/tiledb/test/src/domain.rs @@ -1,25 +1,32 @@ use proptest::prelude::*; -use tiledb::array::{Domain, DomainBuilder}; +use tiledb::array::{ArrayType, Domain, DomainBuilder}; use tiledb::context::Context; use tiledb::Result as TileDBResult; +use crate::strategy::LifetimeBoundStrategy; + pub fn arbitrary( context: &Context, + array_type: ArrayType, ) -> impl Strategy> { const MIN_DIMENSIONS: usize = 1; const MAX_DIMENSIONS: usize = 8; - proptest::collection::vec( - crate::dimension::arbitrary(context), - 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()) - }) + match array_type { + ArrayType::Dense => unimplemented!(), + ArrayType::Sparse => proptest::collection::vec( + crate::dimension::arbitrary(context), + 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(), + } } #[cfg(test)] @@ -28,11 +35,11 @@ mod tests { /// Test that the arbitrary domain construction always succeeds #[test] - fn domain_arbitrary() { + fn domain_arbitrary_sparse() { let ctx = Context::new().expect("Error creating context"); - proptest!(|(maybe_domain in arbitrary(&ctx))| { - maybe_domain.expect("Error constructing arbitrary dimension"); + proptest!(|(maybe_domain in arbitrary(&ctx, ArrayType::Sparse))| { + maybe_domain.expect("Error constructing arbitrary domain"); }); } } diff --git a/tiledb/test/src/lib.rs b/tiledb/test/src/lib.rs index 4857ebb2..5d9d9ef5 100644 --- a/tiledb/test/src/lib.rs +++ b/tiledb/test/src/lib.rs @@ -6,4 +6,5 @@ pub mod attribute; pub mod datatype; pub mod dimension; pub mod domain; +pub mod schema; pub mod strategy; diff --git a/tiledb/test/src/schema.rs b/tiledb/test/src/schema.rs new file mode 100644 index 00000000..b7d1f38e --- /dev/null +++ b/tiledb/test/src/schema.rs @@ -0,0 +1,49 @@ +use proptest::prelude::*; +use tiledb::array::{ArrayType, Schema, SchemaBuilder}; +use tiledb::context::Context; +use tiledb::Result as TileDBResult; + +pub fn arbitrary_array_type() -> impl Strategy { + // TODO: implement Domain scenario for Dense arrays + Just(ArrayType::Sparse) +} + +pub fn arbitrary( + context: &Context, +) -> impl Strategy> { + const MIN_ATTRS: usize = 1; + const MAX_ATTRS: usize = 128; + + arbitrary_array_type() + .prop_flat_map(move |array_type| + ( + Just(array_type), + crate::domain::arbitrary(context, array_type), + proptest::collection::vec(crate::attribute::arbitrary(context), MIN_ATTRS..=MAX_ATTRS) + )) + .prop_map(|(array_type, domain, attrs)| { + /* TODO: cell order, tile order, capacity, duplicates */ + let mut b = SchemaBuilder::new(context, array_type, domain?)?; + for attr in attrs { + /* TODO: how to ensure no duplicate names, assuming that matters? */ + b = b.add_attribute(attr)? + } + + Ok(b.build()) + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Test that the arbitrary schema construction always succeeds + #[test] + fn schema_arbitrary() { + let ctx = Context::new().expect("Error creating context"); + + proptest!(|(maybe_schema in arbitrary(&ctx))| { + maybe_schema.expect("Error constructing arbitrary schema"); + }); + } +}