P3: assets' posted and scheduled depreciation, their bases, and the K-1 on the tax basis (defect 13, D-41)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
Book value is cost less what the books posted; the schedule's figure is apart. An asset's acquired date comes from its entry. Contributed property keeps its section 723 carryover basis apart from its depreciable basis (the lower of value and adjusted basis), with its 704(c) built-in gain and method. The K-1 worksheet reports tax-basis capital (Form 1065 Item L) beside the book figures, leaving open what only the CPA knows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3gXMVt7XJPi6ens1or9Dj
This commit is contained in:
81 files changed
+9391
-2604
No files matched your search
@@ -4,10 +4,10 @@
|
||||
//! INVARIANT it checks.
|
||||
|
||||
use chrono::NaiveDate;
|
||||
use ledger_core::{AssetRegister, AssetRegisterRow, TaxBasisRule};
|
||||
use ledger_core::{AssetRegister, AssetRegisterRow, BasisRule, Sec704cMethod};
|
||||
use ledger_import::asset_register::{
|
||||
layout, missing_line, notes, rule_cited, rule_label, rule_mark, template_data,
|
||||
typeset_asset_register,
|
||||
FMV_NOT_RECORDED_MARK, layout, method_cited, missing_line, notes, rule_cited, rule_label,
|
||||
rule_mark, template_data, typeset_asset_register,
|
||||
};
|
||||
use ledger_import::report::ReportMeta;
|
||||
use ledger_import::{PdfError, asset_register_pdf};
|
||||
@@ -31,68 +31,95 @@ fn meta() -> ReportMeta {
|
||||
}
|
||||
}
|
||||
|
||||
fn row(id: u64, tag: &str, desc: &str, cost: i64, acc: i64) -> AssetRegisterRow {
|
||||
/// A row: `scheduled` the schedule's accumulated depreciation, `posted`
|
||||
/// what the books carry; book value is cost less posted.
|
||||
fn row(id: u64, tag: &str, desc: &str, cost: i64, scheduled: i64, posted: i64) -> AssetRegisterRow {
|
||||
AssetRegisterRow {
|
||||
asset_id: id,
|
||||
tag: Some(tag.into()),
|
||||
description: desc.into(),
|
||||
serial: None,
|
||||
in_service: d(2026, 1, 15),
|
||||
acquired_date: d(2026, 1, 15),
|
||||
in_service_date: d(2026, 1, 15),
|
||||
cost: cents(cost),
|
||||
salvage: Decimal::ZERO,
|
||||
useful_life_months: 36,
|
||||
accumulated: cents(acc),
|
||||
book_value: cents(cost - acc),
|
||||
accumulated_scheduled: cents(scheduled),
|
||||
accumulated_posted: cents(posted),
|
||||
book_value: cents(cost - posted),
|
||||
disposed: None,
|
||||
tax_rule: None,
|
||||
contributor_basis: None,
|
||||
tax_basis: None,
|
||||
built_in_gain: None,
|
||||
basis_rule: None,
|
||||
contributor_adjusted_basis: None,
|
||||
fmv_at_contribution: None,
|
||||
fmv_recorded: false,
|
||||
tax_basis_723: None,
|
||||
depreciable_basis: None,
|
||||
built_in_gain_704c: None,
|
||||
sec704c_1c: false,
|
||||
sec704c_method: None,
|
||||
basis_source: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Bought: tax basis is cost.
|
||||
/// Bought: depreciable basis is cost.
|
||||
fn bought(mut r: AssetRegisterRow) -> AssetRegisterRow {
|
||||
r.tax_rule = Some(TaxBasisRule::Cost);
|
||||
r.tax_basis = Some(r.cost);
|
||||
r.basis_rule = Some(BasisRule::Purchase);
|
||||
r.depreciable_basis = Some(r.cost);
|
||||
r
|
||||
}
|
||||
|
||||
/// Contributed under `rule` with the member's basis `basis` (cents); tax
|
||||
/// basis and built-in gain as ledger_core::Asset computes them.
|
||||
fn contributed(mut r: AssetRegisterRow, rule: TaxBasisRule, basis: i64) -> AssetRegisterRow {
|
||||
/// Contributed under `rule` with the member's adjusted basis `basis`
|
||||
/// (cents) and its value `fmv` (cents; None: recorded before P3, read as
|
||||
/// the book cost); figures as ledger_core::kernel::basis_figures gives
|
||||
/// them.
|
||||
fn contributed(
|
||||
mut r: AssetRegisterRow,
|
||||
rule: BasisRule,
|
||||
basis: i64,
|
||||
fmv: Option<i64>,
|
||||
) -> AssetRegisterRow {
|
||||
let b = cents(basis);
|
||||
r.tax_rule = Some(rule);
|
||||
r.contributor_basis = Some(b);
|
||||
r.tax_basis = Some(match rule {
|
||||
TaxBasisRule::PersonalUseConversion => b.min(r.cost),
|
||||
_ => b,
|
||||
});
|
||||
r.built_in_gain = Some(r.cost - b);
|
||||
let v = fmv.map_or(r.cost, cents);
|
||||
let f = ledger_core::kernel::basis_figures(rule, r.cost, b, v).unwrap();
|
||||
r.basis_rule = Some(rule);
|
||||
r.contributor_adjusted_basis = Some(b);
|
||||
r.fmv_at_contribution = Some(v);
|
||||
r.fmv_recorded = fmv.is_some();
|
||||
r.tax_basis_723 = f.tax_basis_723;
|
||||
r.depreciable_basis = Some(f.depreciable_basis);
|
||||
r.built_in_gain_704c = f.built_in_gain_704c;
|
||||
r.sec704c_1c = f.built_in_gain_704c.is_some_and(|g| g < Decimal::ZERO);
|
||||
r
|
||||
}
|
||||
|
||||
fn register(rows: Vec<AssetRegisterRow>) -> AssetRegister {
|
||||
let held = || rows.iter().filter(|r| r.disposed.is_none());
|
||||
let total_cost = held().map(|r| r.cost).sum();
|
||||
let total_accumulated = held().map(|r| r.accumulated).sum();
|
||||
let total_tax_basis = held().filter_map(|r| r.tax_basis).sum();
|
||||
let missing_tax_basis = held().filter(|r| r.tax_basis.is_none()).count();
|
||||
let total_cost: Decimal = held().map(|r| r.cost).sum();
|
||||
let total_accumulated_scheduled: Decimal = held().map(|r| r.accumulated_scheduled).sum();
|
||||
let total_accumulated_posted: Decimal = held().map(|r| r.accumulated_posted).sum();
|
||||
AssetRegister {
|
||||
total_tax_basis,
|
||||
missing_tax_basis,
|
||||
as_of: d(2026, 10, 15),
|
||||
total_book_value: total_cost - total_accumulated,
|
||||
total_depreciable_basis: held().filter_map(|r| r.depreciable_basis).sum(),
|
||||
total_tax_basis_723: held().filter_map(|r| r.tax_basis_723).sum(),
|
||||
missing_basis: held().filter(|r| r.depreciable_basis.is_none()).count(),
|
||||
total_book_value: total_cost - total_accumulated_posted,
|
||||
ledger_cost: total_cost,
|
||||
ledger_accumulated: total_accumulated - cents(1234),
|
||||
ledger_accumulated: total_accumulated_scheduled - cents(1234),
|
||||
total_cost,
|
||||
total_accumulated,
|
||||
total_accumulated_scheduled,
|
||||
total_accumulated_posted,
|
||||
rows,
|
||||
}
|
||||
}
|
||||
|
||||
/// Hand-worked: held cost 2,500.00 + 1,299.00 + 1,750.00 + 800.00 =
|
||||
/// 6,349.00; scheduled 527.78 + 324.75 = 852.53; posted 500.00 + 324.75 =
|
||||
/// 824.75; book value 6,349.00 − 824.75 = 5,524.25; §723 basis 900.00 +
|
||||
/// 2,000.00 = 2,900.00; depreciable basis 2,500.00 + 900.00 + 1,750.00 =
|
||||
/// 5,150.00; the books carry 852.53 − 12.34 = 840.19 accumulated, so
|
||||
/// 12.34 isn't yet posted and 840.19 − 824.75 = 15.44 isn't from runs.
|
||||
fn sample() -> AssetRegister {
|
||||
let mut disposed = row(3, "FL-0003", "Old monitor", 40000, 0);
|
||||
let mut disposed = row(3, "FL-0003", "Old monitor", 40000, 0, 0);
|
||||
disposed.book_value = Decimal::ZERO;
|
||||
disposed.disposed = Some((d(2026, 9, 30), cents(4500)));
|
||||
let mut laptop = row(
|
||||
@@ -101,27 +128,41 @@ fn sample() -> AssetRegister {
|
||||
"Framework Laptop 13 (Ryzen 7 7840U, 64 GB, 4 TB)",
|
||||
250000,
|
||||
52778,
|
||||
50000,
|
||||
);
|
||||
laptop.serial = Some("FRANBMCP0A1234".into());
|
||||
laptop.salvage = cents(10000);
|
||||
laptop.acquired_date = d(2026, 1, 10);
|
||||
// A member's business laptop: carryover basis, built-in gain, its
|
||||
// value recorded, the traditional method chosen, the facts' source.
|
||||
let mut air = contributed(
|
||||
row(2, "FL-0002", "MacBook Air", 129900, 32475, 32475),
|
||||
BasisRule::Carryover723,
|
||||
90000,
|
||||
Some(129900),
|
||||
);
|
||||
air.sec704c_method = Some(Sec704cMethod::Traditional);
|
||||
air.basis_source = Some(ledger_core::settings::Source {
|
||||
decided_by: "Morgan Ellis".into(),
|
||||
decided_on: d(2026, 10, 20),
|
||||
citation: Some("entry 7".into()),
|
||||
note: None,
|
||||
});
|
||||
register(vec![
|
||||
bought(laptop),
|
||||
// A member's business laptop: carryover basis, built-in gain.
|
||||
contributed(
|
||||
row(2, "FL-0002", "MacBook Air", 129900, 32475),
|
||||
TaxBasisRule::Carryover,
|
||||
90000,
|
||||
),
|
||||
air,
|
||||
bought(disposed),
|
||||
// A member's personal camera: worth less than its basis, so tax
|
||||
// basis is the fair market value and there's a built-in loss.
|
||||
// A member's personal camera, recorded before P3 (value read as
|
||||
// the book cost): worth less than its basis, so the depreciable
|
||||
// basis is the value and there's a built-in loss.
|
||||
contributed(
|
||||
row(4, "FL-0004", "Sony A7 IV camera", 175000, 0),
|
||||
TaxBasisRule::PersonalUseConversion,
|
||||
row(4, "FL-0004", "Sony A7 IV camera", 175000, 0, 0),
|
||||
BasisRule::PersonalUseConversion,
|
||||
200000,
|
||||
None,
|
||||
),
|
||||
// No tax basis recorded yet.
|
||||
row(5, "FL-0005", "Standing desk", 80000, 0),
|
||||
row(5, "FL-0005", "Standing desk", 80000, 0, 0),
|
||||
])
|
||||
}
|
||||
|
||||
@@ -157,8 +198,10 @@ fn pdf_is_deterministic() {
|
||||
assert_eq!(a, asset_register_pdf(&r, &meta()).unwrap());
|
||||
}
|
||||
|
||||
/// INVARIANTS 1, 2, 3, 5: header, every asset, the status of each, the
|
||||
/// register's totals, and the reconciliation with both differences.
|
||||
/// INVARIANTS 1, 2, 3, 5: header, every asset with its acquired and
|
||||
/// in-service dates, the status of each, depreciation scheduled and
|
||||
/// posted, the register's totals, and the reconciliation with its three
|
||||
/// differences.
|
||||
#[test]
|
||||
fn pdf_shows_assets_totals_and_reconciliation() {
|
||||
let t = all_text(&sample(), &meta());
|
||||
@@ -166,22 +209,26 @@ fn pdf_shows_assets_totals_and_reconciliation() {
|
||||
"Fernhill Labs LLC",
|
||||
"Fixed Asset Register",
|
||||
"As of October 15, 2026",
|
||||
"ACQUIRED",
|
||||
"IN SERVICE",
|
||||
"DEPRECIATION SCHEDULED",
|
||||
"DEPRECIATION POSTED",
|
||||
"FL-0001",
|
||||
"FRANBMCP0A1234",
|
||||
"2026-01-10 2026-01-15",
|
||||
"MacBook Air",
|
||||
"Active",
|
||||
"Disposed 2026-09-30, proceeds 45.00",
|
||||
"Total, assets held",
|
||||
"6,349.00", // cost held: 2,500.00 + 1,299.00 + 1,750.00 + 800.00
|
||||
"852.53", // accumulated held
|
||||
"5,496.47", // book value held: 6,349.00 - 852.53
|
||||
"$6,349.00 $852.53 $824.75 $5,524.25",
|
||||
"Cost per register",
|
||||
"Cost per books",
|
||||
"Difference (unregistered cost)",
|
||||
"Accumulated depreciation per schedule",
|
||||
"Accumulated depreciation per books",
|
||||
"Difference (not yet posted)",
|
||||
"12.34",
|
||||
"Difference (not yet posted) $12.34",
|
||||
"Accumulated depreciation from the assets' runs",
|
||||
"Difference (not from runs) $15.44",
|
||||
"Journal seq 314",
|
||||
] {
|
||||
assert!(t.contains(s), "{s:?} missing from {t:?}");
|
||||
@@ -189,45 +236,58 @@ fn pdf_shows_assets_totals_and_reconciliation() {
|
||||
// The disposed asset's cost (400.00) is shown but in no total.
|
||||
assert!(t.contains("400.00"));
|
||||
let l = layout(&sample());
|
||||
assert_eq!(l.totals, [cents(634900), cents(85253), cents(549647)]);
|
||||
assert_eq!(
|
||||
l.totals,
|
||||
[cents(634900), cents(85253), cents(82475), cents(552425)]
|
||||
);
|
||||
}
|
||||
|
||||
/// INVARIANTS 7-9: the tax table shows each rule in short words, the
|
||||
/// contributor's basis, the tax basis, the built-in gain and loss, the
|
||||
/// register's tax basis total, the missing line, and the notes with
|
||||
/// their citations.
|
||||
/// value at contribution (marked when read as the book cost), the
|
||||
/// contributor's adjusted basis, the §723 basis, the depreciable basis,
|
||||
/// the built-in gain and loss, the method and the facts' source under the
|
||||
/// description, the register's tax totals, the missing line, and the
|
||||
/// notes with their citations.
|
||||
#[test]
|
||||
fn pdf_shows_tax_basis() {
|
||||
fn pdf_shows_723_and_depreciable_basis() {
|
||||
let r = sample();
|
||||
let t = all_text(&r, &meta());
|
||||
for s in [
|
||||
"Federal tax basis",
|
||||
"TAX BASIS RULE",
|
||||
"CONTRIBUTOR'S BASIS",
|
||||
"Federal tax figures, at contribution or purchase",
|
||||
"BASIS RULE",
|
||||
"VALUE AT CONTRIBUTION",
|
||||
"CONTRIBUTOR'S ADJUSTED BASIS",
|
||||
"§723 BASIS",
|
||||
"DEPRECIABLE BASIS",
|
||||
"BUILT-IN GAIN (LOSS)",
|
||||
"Carryover",
|
||||
"Personal-use conversion",
|
||||
"900.00", // MacBook: contributor's basis = tax basis
|
||||
"399.00", // its built-in gain
|
||||
"2,000.00", // camera: contributor's basis
|
||||
"1,750.00", // its tax basis: the fair market value
|
||||
"(250.00)", // its built-in loss: 1,750.00 - 2,000.00
|
||||
"Not recorded",
|
||||
"Total tax basis, assets held",
|
||||
"5,150.00", // 2,500.00 + 900.00 + 1,750.00; the desk has none
|
||||
// MacBook: cost, value, adjusted basis, §723, depreciable, gain.
|
||||
"Carryover 2 1,299.00 1,299.00 900.00 900.00 900.00 399.00",
|
||||
"Traditional (Treas. Reg. §1.704-3(b))",
|
||||
"Morgan Ellis, 2026-10-20: entry 7",
|
||||
// Camera: value read as cost (marked), basis 2,000.00, the lesser.
|
||||
"Personal-use conversion 3 1,750.00 * 1,750.00 2,000.00 2,000.00 1,750.00 (250.00)",
|
||||
"Standing desk Not recorded 800.00",
|
||||
"Total, assets held $2,900.00 $5,150.00",
|
||||
"Tax basis not recorded for 1 asset",
|
||||
"Notes",
|
||||
"Book value is the fair market value at contribution",
|
||||
"IRC §1012(a)",
|
||||
"Book value is cost less the depreciation the books carry",
|
||||
"IRC §1012",
|
||||
"IRC §723",
|
||||
"IRC §1016(a)",
|
||||
"Treas. Reg. §1.168(i)-4(b)",
|
||||
// The PDF wraps "§1.704-3(a)(3)(ii)" between its parentheses.
|
||||
"Treas. Reg. §1.704-3(a) (3)(ii)",
|
||||
"IRC §704(c)(1)(C)",
|
||||
"Value at contribution not recorded as a fact",
|
||||
] {
|
||||
assert!(t.contains(s), "{s:?} missing from {t:?}");
|
||||
}
|
||||
let l = layout(&r);
|
||||
assert_eq!(l.tax_total, r.total_tax_basis);
|
||||
assert_eq!(l.tax_total, cents(515000));
|
||||
assert_eq!(
|
||||
l.tax_totals,
|
||||
[r.total_tax_basis_723, r.total_depreciable_basis]
|
||||
);
|
||||
assert_eq!(l.tax_totals, [cents(290000), cents(515000)]);
|
||||
assert_eq!(
|
||||
l.missing.as_deref(),
|
||||
Some("Tax basis not recorded for 1 asset")
|
||||
@@ -235,10 +295,19 @@ fn pdf_shows_tax_basis() {
|
||||
assert_eq!(l.notes, notes());
|
||||
// Each line carries its row's tax fields unchanged.
|
||||
for (line, row) in l.lines.iter().zip(&r.rows) {
|
||||
assert_eq!(line.tax_rule, row.tax_rule);
|
||||
assert_eq!(line.contributor_basis, row.contributor_basis);
|
||||
assert_eq!(line.tax_basis, row.tax_basis);
|
||||
assert_eq!(line.built_in_gain, row.built_in_gain);
|
||||
assert_eq!(line.basis_rule, row.basis_rule);
|
||||
assert_eq!(line.fmv_at_contribution, row.fmv_at_contribution);
|
||||
assert_eq!(line.fmv_recorded, row.fmv_recorded);
|
||||
assert_eq!(
|
||||
line.contributor_adjusted_basis,
|
||||
row.contributor_adjusted_basis
|
||||
);
|
||||
assert_eq!(line.tax_basis_723, row.tax_basis_723);
|
||||
assert_eq!(line.depreciable_basis, row.depreciable_basis);
|
||||
assert_eq!(line.built_in_gain_704c, row.built_in_gain_704c);
|
||||
assert_eq!(line.sec704c_method, row.sec704c_method.map(method_cited));
|
||||
assert_eq!(line.accumulated_posted, row.accumulated_posted);
|
||||
assert_eq!(line.accumulated_scheduled, row.accumulated_scheduled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,11 +315,11 @@ fn pdf_shows_tax_basis() {
|
||||
/// (a disposed one without doesn't count), and the plural reads right.
|
||||
#[test]
|
||||
fn missing_line_only_when_missing() {
|
||||
let mut gone = row(1, "FL-0001", "Old monitor", 40000, 0);
|
||||
let mut gone = row(1, "FL-0001", "Old monitor", 40000, 0, 0);
|
||||
gone.book_value = Decimal::ZERO;
|
||||
gone.disposed = Some((d(2026, 9, 30), cents(4500)));
|
||||
let r = register(vec![bought(row(2, "FL-0002", "Desk", 50000, 0)), gone]);
|
||||
assert_eq!(r.missing_tax_basis, 0);
|
||||
let r = register(vec![bought(row(2, "FL-0002", "Desk", 50000, 0, 0)), gone]);
|
||||
assert_eq!(r.missing_basis, 0);
|
||||
assert_eq!(layout(&r).missing, None);
|
||||
assert!(!all_text(&r, &meta()).contains("Tax basis not recorded"));
|
||||
assert_eq!(missing_line(0), None);
|
||||
@@ -260,36 +329,46 @@ fn missing_line_only_when_missing() {
|
||||
);
|
||||
}
|
||||
|
||||
/// INVARIANT 7: the rules in words, short and with their citations.
|
||||
/// INVARIANT 7: the rules in words, short and with their citations; the
|
||||
/// methods with their paragraphs.
|
||||
#[test]
|
||||
fn rule_words() {
|
||||
use TaxBasisRule::*;
|
||||
use BasisRule::*;
|
||||
assert_eq!(
|
||||
[Cost, Carryover, PersonalUseConversion].map(rule_label),
|
||||
["Cost", "Carryover", "Personal-use conversion"]
|
||||
[Purchase, Carryover723, PersonalUseConversion].map(rule_label),
|
||||
["Purchase", "Carryover", "Personal-use conversion"]
|
||||
);
|
||||
assert_eq!(
|
||||
[Cost, Carryover, PersonalUseConversion].map(rule_cited),
|
||||
[Purchase, Carryover723, PersonalUseConversion].map(rule_cited),
|
||||
[
|
||||
"Cost",
|
||||
"Purchase (IRC §1012)",
|
||||
"Carryover (IRC §723)",
|
||||
"Personal-use conversion (Treas. Reg. §1.168(i)-4(b))"
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
Sec704cMethod::ALL.map(method_cited),
|
||||
[
|
||||
"Traditional (Treas. Reg. §1.704-3(b))".to_string(),
|
||||
"Traditional with curative allocations (Treas. Reg. §1.704-3(c))".to_string(),
|
||||
"Remedial (Treas. Reg. §1.704-3(d))".to_string(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/// INVARIANT 9: the notes number the rules 1, 2, 3 (the general note
|
||||
/// first and unnumbered, the built-in gain note 4), each rule's note
|
||||
/// cites that rule, and the PDF marks each recorded line's rule with its
|
||||
/// note's number; a line with no rule recorded has no mark.
|
||||
/// first and unnumbered, the built-in gain note 4, the value read as cost
|
||||
/// "*"), each rule's note cites that rule, and the PDF marks each
|
||||
/// recorded line's rule with its note's number; a line with no rule
|
||||
/// recorded has no mark.
|
||||
#[test]
|
||||
fn rule_marks_match_their_notes() {
|
||||
use TaxBasisRule::*;
|
||||
let rules = [Cost, Carryover, PersonalUseConversion];
|
||||
use BasisRule::*;
|
||||
let rules = [Purchase, Carryover723, PersonalUseConversion];
|
||||
assert_eq!(rules.map(rule_mark), ["1", "2", "3"]);
|
||||
let n = notes();
|
||||
let marks: Vec<&str> = n.iter().map(|n| n.mark.as_str()).collect();
|
||||
assert_eq!(marks, ["", "1", "2", "3", "4"]);
|
||||
assert_eq!(marks, ["", "1", "2", "3", "4", FMV_NOT_RECORDED_MARK]);
|
||||
for rule in rules {
|
||||
let note = n.iter().find(|n| n.mark == rule_mark(rule)).unwrap();
|
||||
let cites = format!("{}: ", rule_cited(rule));
|
||||
@@ -308,15 +387,15 @@ fn rule_marks_match_their_notes() {
|
||||
// The PDF: the mark right after the rule, the note under its number.
|
||||
let t = all_text(&r, &meta());
|
||||
for s in [
|
||||
"(Ryzen 7 7840U, 64 GB, 4 TB) Cost 1 2,500.00",
|
||||
"MacBook Air Carryover 2 1,299.00",
|
||||
"Old monitor Cost 1 400.00",
|
||||
"(Ryzen 7 7840U, 64 GB, 4 TB) Purchase 1 2,500.00",
|
||||
"Carryover 2 1,299.00",
|
||||
"Old monitor Purchase 1 400.00",
|
||||
"Sony A7 IV camera Personal-use conversion 3 1,750.00",
|
||||
"Standing desk Not recorded 800.00",
|
||||
"1 Cost: property the company bought",
|
||||
"2 Carryover (IRC §723): property a member contributes",
|
||||
"3 Personal-use conversion (Treas. Reg. §1.168(i)-4(b)): property converted",
|
||||
"4 Built-in gain (loss):",
|
||||
"1 Purchase (IRC §1012): property the company bought",
|
||||
"2 Carryover (IRC §723): the company's basis in property a member contributes",
|
||||
"3 Personal-use conversion (Treas. Reg. §1.168(i)-4(b)): the §723 basis",
|
||||
"4 Built-in gain (loss), IRC §704(c):",
|
||||
] {
|
||||
assert!(t.contains(s), "{s:?} missing from {t:?}");
|
||||
}
|
||||
@@ -334,6 +413,7 @@ fn empty_register_renders() {
|
||||
"No fixed assets",
|
||||
"Total, assets held",
|
||||
"Difference (not yet posted)",
|
||||
"Difference (not from runs)",
|
||||
] {
|
||||
assert!(t.contains(s), "{s:?} missing from {t:?}");
|
||||
}
|
||||
@@ -342,7 +422,7 @@ fn empty_register_renders() {
|
||||
/// INVARIANT 6: markup in every text field prints literally and never runs.
|
||||
#[test]
|
||||
fn text_is_data() {
|
||||
let mut a = row(1, "#FL-*1*", "#panic() *bold* $x$ <l> @r [x] \\", 100, 0);
|
||||
let mut a = row(1, "#FL-*1*", "#panic() *bold* $x$ <l> @r [x] \\", 100, 0, 0);
|
||||
a.serial = Some("_u_ // /*".into());
|
||||
let m = ReportMeta {
|
||||
company: "#co *Inc*".into(),
|
||||
@@ -357,7 +437,7 @@ fn text_is_data() {
|
||||
for s in [
|
||||
"#panic()", "*", "_", "$", "[", "]", "\\", "#", "<a>", "@a", "//", "/*", "\"", "`",
|
||||
] {
|
||||
let mut a = row(1, s, s, 100, 0);
|
||||
let mut a = row(1, s, s, 100, 0, 0);
|
||||
a.serial = Some(s.into());
|
||||
let m = ReportMeta {
|
||||
company: s.into(),
|
||||
@@ -379,6 +459,7 @@ fn long_register_paginates_landscape() {
|
||||
&format!("Asset {i}"),
|
||||
100_000,
|
||||
1_000,
|
||||
1_000,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
Reference in new issue
Block a user