From 65dd11d26b671e858c4b8c96584c38d116ee5303 Mon Sep 17 00:00:00 2001 From: Stephen Waits <1+swaits@noreply.git.swaits.com> Date: Sun, 11 Oct 2026 02:26:00 +0000 Subject: [PATCH] asset slice + testing initiative: fixed assets, property/mutation/fuzz testing, docs --- fuzz/fuzz_targets/fuzz_entry_validate.rs | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 fuzz/fuzz_targets/fuzz_entry_validate.rs diff --git a/fuzz/fuzz_targets/fuzz_entry_validate.rs b/fuzz/fuzz_targets/fuzz_entry_validate.rs new file mode 100644 index 0000000..f2d175c --- /dev/null +++ b/fuzz/fuzz_targets/fuzz_entry_validate.rs @@ -0,0 +1,51 @@ +// Fuzz target: arbitrary JSON as a journal entry. If validation accepts +// it, the entry MUST balance exactly — validation is the enforcement +// point, and this pins it. Staged here; `cargo fuzz init` wires it up. +#![no_main] + +use libfuzzer_sys::fuzz_target; +use ledger_core::{AccountType, Currency, JournalEntry, Ledger, Side}; +use rust_decimal::Decimal; + +fn test_chart() -> Ledger { + let mut ledger = Ledger::new(Currency::USD); + for (code, name, typ) in [ + ("1000", "Cash", AccountType::Asset), + ("2000", "Payable", AccountType::Liability), + ("3000", "Equity", AccountType::Equity), + ("4000", "Revenue", AccountType::Revenue), + ("6000", "Rent", AccountType::Expense), + ] { + ledger.add_account(code, name, typ, None, false).unwrap(); + } + ledger +} + +fuzz_target!(|data: &[u8]| { + if let Ok(entry) = serde_json::from_slice::(data) { + let ledger = test_chart(); + // Validation must never panic on hostile input. + if entry.validate(ledger.chart()).is_ok() { + let debits: Decimal = entry + .lines() + .iter() + .filter(|l| l.side == Side::Debit) + .map(|l| l.amount.amount) + .sum(); + let credits: Decimal = entry + .lines() + .iter() + .filter(|l| l.side == Side::Credit) + .map(|l| l.amount.amount) + .sum(); + assert_eq!( + debits, credits, + "validate() accepted an unbalanced entry: {entry:?}" + ); + assert!( + debits > Decimal::ZERO, + "validate() accepted a zero-total entry" + ); + } + } +});