Make CLI test substring matches CRLF-tolerant on Windows#512
Conversation
The --print rollout in #510 anchored ~36 assertions on the bare-value line via `out.includes("\n<value>\n")`, which fails on Windows because Pascal's WriteLn writes CRLF — so the captured stdout contains `\r\n<value>\r\n` and the substring is never present. Add a small `containsLine` helper to each test-cli script that strips \r before matching, and route every \n<value>\n check through it. The change is a no-op on Linux/macOS and unblocks the cli/windows-latest job in CI (run 25309261679). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR consolidates CLI test utilities into shared modules and improves assertion robustness. It creates ChangesTest Infrastructure Centralization
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Review rate limit: 3/5 reviews remaining, refill in 19 minutes and 7 seconds. Comment |
Suite TimingTest Runner (interpreted: 8,599 passed; bytecode: 8,599 passed)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.
Benchmarks (interpreted: 407; bytecode: 407)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.
Measured on ubuntu-latest x64. |
Benchmark Results407 benchmarks Interpreted: 🟢 60 improved · 🔴 30 regressed · 317 unchanged · avg +1.0% arraybuffer.js — Interp: 🟢 1, 🔴 2, 11 unch. · avg +0.0% · Bytecode: 🟢 4, 🔴 5, 5 unch. · avg -0.7%
arrays.js — Interp: 🟢 2, 🔴 1, 16 unch. · avg +0.7% · Bytecode: 🔴 4, 15 unch. · avg -1.5%
async-await.js — Interp: 6 unch. · avg -0.5% · Bytecode: 🟢 1, 🔴 1, 4 unch. · avg +0.1%
async-generators.js — Interp: 2 unch. · avg -0.4% · Bytecode: 🟢 1, 1 unch. · avg +2.3%
base64.js — Interp: 🟢 1, 🔴 1, 8 unch. · avg +0.5% · Bytecode: 🟢 4, 🔴 1, 5 unch. · avg +2.6%
classes.js — Interp: 🟢 3, 🔴 2, 26 unch. · avg +0.6% · Bytecode: 🟢 10, 🔴 1, 20 unch. · avg +1.6%
closures.js — Interp: 🟢 2, 9 unch. · avg +1.2% · Bytecode: 🟢 2, 9 unch. · avg +1.9%
collections.js — Interp: 🔴 2, 10 unch. · avg -0.4% · Bytecode: 🔴 2, 10 unch. · avg -1.6%
csv.js — Interp: 🟢 2, 11 unch. · avg +1.4% · Bytecode: 🟢 2, 🔴 1, 10 unch. · avg +1.8%
destructuring.js — Interp: 🟢 2, 20 unch. · avg +1.4% · Bytecode: 🟢 3, 🔴 5, 14 unch. · avg +0.2%
fibonacci.js — Interp: 8 unch. · avg +0.8% · Bytecode: 🔴 1, 7 unch. · avg -1.1%
float16array.js — Interp: 🟢 9, 23 unch. · avg +1.3% · Bytecode: 🟢 8, 🔴 7, 17 unch. · avg +0.9%
for-of.js — Interp: 🟢 1, 6 unch. · avg +1.6% · Bytecode: 7 unch. · avg -1.3%
generators.js — Interp: 4 unch. · avg -0.9% · Bytecode: 🔴 3, 1 unch. · avg -2.4%
iterators.js — Interp: 🟢 4, 🔴 4, 34 unch. · avg +0.2% · Bytecode: 🟢 13, 🔴 1, 28 unch. · avg +1.9%
json.js — Interp: 🟢 3, 🔴 1, 16 unch. · avg +0.8% · Bytecode: 🟢 1, 19 unch. · avg +0.3%
jsx.jsx — Interp: 🟢 3, 18 unch. · avg +1.3% · Bytecode: 🟢 3, 🔴 6, 12 unch. · avg -0.8%
modules.js — Interp: 🟢 2, 7 unch. · avg +3.4% · Bytecode: 9 unch. · avg -1.0%
numbers.js — Interp: 🟢 1, 10 unch. · avg +1.7% · Bytecode: 🔴 2, 9 unch. · avg -0.2%
objects.js — Interp: 🟢 2, 5 unch. · avg +1.0% · Bytecode: 🟢 1, 🔴 1, 5 unch. · avg +0.7%
promises.js — Interp: 12 unch. · avg +0.1% · Bytecode: 12 unch. · avg +1.4%
regexp.js — Interp: 🟢 4, 7 unch. · avg +2.6% · Bytecode: 🟢 3, 🔴 1, 7 unch. · avg +1.7%
strings.js — Interp: 🟢 3, 🔴 1, 15 unch. · avg +0.9% · Bytecode: 🟢 6, 🔴 1, 12 unch. · avg +1.6%
tsv.js — Interp: 🟢 1, 8 unch. · avg +1.3% · Bytecode: 🟢 4, 5 unch. · avg +2.8%
typed-arrays.js — Interp: 🟢 2, 🔴 6, 14 unch. · avg -8.0% · Bytecode: 🟢 1, 🔴 7, 14 unch. · avg -5.9%
uint8array-encoding.js — Interp: 🟢 1, 🔴 10, 7 unch. · avg -18.6% · Bytecode: 🟢 8, 🔴 1, 9 unch. · avg +5.3%
weak-collections.js — Interp: 🟢 11, 4 unch. · avg +40.4% · Bytecode: 🟢 7, 8 unch. · avg +5.7%
Deterministic profile diffDeterministic profile diff: no significant changes. Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
test262 Conformance
Areas closest to 100%
Compatibility roadmap skips
Non-blocking. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached |
Replace the three inline copies of the CRLF-tolerant `containsLine` helper added in the previous commit with a single shared module so future test-cli additions share the implementation instead of hand-copying it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/test-cli-helpers.ts`:
- Around line 13-14: The containsLine helper currently uses s.replace(/\r/g,
"").includes(`\n${value}\n`) which misses first/last lines; change containsLine
to split the string on /\r?\n/ (preserves CRLF handling) and check exact
equality against value (e.g., const lines = s.split(/\r?\n/); return
lines.includes(value)); update the exported function name containsLine
accordingly so single-line outputs and edges are handled correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dbe19145-b03e-43b1-a968-e261f05cdc98
📒 Files selected for processing (4)
scripts/test-cli-apps.tsscripts/test-cli-config.tsscripts/test-cli-helpers.tsscripts/test-cli.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- scripts/test-cli.ts
| export const containsLine = (s: string, value: string): boolean => | ||
| s.replace(/\r/g, "").includes(`\n${value}\n`); |
There was a problem hiding this comment.
Use a real line split here.
replace(/\r/g, "").includes(\\n${value}\n`)still misses values on the first or last line, so this helper is brittle for single-line outputs. Splitting on/\r?\n/` and checking exact line equality would keep the CRLF fix and make the helper behave like its name suggests.
♻️ Suggested fix
-export const containsLine = (s: string, value: string): boolean =>
- s.replace(/\r/g, "").includes(`\n${value}\n`);
+export const containsLine = (s: string, value: string): boolean =>
+ s.split(/\r?\n/).some((line) => line === value);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const containsLine = (s: string, value: string): boolean => | |
| s.replace(/\r/g, "").includes(`\n${value}\n`); | |
| export const containsLine = (s: string, value: string): boolean => | |
| s.split(/\r?\n/).some((line) => line === value); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/test-cli-helpers.ts` around lines 13 - 14, The containsLine helper
currently uses s.replace(/\r/g, "").includes(`\n${value}\n`) which misses
first/last lines; change containsLine to split the string on /\r?\n/ (preserves
CRLF handling) and check exact equality against value (e.g., const lines =
s.split(/\r?\n/); return lines.includes(value)); update the exported function
name containsLine accordingly so single-line outputs and edges are handled
correctly.
Consolidates the duplicated bits across all five scripts/test-cli*.ts
harnesses into a small role-split module:
scripts/test-cli/
binaries.ts — LOADER, BARE, REPL, TESTRUNNER, BUNDLER, BENCHRUNNER
assertions.ts — containsLine, normalizeLineEndings
tmpdir.ts — mkdtemp, makeTmpFactory, clean
Each consumer now imports only what it needs. The test-cli-helpers.ts
single-file shim added in the previous commit is removed; tmpdir-prefix
binding stays close to each harness via either makeTmpFactory("...")
(when one prefix per file) or mkdtemp("...") inline (when prefixes
differ per block, like test-cli.ts).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
The
--printrollout in #510 anchored ~36 assertions on the bare-value line viaout.includes(`\n${value}\n`), which fails on Windows because Pascal'sWriteLnwrites CRLF — so the captured stdout contains\r\n<value>\r\nand the substring is never present. The Windows CLI job in CI run 25309261679 failed on the very first such check (Stdin smoke (interpreted)).Changes
containsLine(out, value)helper to each of the threescripts/test-cli*.tsfiles that strips\rbefore substring matching.out.includes("\n<value>\n")site through the helper (9 intest-cli.ts, 5 intest-cli-apps.ts, 22 intest-cli-config.ts).The helper is a no-op on Linux/macOS (no
\rto strip), so existing platforms remain unaffected.Test plan
bun run scripts/test-cli.tspasses locally on macOSbun run scripts/test-cli-apps.tspasses locally on macOSbun run scripts/test-cli-config.tspasses locally on macOScli (i386-win32)andcli (x86_64-win64)jobs go green🤖 Generated with Claude Code