datasynth-test-utils
Test utilities and helpers for the SyntheticData workspace.
Overview
datasynth-test-utils provides shared testing infrastructure:
- Test Fixtures: Pre-configured test data and scenarios
- Assertion Helpers: Domain-specific assertions for financial data
- Mock Generators: Simplified generators for unit testing
- Snapshot Testing: Helpers for snapshot-based testing
Fixtures
Journal Entry Fixtures
#![allow(unused)]
fn main() {
use synth_test_utils::fixtures;
// Balanced two-line entry
let entry = fixtures::balanced_journal_entry();
assert!(entry.is_balanced());
// Entry with specific amounts
let entry = fixtures::journal_entry_with_amount(dec!(1000.00));
// Fraudulent entry for testing detection
let entry = fixtures::fraudulent_entry(FraudType::SplitTransaction);
}
Master Data Fixtures
#![allow(unused)]
fn main() {
// Sample vendors
let vendors = fixtures::sample_vendors(10);
// Sample customers
let customers = fixtures::sample_customers(20);
// Chart of accounts
let coa = fixtures::test_chart_of_accounts();
}
Amount Fixtures
#![allow(unused)]
fn main() {
// Benford-compliant amounts
let amounts = fixtures::sample_amounts(1000);
// Round-number biased amounts
let amounts = fixtures::round_amounts(100);
// Fraud-pattern amounts
let amounts = fixtures::suspicious_amounts(50);
}
Configuration Fixtures
#![allow(unused)]
fn main() {
// Minimal valid config
let config = fixtures::test_config();
// Manufacturing preset
let config = fixtures::manufacturing_config();
// Config with specific transaction count
let config = fixtures::config_with_transactions(10000);
}
Assertions
Balance Assertions
#![allow(unused)]
fn main() {
use synth_test_utils::assertions;
#[test]
fn test_entry_is_balanced() {
let entry = create_entry();
assertions::assert_balanced(&entry);
}
#[test]
fn test_trial_balance() {
let tb = generate_trial_balance();
assertions::assert_trial_balance_balanced(&tb);
}
}
Benford’s Law Assertions
#![allow(unused)]
fn main() {
#[test]
fn test_benford_compliance() {
let amounts = generate_amounts(10000);
assertions::assert_benford_compliant(&amounts, 0.05);
}
}
Document Chain Assertions
#![allow(unused)]
fn main() {
#[test]
fn test_p2p_chain() {
let documents = generate_p2p_flow();
assertions::assert_valid_document_chain(&documents);
}
}
Uniqueness Assertions
#![allow(unused)]
fn main() {
#[test]
fn test_no_duplicate_ids() {
let entries = generate_entries(1000);
assertions::assert_unique_document_ids(&entries);
}
}
Mock Generators
Simple Journal Entry Generator
#![allow(unused)]
fn main() {
use synth_test_utils::mocks::MockJeGenerator;
let mut generator = MockJeGenerator::new(42);
// Generate entries without full config
let entries = generator.generate(100);
}
Predictable Amount Generator
#![allow(unused)]
fn main() {
use synth_test_utils::mocks::MockAmountGenerator;
let mut generator = MockAmountGenerator::new();
// Returns predictable sequence
let amount1 = generator.next(); // 100.00
let amount2 = generator.next(); // 200.00
}
Fixed Date Generator
#![allow(unused)]
fn main() {
use synth_test_utils::mocks::MockDateGenerator;
let generator = MockDateGenerator::fixed(
NaiveDate::from_ymd_opt(2024, 1, 15).unwrap()
);
}
Snapshot Testing
#![allow(unused)]
fn main() {
use synth_test_utils::snapshots;
#[test]
fn test_je_serialization() {
let entry = fixtures::balanced_journal_entry();
snapshots::assert_json_snapshot("je_balanced", &entry);
}
#[test]
fn test_csv_output() {
let entries = fixtures::sample_entries(10);
snapshots::assert_csv_snapshot("entries_sample", &entries);
}
}
Test Helpers
Temporary Directories
#![allow(unused)]
fn main() {
use synth_test_utils::temp_dir;
#[test]
fn test_output_writing() {
let dir = temp_dir::create();
// Test writes to temp directory
let path = dir.path().join("test.csv");
write_output(&path)?;
assert!(path.exists());
// Directory cleaned up on drop
}
}
Seed Management
#![allow(unused)]
fn main() {
use synth_test_utils::seeds;
#[test]
fn test_deterministic_generation() {
let seed = seeds::fixed();
let result1 = generate_with_seed(seed);
let result2 = generate_with_seed(seed);
assert_eq!(result1, result2);
}
}
Time Helpers
#![allow(unused)]
fn main() {
use synth_test_utils::time;
#[test]
fn test_with_frozen_time() {
let frozen = time::freeze_at(2024, 1, 15);
let entry = generate_entry_with_current_date();
assert_eq!(entry.posting_date, frozen.date());
}
}
Usage in Other Crates
Add to Cargo.toml:
[dev-dependencies]
datasynth-test-utils = { path = "../datasynth-test-utils" }
Use in tests:
#![allow(unused)]
fn main() {
#[cfg(test)]
mod tests {
use synth_test_utils::{fixtures, assertions};
#[test]
fn test_my_function() {
let input = fixtures::test_config();
let result = my_function(&input);
assertions::assert_balanced(&result);
}
}
}
Fixture Data Files
Test data files in fixtures/:
datasynth-test-utils/
└── fixtures/
├── chart_of_accounts.yaml
├── sample_entries.json
├── vendor_master.csv
└── test_config.yaml