Skip to content

test(shell): align brace.test.ts nested-empty-variant cases with bash-5.2 literal {} - #34882

Merged
Jarred-Sumner merged 2 commits into
mainfrom
farm/6f04c7ce/fix-brace-test-merge-conflict
Jul 21, 2026
Merged

Jarred-Sumner merged 2 commits into
mainfrom
farm/6f04c7ce/fix-brace-test-merge-conflict

Conversation

@robobun

@robobun robobun commented Jul 21, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes test/js/bun/shell/brace.test.ts which is red on main (four hard failures on every lane, e.g. build 76627).

Cause

#34856 and #34865 were developed in parallel and merged three minutes apart. #34856 changed the brace lexer so a {...} group with no top-level comma is demoted to literal text (bash 5.2 semantics) before the parser sees it. #34865 added a nested with empty variant test.each block whose last four entries still expect the pre-#34856 behaviour. #34865's own commit message notes #34856 was addressing the literal-{} question separately; the rebase was textually clean so neither PR's CI caught the semantic overlap.

$.braces > nested with empty variant > {{a,}{b,}}   expected ["ab","a","b",""]   got ["{ab}","{a}","{b}","{}"]
$.braces > nested with empty variant > {x,a{}b}     expected ["x","ab"]          got ["x","a{}b"]
$.braces > nested with empty variant > {a,b{}}c     expected ["ac","bc"]         got ["ac","b{}c"]
$.braces > nested with empty variant > {x,{}y}      expected ["x","y"]           got ["x","{}y"]

bash 5.2.37 agrees with the new output in every case:

$ bash -c 'printf "[%s] " {{a,}{b,}}'   # [{ab}] [{a}] [{b}] [{}]
$ bash -c 'printf "[%s] " {x,a{}b}'     # [x] [a{}b]
$ bash -c 'printf "[%s] " {a,b{}}c'     # [ac] [b{}c]
$ bash -c 'printf "[%s] " {x,{}y}'      # [x] [{}y]

Fix

All four entries are removed from the nested with empty variant block: after #34856 none of them reach the parse_expansion/expand_nested path that block guards, because the lexer demotes their comma-less group to text first. The remaining ten entries in that block (notably p{q,{r,}{s,}}t, which still routes through expand_nested with sibling trailing-empty groups) continue to cover #34865's fix.

  • {{a,}{b,}} is moved to the comma-less brace group is literal (bash 5.2) block with the bash-correct expectation ["{ab}","{a}","{b}","{}"]. That block also runs each case through the actual shell in a subprocess, so the pattern now gets both $.braces() and end-to-end shell coverage.
  • {x,a{}b}, {a,b{}}c, {x,{}y} are dropped together with their now-inaccurate comment (which describes a 0-variant {} reaching the parser, a state that no longer exists). Their literal-{} behaviour is already asserted by p{q{},r}s / {a,b{}}z / {a,{}}z in that same block.

No src/ change: the runtime behaviour is correct (matches bash); only the stale expectations are realigned.

Verification

bun bd test test/js/bun/shell/brace.test.ts
# before: 39 pass, 4 fail
# after:  40 pass, 0 fail

[stamp-90s] gate passed · iteration 0 · 1 files touched

passes on PR (with fix)
Test-only change.

Debug/ASAN (expected pass):
$ bun bd test 'test/js/bun/shell/brace.test.ts'
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test test/js/bun/shell/brace.test.ts
info: syncing channel updates for nightly-2026-05-06-x86_64-unknown-linux-gnu
info: latest update on 2026-05-06 for version 1.97.0-nightly (e95e73209 2026-05-05)
info: component rust-src is up to date
info: checking for self-update (current version: 1.29.0)
bun test v1.4.0 (0ecd8eb85)

test/js/bun/shell/brace.test.ts:
(pass) $.braces > no-op [1.89ms]
(pass) $.braces > 2 [1.81ms]
(pass) $.braces > 3 [1.77ms]
(pass) $.braces > nested [1.63ms]
(pass) $.braces > nested 2 [2.01ms]
(pass) $.braces > nested sibling product [1.71ms]
(pass) $.braces > nested sibling product with surrounding text [1.44ms]
(pass) $.braces > nested sibling product mixed with variants [1.97ms]
(pass) $.braces > nested sibling product triple [2.04ms]
(pass) $.braces > nested with empty variant > {x,a{,}b} [1.46ms]
(pass) $.braces > nested with empty variant > {x,{a,}}z [0.65ms]
(pass) $.braces > nested with empty variant > {x,{,a}}z [0.48ms]
(pass) $.braces > nested with empty variant > {x,{,}}z [0.47ms]
(pass) $.braces > nested with empty variant > a{b,c{d,}}e [0.52ms]
(pass) $.braces > nested with empty variant > a{b,c{,d}}e [0.48ms]
(pass) $.braces > nested with empty variant > {x,{a,,b}} [0.74ms]
(pass) $.braces > nested with empty variant > {x,{a,b,}} [0.47ms]
(pass) $.braces > nested with empty variant > {{a,},x} [0.49ms]
(pass) $.braces > nested with empty variant > p{q,{r,}{s,}}t [0.51ms]
(pass) $.braces > very deeply nested [2.81ms]
(pass) $.braces > empty string [2.88ms]
(pass) $.braces > unicode [2.43ms]
(pass) brace + glob composition > src/*.{ts,tsx} globs after brace expansion [62.79ms]
(pass) brace + glob composition > {src,lib}/*.ts composes a brace prefix with a glob [27.96ms]
(pass) brace + glob composition > an interpolated comma inside a brace group is one literal branch [22.66ms]
(pass) $.braces input bounds > rejects a word with an excessive number of br
... (truncated)
Exit: 0
diff hotspot
test/js/bun/shell/brace.test.ts | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

gate history · 1 passed · 0 rejected · iteration 0

evidence per changed file
file                             reads  edits  tests
test/js/bun/shell/brace.test.ts      2      3      0

…-5.2 literal {}

#34856 and #34865 were developed in parallel and merged minutes apart.
#34856 makes the lexer demote any comma-less {...} group to literal text
(bash 5.2 semantics); #34865 added test cases to the nested-empty-variant
block that still expected the parser to treat a nested {} as one empty
variant. After both landed, four of those cases assert the pre-#34856
output and fail on every lane.

- {{a,}{b,}}: update expectation to ["{ab}","{a}","{b}","{}"]. The
  outer group has no top-level comma so its braces are literal; the inner
  {a,}/{b,} still exercise the trailing-empty-variant parser path this
  block exists to cover.
- {x,a{}b}, {a,b{}}c, {x,{}y}: drop. The code path their comment
  described (parser seeing a 0-variant {}) no longer exists because the
  lexer demotes {} to text first, and the resulting literal-{} behaviour
  is already asserted by p{q{},r}s / {a,b{}}z / {a,{}}z in the
  comma-less-is-literal block #34856 added.

All four updated/removed expectations match bash 5.2.37 exactly.
@robobun

robobun commented Jul 21, 2026 •

Copy link
Copy Markdown
Collaborator Author

Status: brace.test.ts green locally (40 pass / 0 fail on bun bd). Test-only change; runtime already matches bash 5.2. Addressed review nit in 0ecd8eb (moved {{a,}{b,}} to the comma-less-is-literal block since it now dispatches to expand_flat, not expand_nested). Waiting on CI.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3026e373-5e18-4b9f-9982-88b1ec01b53e

📥 Commits

Reviewing files that changed from the base of the PR and between 13f5dec and 0ecd8eb.

📒 Files selected for processing (1)
  • test/js/bun/shell/brace.test.ts

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Jul 21, 2026 •

Copy link
Copy Markdown
Collaborator Author
Updated 11:05 PM PT - Jul 20th, 2026

@robobun, your commit 0ecd8eb is building: #76652

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — test-only fix for the #34856/#34865 merge race; updated expectations match bash 5.2 and the three dropped {} cases are already covered in the comma-less brace group is literal block. The inline nit about which code path {{a,}{b,}} now dispatches to is worth a look but non-blocking (the next entry p{q,{r,}{s,}}t still covers expand_nested).

Extended reasoning...

Overview

This PR touches only test/js/bun/shell/brace.test.ts. Two PRs (#34856: comma-less {...} is literal; #34865: nested trailing-empty variant fix) merged three minutes apart with a textually-clean but semantically-conflicting rebase, leaving four hard failures on main. The change updates one expectation ({{a,}{b,}} → ["{ab}","{a}","{b}","{}"]) and deletes three cases ({x,a{}b}, {a,b{}}c, {x,{}y}) whose documented code path — a 0-variant {} reaching the nested parser — no longer exists because the lexer demotes comma-less groups to text first.

Security risks

None. Test-only; no runtime, parser, or build changes.

Level of scrutiny

Low. This is a mechanical realignment of stale test expectations with already-merged runtime behaviour. I verified all five affected inputs against bash 5.2 locally and each matches the new/implied expectations exactly. I also confirmed the three deleted inputs' literal-{} behaviour is asserted by p{q{},r}s / {a,b{}}z / {a,{}}z in the comma-less brace group is literal (bash 5.2) block, so no coverage is lost — consistent with REVIEW.md's "every deletion needs a stated reason or replacement".

Other factors

The bug hunter raised one nit: the new comment on {{a,}{b,}} claims the inner {a,}/{b,} still exercise the nested trailing-empty path, but tracing tokenize_impl → flatten_tokens shows contains_nested stays false (the outer braces become Text, so brace_count never exceeds 1) and the input dispatches to expand_flat. This is a comment-accuracy issue only — the assertion is correct, and the very next entry p{q,{r,}{s,}}t genuinely routes through expand_nested with sibling trailing-empty groups, so #34865's fix remains guarded. Not worth blocking a red-main fix over.

Comment thread test/js/bun/shell/brace.test.ts Outdated
After #34856 demotes the outer braces to text, this input dispatches to
expand_flat (brace_count never exceeds 1), not the expand_nested path
the nested-empty-variant block guards. Move it to the block that tests
the behaviour it actually exercises; p{q,{r,}{s,}}t in the original
block still covers sibling trailing-empty groups through expand_nested.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM — thanks for moving {{a,}{b,}} to the comma-less block in 0ecd8eb; that addresses the nit and the case now also runs through the shell subprocess assertion.

Extended reasoning...

Overview

Test-only change to test/js/bun/shell/brace.test.ts fixing four hard failures on main caused by a semantic merge conflict between #34856 (comma-less {...} demoted to literal in the lexer) and #34865 (nested trailing-empty-variant fix). Drops three test.each entries whose documented code path (parser encountering a 0-variant {}) no longer exists post-#34856, and moves {{a,}{b,}} with its bash-5.2-aligned expectation to the comma-less brace group is literal block.

Security risks

None. Pure test-expectation update; no src/ change.

Level of scrutiny

Low. This is un-breaking a red test file on main by aligning stale expectations with runtime behaviour that already matches bash 5.2. The dropped cases' literal-{} behaviour is already asserted by p{q{},r}s / {a,b{}}z / {a,{}}z in the same file, and the nested trailing-empty path #34865 fixed remains covered by p{q,{r,}{s,}}t, so no coverage is lost. I verified the moved case's expectation locally against bash (printf "[%s] " {{a,}{b,}} → [{ab}] [{a}] [{b}] [{}]).

Other factors

My earlier nit (the case was in the wrong describe with a comment misstating which parser path it exercises) was addressed in 0ecd8eb — the case now sits alongside {a{b,c}} in the comma-less block where it belongs, and picks up the shell-subprocess assertion for free via the shared cases array. The PR description states each deletion's reason and names the surviving coverage, satisfying REVIEW.md's "every deletion needs a stated reason or replacement".

@Jarred-Sumner
Jarred-Sumner merged commit 2b90109 into main Jul 21, 2026
49 of 62 checks passed
@Jarred-Sumner
Jarred-Sumner deleted the farm/6f04c7ce/fix-brace-test-merge-conflict branch July 21, 2026 04:59
robobun added a commit that referenced this pull request Jul 21, 2026
Picks up #34882 (brace.test.ts nested-empty-variant fix): faa769d
merged main at 13f5dec, before #34882 landed, so 76654 had the
briefly-broken brace.test.ts from #34865 without its follow-up fix.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants