Summary
The literal presence check (_check_literals) compares extracted Gherkin literal values against body_constant_nodes from AST analysis. This fails when the test code uses Decimal("77000") — the AST sees a string constant "77000", but the Gherkin literal is parsed as int 77000. String "77000" != int 77000, so the check fails despite the value being clearly present.
Reproduction
Feature file:
Example: Escape updates last mid
Given trend_escape_bps of 30 and previous mid of 77000
When a trend escape is triggered at mid 76760
Then subsequent ticks use 76760 as the previous mid
Beehave extracts literals: [(30, int), (77000, int), (76760, int), (76760, int)]
Test code:
def test_escape_updates_last_mid():
snap = make_snapshot(reference_price=Decimal("77000"))
AST body_constant_nodes contains "77000" (str) but NOT 77000 (int). Check fails:
missing-literal: literal '77000' not found in function body
Current behavior
_check_literals does: if lit.value not in ti.body_constant_nodes — exact Python equality, so 77000 != "77000".
Suggested fix
Compare string representations instead of exact type equality. The intent of the literal check is to verify the value appears in the test body, not that it has the same Python type as the Gherkin parser produced. Something like:
lit_str = str(lit.value)
if not any(lit_str == str(node) for node in ti.body_constant_nodes):
# violation
Or more simply, normalize both sides to strings before comparison.
Workaround
Tests must include bare int literals (e.g., assert snap.reference_price == 77000) to produce int AST constants that match the Gherkin-extracted int literals. This adds noise assertions.
Summary
The literal presence check (
_check_literals) compares extracted Gherkin literal values againstbody_constant_nodesfrom AST analysis. This fails when the test code usesDecimal("77000")— the AST sees a string constant"77000", but the Gherkin literal is parsed as int77000. String"77000"!= int77000, so the check fails despite the value being clearly present.Reproduction
Feature file:
Beehave extracts literals:
[(30, int), (77000, int), (76760, int), (76760, int)]Test code:
AST
body_constant_nodescontains"77000"(str) but NOT77000(int). Check fails:Current behavior
_check_literalsdoes:if lit.value not in ti.body_constant_nodes— exact Python equality, so77000 != "77000".Suggested fix
Compare string representations instead of exact type equality. The intent of the literal check is to verify the value appears in the test body, not that it has the same Python type as the Gherkin parser produced. Something like:
Or more simply, normalize both sides to strings before comparison.
Workaround
Tests must include bare int literals (e.g.,
assert snap.reference_price == 77000) to produce int AST constants that match the Gherkin-extracted int literals. This adds noise assertions.