Hi all,
Following the spec process thread earlier this year, I've put together
a tool aimed at the "completeness" problem Martin identified: the
0.8→1.0 gap where lots of little details are easy to miss.
beancompat is a black-box property test suite for beancount implementations:
https://github.com/TJesionowski/beancompat
The idea: exercise the full external interface that downstream tooling
(Fava, plugins, extensions) relies on, and document where
implementations diverge. This is descriptive, not normative, but the
worst incompatibilities are built by accident..
What's there now:
- Hand-written fixtures covering parse, booking, interpolation, BQL,
metadata, tags/links, flags, prices, cost inventory, and more
- Hypothesis-based generative tests that find unknown divergences by
checking agreement across implementations
- A language-independent fixture format (JSON pairs of .beancount
snippet + expected output) so non-Python implementations can consume
them directly without a Python harness
- Adapters for beancount v3 (reference), limabean, and rustledger
- Full Fava-compat capability surface: CAP_HASH, CAP_PLUGINS,
CAP_SUMMARIZE, CAP_INGEST, plus fixtures covering all 31
BeancountOptions keys Fava reads
What I've found so far:
A few concrete divergences are already documented against limabean and
rustledger:
1. Currency list ordering in `open` directives — limabean's currency
list is non-deterministic across runs. The allowed-currency list
appears to be iterated from a HashSet with randomized hashing rather
than preserved in source order. The generative test suite surfaced
this immediately.
2. `display_precision_by_currency` absent from options — rustledger's
DisplayContext has no public iterator over inferred precisions, so the
field is never populated. Parser-only adapters (beancount-parser-lima)
have the same gap for a different reason: no loader means dcontext is
never computed.
3. Options coverage gaps — against the 31-key fixture (all options
Fava reads): limabean rejects `plugin_processing_mode`,
`infer_tolerance_from_cost`, `render_commas`, and `booking_method` as
unknown (parse error on load); rustledger aliases
`tolerance_multiplier` and `inferred_tolerance_multiplier` so they
can't be set or reported independently.
These are documented as `known_divergences` in the fixture files.
TurboBean is on the radar and is the highest-value target given the
vNext inventory divergence, but the adapter is blocked on upstream
shipping a structured-output command. I haven't had time to update for
Martin's recent changes, but that's also on the list.
Feedback and contributions welcome. I would love to get a few
collaborators to keep this thing relevant, so if you're interested
just let me know.
Tim