From 187fcf75edb5045b0f117753cd9ca0b20ac88a4a Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sun, 6 Jan 2019 08:30:54 +0000 Subject: [PATCH] journal: clarify balance assertion/display precision interaction Surprisingly, balance assertions were checking to maximum precision, which meant it was possible, with a display-precision-limiting commodity directive, to have a failing assertion with the error message showing asserted and actual amounts that looked the same. Now we round the calculated account balance (but not the asserted balance) to display precision before comparing. This should ensure assertions always behave as you would expect from visual inspection. --- hledger-lib/Hledger/Data/Journal.hs | 4 +++- hledger-lib/hledger_journal.m4.md | 28 +++++++++++++++++++++++ tests/journal/balance-assertions.test | 32 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 5f25f53f8..94d551bc0 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -585,7 +585,9 @@ checkBalanceAssertion _ _ = Right () checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String () checkBalanceAssertionCommodity p assertedamt actualbal - | isReallyZeroAmount diff = Right () + -- this effectively compares the actual balance rounded to display precision (I believe), + -- with the asserted balance as written. See examples in balance assertions manual. + | isZeroAmount diff = Right () | True = Left err where assertedcomm = acommodity assertedamt diff --git a/hledger-lib/hledger_journal.m4.md b/hledger-lib/hledger_journal.m4.md index 7f63f0e65..93e6a4884 100644 --- a/hledger-lib/hledger_journal.m4.md +++ b/hledger-lib/hledger_journal.m4.md @@ -466,6 +466,34 @@ Balance assertions are checked against all postings, both real and [virtual](#virtual-postings). They are not affected by the `--real/-R` flag or `real:` query. +### Assertions and precision + +The calculated account balance is rounded to display precision before checking. +Eg: here the calculated balance is $1.006. The commodity directive causes +users, and balance assertions, to see this rounded to two decimal places, ie $1.01, +so this assertion passes: +```journal +commodity $1000.00 + +2019/01/01 + (a) $0.006 + +2019/01/02 + (a) $1.00 = $1.01 +``` + +The asserted balance is not rounded to display precision. So this assertion fails: +```journal +commodity $1000.00 + +2019/01/01 + (a) $0.006 + +2019/01/02 + (a) $1.00 = $1.007 +# calculated: $1.01 +# asserted: $1.007 (difference: +$0.001) +``` ## Balance Assignments diff --git a/tests/journal/balance-assertions.test b/tests/journal/balance-assertions.test index e247f668e..5b52d86a4 100755 --- a/tests/journal/balance-assertions.test +++ b/tests/journal/balance-assertions.test @@ -365,3 +365,35 @@ hledger -f- stats >>> >>>2 /unexpected '@'/ >>>=1 + +# 21. The calculated balance is rounded to display precision before checking. +# Here the calculated balance is $1.005 but users, and balance assertions, +# see it as $1.00 (because the commodity directive set display precision to 2). +hledger -f- stats +<<< +commodity $1000.00 + +2019/01/01 + (a) $0.006 + +2019/01/02 + (a) $1.00 = $1.01 + +>>> /Transactions/ +>>>2 +>>>=0 + +# 22. The asserted balance is not rounded to display precision. +hledger -f- stats +<<< +commodity $1000.00 + +2019/01/01 + (a) $0.006 + +2019/01/02 + (a) $1.00 = $1.007 + +>>> +>>>2 /difference: \+\$0\.001/ +>>>=1