use block::Context;
use header::{SuiteHeader, SuiteLabel};
#[derive(new)]
pub struct Suite<T> {
pub(crate) header: SuiteHeader,
pub(crate) environment: T,
pub(crate) context: Context<T>,
}
impl<T> Suite<T> {
pub fn num_blocks(&self) -> usize {
self.context.num_blocks()
}
pub fn num_examples(&self) -> usize {
self.context.num_examples()
}
pub fn is_empty(&self) -> bool {
self.context.is_empty()
}
}
unsafe impl<T> Send for Suite<T> where T: Send {}
unsafe impl<T> Sync for Suite<T> where T: Sync {}
pub fn suite<F, T>(name: &'static str, environment: T, body: F) -> Suite<T>
where
F: FnOnce(&mut Context<T>),
T: Clone + ::std::fmt::Debug,
{
let header = SuiteHeader {
label: SuiteLabel::Suite,
name,
};
suite_internal(header, environment, body)
}
pub fn describe<F, T>(name: &'static str, environment: T, body: F) -> Suite<T>
where
F: FnOnce(&mut Context<T>),
T: Clone + ::std::fmt::Debug,
{
let header = SuiteHeader {
label: SuiteLabel::Describe,
name,
};
suite_internal(header, environment, body)
}
pub fn given<F, T>(name: &'static str, environment: T, body: F) -> Suite<T>
where
F: FnOnce(&mut Context<T>),
T: Clone + ::std::fmt::Debug,
{
let header = SuiteHeader {
label: SuiteLabel::Given,
name,
};
suite_internal(header, environment, body)
}
fn suite_internal<F, T>(header: SuiteHeader, environment: T, body: F) -> Suite<T>
where
F: FnOnce(&mut Context<T>),
T: Clone + ::std::fmt::Debug,
{
let mut ctx = Context::new(None);
body(&mut ctx);
Suite::new(header, environment, ctx)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_suite() {
let suite = suite("name", (), |_| {});
assert_eq!(suite.header.label, SuiteLabel::Suite);
assert_eq!(suite.header.name, "name");
assert_eq!(suite.environment, ());
assert_eq!(suite.is_empty(), true);
assert_eq!(suite.num_examples(), 0);
}
#[test]
fn empty_describe() {
let describe = describe("name", (), |_| {});
assert_eq!(describe.header.label, SuiteLabel::Describe);
assert_eq!(describe.header.name, "name");
assert_eq!(describe.environment, ());
assert_eq!(describe.is_empty(), true);
assert_eq!(describe.num_examples(), 0);
}
#[test]
fn empty_given() {
let given = given("name", (), |_| {});
assert_eq!(given.header.label, SuiteLabel::Given);
assert_eq!(given.header.name, "name");
assert_eq!(given.environment, ());
assert_eq!(given.is_empty(), true);
assert_eq!(given.num_examples(), 0);
}
#[test]
fn non_empty_suite() {
let suite = suite("suite", (), |ctx| {
ctx.context("context", |_| {});
});
assert_eq!(suite.header.label, SuiteLabel::Suite);
assert_eq!(suite.header.name, "suite");
assert_eq!(suite.environment, ());
assert_eq!(suite.is_empty(), false);
assert_eq!(suite.num_examples(), 0);
}
}