Skip to content

feat(coverage): report real per-arm execution counts in BRDA #1061

Closed

Description

@Chemaclass

Problem

Branch coverage records whether an arm was taken, never how often. compute_branch_hits (src/coverage/branches.sh:223) emits taken_count as 0 or 1, documented as an MVP limit, and report_lcov writes that straight into BRDA (src/coverage/report_lcov.sh:64).

LCOV consumers read the BRDA fourth field as an execution count. Reporting 1 for an arm taken 5,000 times and 1 for an arm taken once loses the distinction that makes branch data useful: which paths are exercised in earnest and which are grazed by a single test.

The per-line data needed already exists. _BASHUNIT_COVERAGE_HITS_BY_LINE holds real execution counts, which is what LCOV DA records emit today.

Proposal

Report the arm's execution count instead of a taken flag.

  • _arm_taken (src/coverage/branches.sh:204) returns on the first hit line. Instead, take the count of the arm's first executable line, which is the closest analogue to how other tools count an arm entry.
  • Decide the rule explicitly and document it: first executable line's count, or the maximum across the arm's lines. First-line count is the honest one for an arm, since later lines can be skipped by an early return.
  • BRDA then carries a real count, and BRH still counts arms with a non-zero count, so existing summaries stay valid.

Low priority next to the correctness issues in this audit. It improves data quality, it does not correct a wrong number.

Where to change

  • src/coverage/branches.sh:196-251 _arm_taken, compute_branch_hits
  • src/coverage/report_lcov.sh:60-69 BRDA emission
  • src/coverage/html_file.sh if the HTML report shows branch data

Acceptance criteria

  • BRDA reports the arm's execution count, not 0 or 1
  • An arm inside a loop that ran 10 times reports 10
  • An arm never taken still reports 0
  • BRF and BRH totals are unchanged for the same run
  • The chosen counting rule is documented in the function comment
  • genhtml accepts the output, tested on a real LCOV file
  • Both engines produce the same numbers (trap and xtrace)

Repo checklist (agent)

  • TDD: RED then GREEN then REFACTOR. Write the failing test first.
  • Bash 3.0+ only: no printf -v, no += append, no declare -A, no [[ ]], no ${var,,}, no &>>, no ${arr[-1]}.
  • The _branch_* helpers mutate their caller's locals through dynamic scoping on purpose and must stay in one file, see ADR-010 and the comment at src/coverage/branches.sh:196-202.
  • Gates: make sa, make lint, ./bashunit tests/, ./bashunit --parallel tests/. Never run shfmt -w.
  • CHANGELOG.md: one line under ## Unreleased.
  • One issue = one PR.

Activity

  1. self-assigned this
    on Aug 13, 2026
  2. Chemaclass commented on Aug 13, 2026

    @Chemaclass
    MemberAuthor

    Done in #1083 (merged).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions