use fluent_test::prelude::*;
use once_cell::sync::Lazy;
use std::cell::RefCell;
use std::sync::{
Mutex,
atomic::{AtomicUsize, Ordering},
};
static SETUP_COUNTER: AtomicUsize = AtomicUsize::new(0);
static TEST_VALUE_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
static INNER_TEST_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
static OUTER_TEST_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
thread_local! {
static TEST_VALUE: RefCell<u32> = RefCell::new(0);
}
fn set_test_value(value: u32) {
TEST_VALUE.with(|v| {
*v.borrow_mut() = value;
});
}
fn get_test_value() -> u32 {
TEST_VALUE.with(|v| *v.borrow())
}
#[with_fixtures_module]
mod module_fixtures {
use super::*;
#[setup]
fn setup_function() {
SETUP_COUNTER.fetch_add(1, Ordering::SeqCst);
TEST_VALUE.with(|v| {
*v.borrow_mut() = 0;
});
}
#[tear_down]
fn teardown_function() {
expect!(get_test_value()).to_equal(42);
}
#[test]
fn test_fixtures_are_applied_automatically() {
let _guard = TEST_VALUE_MUTEX.lock().unwrap();
let setup_count = SETUP_COUNTER.load(Ordering::SeqCst);
expect!(setup_count).to_be_greater_than(0);
expect!(get_test_value()).to_equal(0);
set_test_value(42);
expect!(get_test_value()).to_equal(42);
std::thread::sleep(std::time::Duration::from_millis(5));
}
#[test]
fn test_fixtures_run_for_each_test() {
let _guard = TEST_VALUE_MUTEX.lock().unwrap();
expect!(get_test_value()).to_equal(0);
let setup_count = SETUP_COUNTER.load(Ordering::SeqCst);
expect!(setup_count).to_be_greater_than(0);
set_test_value(42);
expect!(get_test_value()).to_equal(42);
std::thread::sleep(std::time::Duration::from_millis(5));
}
}
mod nested_module_test {
use super::*;
#[setup]
fn outer_setup() {
SETUP_COUNTER.fetch_add(10, Ordering::SeqCst); TEST_VALUE.with(|v| {
*v.borrow_mut() = 100;
});
}
#[tear_down]
fn outer_teardown() {
expect!(get_test_value()).to_equal(150);
}
#[with_fixtures_module]
mod inner_module {
use super::*;
#[setup]
fn inner_setup() {
SETUP_COUNTER.fetch_add(1, Ordering::SeqCst);
TEST_VALUE.with(|v| {
*v.borrow_mut() = 200;
});
}
#[tear_down]
fn inner_teardown() {
expect!(get_test_value()).to_equal(250);
}
#[test]
fn test_inner_fixtures_are_applied() {
let _guard = INNER_TEST_MUTEX.lock().unwrap();
expect!(get_test_value()).to_equal(200);
set_test_value(250);
expect!(get_test_value()).to_equal(250);
std::thread::sleep(std::time::Duration::from_millis(5));
}
}
#[test]
#[with_fixtures]
fn test_outer_fixtures_explicit() {
let _guard = OUTER_TEST_MUTEX.lock().unwrap();
expect!(get_test_value()).to_equal(100);
set_test_value(150);
expect!(get_test_value()).to_equal(150);
std::thread::sleep(std::time::Duration::from_millis(5));
}
}