Skip to main content

Module testonly

Module testonly 

Source
Expand description

Shared synthetic corpora + per-journey fixtures for the worked-example journeys (J1–J9).

Hoisted here (from xtask, TUI-walkthrough spec §4.1) so ALL consumers share ONE source of truth: the xtask examples generator, and the btctax-tui / btctax-tui-edit screen-walkthrough emit tests. A plain pub module (like btctax_forms::testonly) — the corpora are tiny synthetic CSVs, and the generator’s generate() is a non-test fn, so they cannot be #[cfg(test)].

The CSV corpora carry explicit CRLF: committed .csv files are force-LF’d by .gitattributes and would break the Coinbase parser, so they live as string consts (a driver writes them to a tempdir at runtime). These bytes are byte-identical to their previous home in xtask/src/examples.rs — the examples_golden_matches_committed gate proves the move changed nothing.

Structs§

JourneyFixture
One journey’s synthetic input: the named corpus files a driver writes to a tempdir before import. The SAME fixture seeds both walkthrough capture halves (the editor emit test drives its flows; the viewer emit test re-seeds this corpus and replays the equivalent decisions via btctax-cli), so the two halves of a journey converge by construction on one source of truth (walkthrough spec §4.2).

Constants§

J1_CSV
J1 corpus: a single-buyer happy path — one Buy + one partial Sell in 2025.
J2_CSV
J2 corpus: an LT lot (2023) + an ST lot (2025) + a 2025 Send of 2 BTC donated to charity.
J3_CSV
J3 corpus: a Buy + a Receive (an inbound transfer with unknown basis → a hard blocker until classified).
J4_CSV
J4 corpus: two River staking-income deposits in 2025 (FMV resolved from the bundled dataset).
J5_CSV
J5 corpus: an LT lot + a higher-basis ST lot + a 2025 sell — a genuine changed-selection scenario (HIFO ≠ FIFO) so the optimizer has a tax-saving pick to propose.
J6_COINBASE_CSV
J6 Coinbase corpus: a cheap 2020 long-term lot, a small 2024 sale, and a 2024 charitable Send of 0.1 BTC (§170(e) donation ⇒ Form 8283). NOTE: HIFO reconstruction draws the 2024 sale from the higher-basis 2024 mining lot (not this 2020 lot) ⇒ it is SHORT-term (Schedule D Part I). Amounts kept small so the return stays under the AMT screen.
J6_FULLRETURN_TOML
The committed full-return ReturnInputs (the kitchen_sink_household() oracle, TOML-serialized). J6 imports it via income import. The fixture lives in this crate (self-contained), so this is a SAME-crate include_str! — retiring the cross-crate include the xtask copy carried (M-5 exception).
J6_RIVER_CSV
J6 River corpus: one small 2024 business mining-income deposit (FMV from the bundled dataset). Kept modest deliberately: the kitchen-sink household clears the 2024 Form-6251 AMT-screen worksheet by only a thin margin — a corpus editor who enlarges the sale, income, or donation must keep the household on the computable side of that screen.
J7_CSV
J7 corpus (UX-P1-7): a single 2024 Coinbase Receive of staking rewards — an unknown-basis inbound the single-event classify-inbound-income command values only from a hand-supplied --fmv.
J8_COINBASE_CSV
J8 Coinbase corpus (UX-P1-8): the matching inbound Receive of 0.10 BTC — the SAME coins landing at a second exchange, so the pair is a cross-wallet RELOCATE (not a same-wallet DROP).
J8_RIVER_CSV
J8 River corpus (UX-P1-8): a buy (to give the coins a basis) then a Withdrawal OUT of 0.10 BTC — the out-leg of a cross-exchange self-transfer whose in-leg lands on Coinbase below.
J9_CSV
J9 corpus (UX-P1-10): a cheap 2023 long-term lot (0.60) + a pricier 2024 lot (0.40), then a 2025 sale of only 0.50 — less than the combined holdings, so specific-lot identification is meaningful.

Functions§

j1
The nine journey fixtures, keyed by the same corpus filenames the examples journeys use.
j2
j3
j4
j5
j6
j7
j8
J8 — the PoC journey: a cross-exchange self-transfer (River Withdrawal out → Coinbase Receive in).
j9
seed_j1_with_profile
Seed J1 (single buyer: one Buy + one partial Sell, no transfers → no reconciliation) and set the 2025 tax profile its walkthrough VIEWER needs for the Tax tab to compute — single filer, $100k ordinary income, mirroring the J1 worked example’s tax-profile step. The viewer half then only opens + reads.
seed_j2_donated
Seed J2’s fully post-decision state — the outbound reclassified as a donation, the Form 8283 appraiser/donee details recorded (Section B complete), and a 2025 profile so the viewer’s Tax tab computes the charitable-deduction line. The walkthrough’s VIEWER renders Forms (the two 8283 rows) + Tax. Made-date threaded from the caller.
seed_j2_reclassified
Seed J2 with the outbound Send reclassified as a §170(e) charitable DONATION (FMV $217,992.34 = 2 BTC × the contribution-date close, donee “Habitat for Humanity”) — but WITHOUT the Form 8283 appraiser/donee details yet. This is the state the walkthrough’s d (set-donation-details) EDITOR frame drives from (the details form still empty). Made-date threaded from the caller.
seed_j3_self_transfer
Seed J3 (an unknown-basis inbound Receive → a hard blocker) classified as a SELF-TRANSFER of the filer’s own coins returning — non-taxable, carrying a supplied basis ($19,000) and acquisition date (2024-11-01, so the holding period runs from then). The post-classify state the VIEWER renders (Holdings). The editor half seeds only the raw import and drives the classify. Made-date threaded from the caller.
seed_j4_reclassified
Seed J4 (two River staking receipts) with a 2025 profile AND both receipts reclassified as a trade or business (--business true --kind staking) — the post-reclassify state the walkthrough’s VIEWER half renders (Income now on Schedule C/SE; Tax shows the self-employment tax). The editor half drives the reclassify itself, so it seeds only the raw import (seed_journey(&j4())). Made-date pinned for determinism. Refs embed the ms-timestamp of each receipt (not wall-clock).
seed_j5_elected
Seed J5 (an LT lot $30k + a higher-basis ST lot $80k + a 2025 sale $50k) with a 2025 profile AND a standing FIFO election — but NOT the optimizer’s accept. This is the state the walkthrough’s z (optimize-accept) EDITOR frames drive from: the optimizer proposes swapping to the ST lot to realize a loss. The election made-date is hardcoded 2025-01-01 (the engine blocks effective_from before the made-date, so a later threaded now would trip MethodElectionBackdated).
seed_j5_optimized
Seed J5’s post-accept state — the FIFO election PLUS the optimizer’s proposed lot pick accepted (the whole sale moved onto the short-term opt-buy-st lot to realize a loss). The walkthrough’s VIEWER renders the resulting Disposals (ST loss) + Tax (§1211 deduction + carryforward). now is the accept made-date — MUST be ≤ the 2025-06-01 sale so the selection is Contemporaneous; the caller passes the same instant the editor frames pin.
seed_j6_full
Seed J6 — a COMPLETE Form 1040 (the kitchen-sink MFJ household). Combines the crypto reconciliation (mining income → a trade or business; the 0.10 BTC Send → a §170(e) donation with Form 8283 details) with the non-crypto household imported from the committed kitchen_sink_household() TOML. This is the state BOTH walkthrough halves render: the editor half opens the tax-inputs authoring form (T) over these committed inputs; the viewer shows Forms (the crypto forms) + Tax (the merged MFJ return). No raw tax-profile — the full-return inputs take precedence and build_snapshot derives the MFJ profile from them. Made-date threaded from the caller.
seed_j7_income
Seed J7 (a single off-exchange Receive with no market price → a hard unknown-basis blocker) classified as staking INCOME with a hand-supplied FMV ($3,300), plus a 2024 profile — the post-classify state the walkthrough’s VIEWER renders (Income + Tax). The editor half seeds only the raw import and drives the classify. Made-date threaded from the caller (matches the depicted editor session’s clock).
seed_j8_relocated
Seed J8 and apply its RELOCATE self-transfer (river out → coinbase in) — the post-match state the walkthrough’s VIEWER half renders (BALANCED). Refs are J8’s deterministic event refs; RELOCATE routes to link_transfer (out → in), the same decision the editor’s confirm modal makes.
seed_j9_selected
Seed J9 (a cheap 2023 LT lot 0.60 + a pricier 2024 lot 0.40, then a 2025 sale of 0.50 — less than the combined holdings, so specific-lot identification is meaningful) with the whole 0.50 IDENTIFIED against the cheap long-term lot-a (a deliberate per-disposal specific identification). The post-selection state the walkthrough’s VIEWER renders (Disposals drawing from lot-a; Compliance now satisfied). The editor half seeds only the raw import and drives the select-lots flow. Made-date threaded from the caller (the identification is contemporaneous — before/at the sale).
seed_journey
Init a vault at dir/vault.pgp and import the journey fx’s corpus via the REAL adapter ingest.