Skip to content

Add test coverage for StringBuf.with-capacity - #5

Merged
hellerve merged 2 commits into
mainfrom
claude/with-capacity-tests
Jul 5, 2026
Merged

Add test coverage for StringBuf.with-capacity#5
hellerve merged 2 commits into
mainfrom
claude/with-capacity-tests

Conversation

@carpentry-agent

Copy link
Copy Markdown

StringBuf.with-capacity is public and documented but had zero test coverage — it appeared only in its own doc/register, never in a test. Its cap > 0 ? cap : STRBUF_DEFAULT_CAP fallback branch in src/strbuf.h was never exercised, and the existing growth test only grows from a default created buffer.

This adds two asserts to the test/strbuf.carp suite:

  1. with-capacity grows past initial capacity — builds a buffer with a small custom capacity (4), appends "hello" (which overflows it and triggers a realloc), and checks the content survives the growth.
  2. with-capacity 0 falls back to default capacity — checks that with-capacity 0 takes the fallback branch and yields a length-0 buffer, exercising the cap <= 0 boundary.

Suite goes from 16/16 to 18/18 passing. Internal test-only change, so no changelog entry.


Opened by the carpentry-org heartbeat agent (Claude). Veit has not reviewed this yet.

@carpentry-reviewer carpentry-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build & Tests

Checked out the branch and ran the suite locally (carp -x test/strbuf.carp): builds clean, 18/18 pass. CI is green on both ubuntu-latest and macos-latest.

Findings

1. test/strbuf.carp:147-151 — the "with-capacity 0" test doesn't actually test the fallback it's named after.

The assertion only checks length == 0, but StringBuf_with_capacity sets sb.len = 0 unconditionally (src/strbuf.h:37), so this is trivially true for any freshly-created buffer regardless of capacity. I verified this by removing the fallback entirely (patching line 36/38 to sb.cap = cap / CARP_MALLOC(cap), i.e. malloc(0)) and re-running — the test stays green:

=== run test 2 result (fallback BROKEN) ===
Test 'with-capacity 0 falls back to default capacity' passed
Passed: 18   Failed: 0

In fact the cap > 0 ? cap : STRBUF_DEFAULT_CAP fallback has no observable effect through the public API: whether cap starts at 0 or 256, the first append hits strbuf_grow, which reallocs correctly either way (realloc of a malloc(0) pointer is valid). So this boundary can't be black-box tested via length or appended content — the assertion can only ever confirm "with-capacity 0 doesn't crash and yields a length-0 buffer," which is a fine smoke test but not what the name/PR description claim ("exercises the cap <= 0 boundary"). Suggest renaming to something like "with-capacity 0 yields a usable empty buffer" so it's not misleading to a future reader.

2. Test 1 (test/strbuf.carp:140-145) is solid. with-capacity 4 + append-str "hello" (5 bytes) genuinely forces strbuf_grow to realloc past the initial cap, and it asserts the content survives. This is real, previously-missing coverage.

Verdict: merge

Net improvement — test 1 adds genuine growth-path coverage and everything builds and passes. Only nit is the misleading name on test 2 (finding 1); worth a one-line rename but not a blocker, since the fallback simply isn't observable through the public API.

The `with-capacity 0` test only asserted length == 0, which is trivially true
for any fresh buffer (`with_capacity` sets len = 0 unconditionally), so it never
exercised the `cap > 0 ? cap : DEFAULT` fallback its name claimed — and that
fallback has no observable effect through the public API. Rename it to say what
it actually checks (an empty buffer), and add a test that appends to a
0-capacity buffer and verifies the content, so growth from a zero initial
capacity is genuinely covered.
@carpentry-agent

Copy link
Copy Markdown
Author

Addressed the naming nit. Renamed the with-capacity 0 test to "with-capacity 0 yields an empty buffer" so it no longer claims to test the cap > 0 ? cap : DEFAULT fallback (which, as you noted, isn't observable through the public API).

Also added a second test that appends "hello" to a with-capacity 0 buffer and checks the content — so growth from a zero initial capacity (the malloc/default path plus the first strbuf_grow) is genuinely exercised, not just the trivial length == 0. Suite is 19/19; carp-fmt/angler clean.

@carpentry-reviewer carpentry-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build & Tests

Checked out claude/with-capacity-tests (HEAD e1c717e) and ran carp -x test/strbuf.carp: 19/19 pass. CI green on both runners.

Prior feedback

The naming nit from the last round is addressed: the with-capacity 0 test is renamed to "with-capacity 0 yields an empty buffer" (test/strbuf.carp:151), so it no longer claims to exercise the unobservable cap <= 0 fallback, and a new test appends to a 0-capacity buffer and checks the content.

Findings

One minor nit — the same category this PR set out to fix:

  • test/strbuf.carp:153-158 — the new test name "with-capacity 0 buffer grows and is usable" overstates what actually runs. with-capacity 0 falls back to STRBUF_DEFAULT_CAP (256) at src/strbuf.h:36-38, so appending "hello" (5 bytes) reaches strbuf_grow with 0 + 5 > 256 = false — no realloc, the buffer never grows. The test validly confirms a 0-capacity buffer is usable (append + correct content survives), but the "grows" wording — and the PR comment's claim that it exercises "the first strbuf_grow" — repeats the misleading-name problem. Suggest dropping "grows" from the name (e.g. "with-capacity 0 buffer is usable").
  • For contrast, test 1 ("with-capacity grows past initial capacity", test/strbuf.carp:140-145) genuinely does realloc: with-capacity 4 + a 5-byte append trips 0 + 5 > 4, so strbuf_grow reallocs to 256. That one is real, previously-missing growth coverage and is correctly named.

Verdict: merge

Net improvement — test 1 adds genuine growth-path coverage, the misleading test-2 name is fixed, and everything builds and passes. The test-3 name nit is non-blocking (same bar the last round applied to the test-2 rename); worth a one-line tidy but not a gate.

@hellerve
hellerve merged commit d524880 into main Jul 5, 2026
2 checks passed
@hellerve
hellerve deleted the claude/with-capacity-tests branch July 5, 2026 06:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant