Skip to main content

doido_model/
factory.rs

1//! Test factories (FactoryBot-style): build test records with unique sequences.
2//!
3//! A type implements [`Factory::build`] to produce a default instance — usually
4//! using [`sequence`] for unique fields — and gets [`Factory::build_list`] for
5//! free. Pair with [`crate::testing::TestDb`] to persist them.
6
7use std::sync::atomic::{AtomicU64, Ordering};
8
9static SEQUENCE: AtomicU64 = AtomicU64::new(1);
10
11/// A process-global, monotonically increasing counter for unique test values
12/// (FactoryBot `sequence`), e.g. `format!("user{}@example.com", sequence())`.
13pub fn sequence() -> u64 {
14    SEQUENCE.fetch_add(1, Ordering::Relaxed)
15}
16
17/// Builds test instances of a type.
18pub trait Factory: Sized {
19    /// Build one instance (typically using [`sequence`] for unique fields).
20    fn build() -> Self;
21
22    /// Build `n` instances.
23    fn build_list(n: usize) -> Vec<Self> {
24        (0..n).map(|_| Self::build()).collect()
25    }
26}