Conversation
…st.ts and assert whole files Each test spawned up to four bun processes. The re-install and --frozen-lockfile checks after the command under test proved the same property in 82 places. Keep that check in one test per bun.lock write path and drop the rest, plus three setup installs whose result no assertion used. 272 bun spawns become 226. The test count stays 149. Assertions now compare the whole package.json files, the whole catalog-relevant state of bun.lock (catalog sections, workspace rows, resolved versions), and the exact list of note: lines the command printed. Error tests assert the specific error text.
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. 💤 Files selected but had no reviewable changes (1)
⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
Status: closed. The CI numbers did not support the speed claim (16.45 s in this PR's build #100573 against 15.68 s in baseline build #100495 on the asan lane, and the file's shard is not the one that sets the lane's wall time). See the closing comment below for the details and for the small assertion-only change that could be opened on request. Verification that was done: |
There was a problem hiding this comment.
I reviewed this PR and didn't find any bugs. Because it removes 46 verification spawns (re-install / --frozen-lockfile checks) and replaces them with the new lockState() shape assertion across ~90 tests, a human look at the coverage tradeoff would still be worthwhile — specifically whether the retained 33 re-install checks cover every distinct bun.lock write path the dropped ones used to guard.
Checked: expectOk dropping the panic: check matches CLAUDE.md guidance; the new strict note: assertion is a superset of the old stderr.not.toContain("note:") sites; lockState() correctly filters @workspace: rows and conditionally spreads catalog/catalogs; the three removed setup installs each have their result covered by a later step in the same test.
Extended reasoning...
Overview
This PR refactors test/cli/install/bun-add-catalog.test.ts (test-only, ~1000 lines of diff, 149 tests before and after). It cuts 46 redundant subprocess spawns (272 → 226) by dropping re-install and --frozen-lockfile verification runs from tests where the same property is now asserted via a new lockState() helper that compares the full catalog/catalogs/workspaces/resolved shape of bun.lock with toStrictEqual. It also strengthens most remaining assertions: whole-object root()/pkg1()/pkg2() comparisons, strict note: line matching in expectOk, exact error messages in the two failure tests, and (no changes) in installSavesNothing.
Security risks
None. This is a test file for bun add --catalog; no production code, auth, or crypto is touched.
Level of scrutiny
Medium-high. Per REVIEW.md, "Never silently weaken, skip, or delete an existing test or safety net. Every deletion needs a stated reason or replacement." The PR does both — the description enumerates exactly which 29 tests keep re-install checks (one or two per bun.lock write path) and why the other 31 are redundant, and every dropped check is replaced by a stricter lockState() assertion. However, the re-install check and the lockState() check prove slightly different properties: re-install proves bun itself computes the same lockfile from the edited package.json files (self-consistency), while lockState() proves the lockfile matches a hand-authored expected shape. The PR's argument that 33 retained re-install checks suffice to cover every distinct write path is well-reasoned but is a coverage judgment a maintainer should confirm.
Other factors
- The bug hunting system found nothing. I verified the new helpers:
lockState()correctly usesrow[0].includes("@workspace:")to filter workspace rows and conditionally spreadscatalog/catalogssotoStrictEqualstill catches unexpected sections;expectOk's newnote:filter is order-sensitive and defaults to[], which is strictly stronger than the old scatterednot.toContain("note:")checks; dropping thepanic:check aligns with the repo rule that such checks never fail in CI. - The three removed setup installs are each justified in the description (e.g., the second
bun pm packtest now relies on the precedingbun addto write bun.lock, which is the documented behavior). - The diff is large and touches nearly every test in the file. No test names or ordering changed (verified against the description's #36284 compatibility note), so slow-test tracking and the pending PR that edits
name only in peerDependenciesare unaffected. - Both
bun bd testandUSE_SYSTEM_BUN=1 bun testpass per the author's verification, so the strengthened assertions match current behavior.
|
The review above asks whether the kept re-install checks cover the write paths of the dropped ones. Here is the mapping, dropped check first, kept test after the arrow. The count in parentheses is the number of runs when a site is a loop body. The 31 runs add up.
The 12 dropped |
|
Closing this after a self-review of the premise.
Without the speed gain, what is left is a rewrite of the assertions in a file that other open PRs add tests to (#36284 for one). The coverage that is new here is small: the exact The branch stays available for reference. |
Problem
test/cli/install/bun-add-catalog.test.tsis the slowest install test file without a speed pass: 16 s on debian 13 x64-asan (build 100495), 1.3 s with a release build.bun --versionalone). The asan runner also capsdescribe.concurrentat 5 tests (src/options_types/context.rs:506). So the wall time of this file is about the spawn count divided by 5.bun installorbun install --frozen-lockfilerun after the command under test. All 82 prove the same property: the bun.lock the command wrote is in sync with the package.json files it edited. Three more spawns are setup installs whose result no assertion used.pkg1().dependencies,root().workspaces.catalog,lock.catalog) and proved the absence of a version withlockText().not.toContain("no-deps@2.0.0"). 16 tests checked onlystderr not.toContain("error:")plus the exit code. Two error tests checked only that stderr containserror:.Fix
--optional, a dist-tag the target already declared, a seed into the catalog that acatalog:namereference points at, an override,workspaces.catalogwinning over a top-levelcatalog), a reused entry (a new consumer, a declared range, a tarball the target declared,catalogs.defaultspelled both ways, both objects present), a moved resolution (hoisted, isolated, named catalog), a replaced entry other members use, a converted direct range, nameless tarball positionals (member, root,--filter, mixed with a name, kept direct next to a different entry, local tarball),npm:aliases,--filterwith mixed outcomes and with two catalogs, a plainbun addthat uses the default entry,bun update --latest,bun remove. Drop the other 31 runs.--frozen-lockfilewhere it is the subject (pnpm windows: bunx fails when node is not installed #8795, two tests) or the install step of the--lockfile-onlytests. Drop the 12 runs that followed a re-install check or replaced one.'*' alone edits the members...,edits only the filtered member..., and thebun pm packtest whosebun addwrites the bun.lock that pack needs.add, 31 setup installs, 33 re-installs, 6 frozen installs, 12 update, pack, remove andinstall <pkg>runs). 149 tests before and after. No test was removed or merged.lockState()returns the catalog sections, every workspace row, and the resolved version of every non-workspace package from bun.lock. 92 call sites compare it withtoStrictEqual. This replaces the single-field checks and thenot.toContainversion checks, and adds bun.lock coverage to tests that did not read it (placement,--peer,--only-missing, the overrideupdaterows, the plain-add rows).root(),pkg1()andpkg2()are compared as whole objects.expectOkcompares the exact list ofnote:lines the command printed (none by default) and rejectswarn:. This asserts thecatalog entry X changed from A to B (also used by pkg2)note in six tests and its form without the suffix in one. This file never asserted that note before.installSavesNothingalso asserts the install reported(no changes). Tests with a tarball package passrelinks, because bun re-links a tarball package on every install, with or without a catalog (see details).--silenttests assert stdout and stderr are empty.--dry-runand--no-saveassert stdout reportsinstalled no-deps@2.0.0.--lockfile-onlyassertsSaved bun.lock (3 packages)and that the frozen install reports2 packages installed. The overrideupdaterows assert(no changes)and an unchanged root.bun removeasserts its- no-depsrows, that no-deps left the packages section, and that both catalog sections stayed.error: GET <url> - 404line and exit code 1. The pnpm windows: bunx fails when node is not installed #8795 tests asserterror: lockfile had changes, but lockfile is frozen, the note that names the catalog, and that bun.lock kept the old entry.name only in peerDependenciestest is byte for byte unchanged, so install: move existing dependency whenbun addis given an explicit group flag #36284 still applies on top of this branch (checked withgit apply --check). No test was renamed or reordered.bun bd test test/cli/install/bun-add-catalog.test.ts, 149 pass. Timing, three interleaved rounds on one machine, before then after: 14.31 s / 13.44 s, 15.05 s / 14.08 s, 14.72 s / 13.60 s. Best of each: 14.31 s before, 13.44 s after. About 3.7 s of both numbers is fixed: the debug runner starts in 2.75 s and verdaccio in 1 s.USE_SYSTEM_BUN=1 bun testalso passes, in 1.25 s.Background
bun add <pkg> --catalogwrites the catalog entry into the root package.json and acatalog:reference into the target. After the install it derives the catalog sections of bun.lock from the final package.json files. The re-install check proves that derivation matched: a secondbun installfinds nothing to save.bun adddoes, decides the wall time of this file.<workspace>/<name>when it is nested under a workspace.lockState().resolveduses those keys, so a test with two resolutions of one name shows both.Measurements and levers that did not pay
Spawns before (counted by wrapping
Bun.spawn): 144add, 34 setup installs, 64 re-installs, 18--frozen-lockfile, 3install <pkg>, 5update, 2pm pack, 2remove. After: 144, 31, 33, 6, 3, 5, 2, 2.Per spawn on the debug asan build, uncontended:
bun --version106 ms,bun add --catalogwith a fresh cache 145 to 180 ms, no-opbun install148 ms,bun add --dry-run190 ms,--lockfile-only183 ms. So flags that skip the install work do not save anything.In-flight spawns during the file never exceeded 5, which is the asan default for
--max-concurrency. The nested plain describes do inherit the concurrency. Completion order interleaves across describes.A warm cache copied into every test dir (one
bun installinbeforeAll,cpSyncper test) makes everybun addresolve without a registry request, because a cached manifest is fresh for 300 s (src/install/npm.rs:578). It still lost about 3 s here: thecpSyncruns in the sanitized runner process and costs more than the downloads it saves. Not included.With
CIset, the harness runs verdaccio on the build under test. On the debug build that start takes 32 s here. The 149 tests take the same 13 to 14 s either way, so request serving is not the bottleneck on the asan lane either. That start time belongs to the harness and is out of scope for this file.test.eachtables were not introduced. They would not remove a spawn, and they rename tests, which #36284 and the slow-test tracking key on.Observation, unrelated to catalogs: after a package was installed from a tarball url or a local tarball, every later
bun installprints1 package installedfor it again (reproduced with plainbun add <url>in a project without workspaces, released build). The lockfile is not re-saved. Therelinksoption ininstallSavesNothingonly skips the(no changes)check for the six tests with such a package.