Skip to content

Test JSON output via public CLI surface#142

Merged
frostney merged 6 commits into
mainfrom
fix/public-json-cli-tests
Mar 30, 2026
Merged

Test JSON output via public CLI surface#142
frostney merged 6 commits into
mainfrom
fix/public-json-cli-tests

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Mar 30, 2026

Summary

  • remove the internal ScriptLoader JSON native test and replace it with CLI-level JSON smoke coverage
  • keep TestRunner and BenchmarkRunner JSON assertions at the command/workflow layer
  • document that the testing strategy should prefer public surfaces over internal helper-level tests

Verification

  • ./format.pas --check
  • ./build.pas loader benchmarkrunner tests
  • local ScriptLoader JSON success/error smoke checks
  • local TestRunner and BenchmarkRunner JSON output checks

Summary by CodeRabbit

  • Chores

    • Added ScriptLoader JSON output validation to CI/CD pipelines, testing both success cases and error handling across default and bytecode execution modes.
  • Documentation

    • Updated testing strategy documentation to emphasize exercising public-facing APIs over implementation details, improving test maintainability and clarity.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Warning

Rate limit exceeded

@frostney has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 13 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 9 minutes and 13 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 90290c15-8b42-499c-ac76-4af2454b873d

📥 Commits

Reviewing files that changed from the base of the PR and between 295bfb7 and 5046f7d.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/pr.yml
  • AGENTS.md
  • docs/design-decisions.md
  • docs/testing.md
📝 Walkthrough

Walkthrough

The PR updates CI workflows to add ScriptLoader JSON smoke tests validating successful execution and error handling, removes the dedicated Pascal unit test for ScriptLoader JSON, and revises testing documentation to emphasize public-facing entry point coverage over private implementation testing.

Changes

Cohort / File(s) Summary
CI Workflows
.github/workflows/ci.yml, .github/workflows/pr.yml
Added identical "Run ScriptLoader JSON smoke tests" steps that validate ScriptLoader JSON output for successful and error scenarios in both default and bytecode modes.
Testing Documentation
AGENTS.md, docs/design-decisions.md, docs/testing.md
Updated testing guidance to prioritize public-facing entry points (CLI, JavaScript APIs) over internal implementation details; introduced routing rules favoring JavaScript feature tests and CLI smoke tests; replaced explicit test executable invocations with glob-based loop pattern.
Pascal Unit Test Removal
units/Goccia.ScriptLoader.JSON.Test.pas
Removed entire test suite validating BuildSuccessJSON, ExceptionToScriptLoaderErrorInfo, and TGocciaThrowValue handling—functionality now covered by CI smoke tests.

Possibly related PRs

Poem

🐰 From Pascal tests to smoke so bright,
We hop through JSON output, pure delight!
Public paths lead the way, no hidden trails,
CI catches bugs while documentation sails! ✨


🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Test JSON output via public CLI surface' directly reflects the primary objective of this PR: replacing internal unit tests with CLI-level smoke tests. It clearly summarizes the main change without being vague or overly broad.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/public-json-cli-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 3523 3523
Tests Passed 3482 ✅ 3523 ✅
Tests Skipped 41 0
Tests Execution 156.7ms 144.5ms
Tests Engine 312.4ms 527.8ms
Benchmarks Total 263 263
Benchmarks Duration 7.31min 6.17min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 30, 2026

Benchmark Results

263 benchmarks

Interpreted: 🔴 10 regressed · 253 unchanged · avg -3.0%
Bytecode: 🟢 5 improved · 🔴 3 regressed · 255 unchanged · avg -0.0%

arraybuffer.js — Interp: 14 unch. · avg -2.6% · Bytecode: 14 unch. · avg +0.1%
Benchmark Interpreted Δ Bytecode Δ
create ArrayBuffer(0) 475,006 → 457,571 -3.7% 508,984 → 503,270 -1.1%
create ArrayBuffer(64) 452,759 → 438,900 -3.1% 487,280 → 484,554 -0.6%
create ArrayBuffer(1024) 354,392 → 343,820 -3.0% 374,533 → 375,464 +0.2%
create ArrayBuffer(8192) 155,875 → 153,447 -1.6% 163,026 → 160,480 -1.6%
slice full buffer (64 bytes) 522,221 → 496,280 -5.0% 620,900 → 632,392 +1.9%
slice half buffer (512 of 1024 bytes) 447,427 → 428,214 -4.3% 532,665 → 521,759 -2.0%
slice with negative indices 438,233 → 419,000 -4.4% 576,125 → 575,404 -0.1%
slice empty range 499,798 → 480,595 -3.8% 612,795 → 610,243 -0.4%
byteLength access 1,374,612 → 1,395,733 +1.5% 1,623,834 → 1,602,906 -1.3%
Symbol.toStringTag access 1,043,301 → 1,060,910 +1.7% 1,082,522 → 1,080,417 -0.2%
ArrayBuffer.isView 746,064 → 742,674 -0.5% 871,584 → 871,174 -0.0%
clone ArrayBuffer(64) 429,418 → 409,237 -4.7% 485,196 → 486,945 +0.4%
clone ArrayBuffer(1024) 335,144 → 321,757 -4.0% 363,081 → 367,160 +1.1%
clone ArrayBuffer inside object 270,461 → 264,187 -2.3% 286,189 → 301,537 +5.4%
arrays.js — Interp: 🔴 1, 18 unch. · avg -2.7% · Bytecode: 🔴 1, 18 unch. · avg -0.7%
Benchmark Interpreted Δ Bytecode Δ
Array.from length 100 13,347 → 13,305 -0.3% 14,181 → 14,101 -0.6%
Array.from 10 elements 223,838 → 210,379 -6.0% 244,484 → 248,067 +1.5%
Array.of 10 elements 282,841 → 267,798 -5.3% 309,278 → 310,791 +0.5%
spread into new array 333,591 → 312,073 -6.5% 194,995 → 196,739 +0.9%
map over 50 elements 25,333 → 24,731 -2.4% 26,637 → 26,275 -1.4%
filter over 50 elements 22,886 → 22,389 -2.2% 23,598 → 21,470 🔴 -9.0%
reduce sum 50 elements 26,932 → 26,414 -1.9% 18,988 → 18,923 -0.3%
forEach over 50 elements 23,037 → 23,145 +0.5% 27,031 → 27,978 +3.5%
find in 50 elements 32,667 → 32,175 -1.5% 30,597 → 29,679 -3.0%
sort 20 elements 12,615 → 12,538 -0.6% 13,015 → 13,470 +3.5%
flat nested array 116,058 → 107,314 🔴 -7.5% 127,902 → 129,696 +1.4%
flatMap 72,801 → 69,293 -4.8% 80,368 → 82,571 +2.7%
map inside map (5x5) 20,622 → 19,810 -3.9% 22,174 → 22,236 +0.3%
filter inside map (5x10) 15,722 → 15,327 -2.5% 16,607 → 15,666 -5.7%
reduce inside map (5x10) 19,409 → 19,145 -1.4% 15,855 → 15,618 -1.5%
forEach inside forEach (5x10) 16,741 → 16,857 +0.7% 16,512 → 16,766 +1.5%
find inside some (10x10) 13,384 → 13,180 -1.5% 13,097 → 12,641 -3.5%
map+filter chain nested (5x20) 5,156 → 5,109 -0.9% 5,431 → 5,178 -4.6%
reduce flatten (10x5) 38,459 → 36,936 -4.0% 17,953 → 18,172 +1.2%
async-await.js — Interp: 🔴 1, 5 unch. · avg -3.7% · Bytecode: 6 unch. · avg -0.8%
Benchmark Interpreted Δ Bytecode Δ
single await 381,265 → 368,375 -3.4% 412,956 → 406,700 -1.5%
multiple awaits 170,779 → 164,539 -3.7% 181,839 → 179,914 -1.1%
await non-Promise value 861,030 → 839,806 -2.5% 1,095,366 → 1,085,424 -0.9%
await with try/catch 368,955 → 359,761 -2.5% 407,800 → 403,191 -1.1%
await Promise.all 52,320 → 48,596 🔴 -7.1% 52,264 → 52,311 +0.1%
nested async function call 194,053 → 187,997 -3.1% 232,376 → 231,036 -0.6%
classes.js — Interp: 31 unch. · avg -2.6% · Bytecode: 🟢 1, 🔴 1, 29 unch. · avg -0.6%
Benchmark Interpreted Δ Bytecode Δ
simple class new 140,247 → 138,475 -1.3% 204,933 → 203,452 -0.7%
class with defaults 111,969 → 112,806 +0.7% 142,654 → 141,811 -0.6%
50 instances via Array.from 5,473 → 5,695 +4.1% 7,911 → 7,908 -0.0%
instance method call 71,234 → 69,954 -1.8% 93,808 → 93,106 -0.7%
static method call 115,780 → 111,946 -3.3% 184,049 → 180,793 -1.8%
single-level inheritance 56,493 → 54,739 -3.1% 74,083 → 74,019 -0.1%
two-level inheritance 48,528 → 47,150 -2.8% 59,543 → 60,568 +1.7%
private field access 71,111 → 71,042 -0.1% 95,802 → 94,132 -1.7%
private methods 78,524 → 77,561 -1.2% 102,184 → 99,372 -2.8%
getter/setter access 77,331 → 75,055 -2.9% 105,954 → 103,774 -2.1%
class decorator (identity) 95,172 → 92,522 -2.8% 101,738 → 99,727 -2.0%
class decorator (wrapping) 55,178 → 53,810 -2.5% 57,312 → 58,906 +2.8%
identity method decorator 66,981 → 64,241 -4.1% 90,584 → 89,077 -1.7%
wrapping method decorator 53,724 → 51,165 -4.8% 59,019 → 59,496 +0.8%
stacked method decorators (x3) 36,243 → 34,674 -4.3% 45,436 → 44,968 -1.0%
identity field decorator 73,093 → 70,505 -3.5% 71,247 → 71,456 +0.3%
field initializer decorator 61,066 → 59,257 -3.0% 64,501 → 70,855 🟢 +9.9%
getter decorator (identity) 66,296 → 66,025 -0.4% 75,440 → 69,345 🔴 -8.1%
setter decorator (identity) 56,024 → 54,158 -3.3% 59,632 → 62,982 +5.6%
static method decorator 72,278 → 69,641 -3.6% 81,722 → 76,748 -6.1%
static field decorator 84,424 → 81,212 -3.8% 84,640 → 86,106 +1.7%
private method decorator 54,742 → 52,338 -4.4% 69,496 → 68,884 -0.9%
private field decorator 60,354 → 58,139 -3.7% 60,607 → 60,492 -0.2%
plain auto-accessor (no decorator) 105,894 → 101,279 -4.4% 95,721 → 93,624 -2.2%
auto-accessor with decorator 55,776 → 53,775 -3.6% 55,458 → 55,065 -0.7%
decorator writing metadata 45,883 → 44,287 -3.5% 48,939 → 48,504 -0.9%
static getter read 131,104 → 126,511 -3.5% 163,185 → 163,971 +0.5%
static getter/setter pair 99,776 → 98,330 -1.4% 117,361 → 121,059 +3.2%
inherited static getter 79,510 → 78,328 -1.5% 99,312 → 93,601 -5.8%
inherited static setter 84,232 → 83,100 -1.3% 103,533 → 99,965 -3.4%
inherited static getter with this binding 71,983 → 68,310 -5.1% 88,614 → 87,119 -1.7%
closures.js — Interp: 11 unch. · avg -2.3% · Bytecode: 11 unch. · avg -0.6%
Benchmark Interpreted Δ Bytecode Δ
closure over single variable 134,502 → 131,012 -2.6% 276,017 → 271,817 -1.5%
closure over multiple variables 121,492 → 121,452 -0.0% 189,096 → 187,766 -0.7%
nested closures 130,374 → 125,133 -4.0% 224,691 → 225,750 +0.5%
function as argument 95,965 → 92,674 -3.4% 245,691 → 245,860 +0.1%
function returning function 120,539 → 118,763 -1.5% 283,869 → 272,451 -4.0%
compose two functions 72,399 → 70,285 -2.9% 149,800 → 149,514 -0.2%
fn.call 153,854 → 152,966 -0.6% 221,538 → 229,041 +3.4%
fn.apply 111,517 → 109,082 -2.2% 155,979 → 158,012 +1.3%
fn.bind 145,248 → 140,365 -3.4% 282,544 → 272,688 -3.5%
recursive sum to 50 12,192 → 11,858 -2.7% 23,453 → 23,569 +0.5%
recursive tree traversal 20,707 → 20,312 -1.9% 35,535 → 34,640 -2.5%
collections.js — Interp: 🔴 1, 11 unch. · avg -2.2% · Bytecode: 12 unch. · avg -0.5%
Benchmark Interpreted Δ Bytecode Δ
add 50 elements 7,201 → 6,996 -2.9% 7,224 → 7,196 -0.4%
has lookup (50 elements) 91,208 → 89,236 -2.2% 100,152 → 99,173 -1.0%
delete elements 47,793 → 46,986 -1.7% 49,631 → 48,959 -1.4%
forEach iteration 15,710 → 15,403 -1.9% 15,411 → 15,526 +0.7%
spread to array 29,191 → 28,108 -3.7% 217,050 → 210,234 -3.1%
deduplicate array 38,932 → 37,573 -3.5% 71,613 → 71,338 -0.4%
set 50 entries 5,261 → 5,367 +2.0% 5,445 → 5,534 +1.6%
get lookup (50 entries) 87,273 → 87,463 +0.2% 92,240 → 93,018 +0.8%
has check 130,987 → 129,678 -1.0% 142,504 → 142,696 +0.1%
delete entries 45,766 → 45,959 +0.4% 46,985 → 47,640 +1.4%
forEach iteration 15,866 → 15,306 -3.5% 15,303 → 15,325 +0.1%
keys/values/entries 8,091 → 7,385 🔴 -8.7% 27,367 → 26,028 -4.9%
destructuring.js — Interp: 🔴 1, 21 unch. · avg -3.9% · Bytecode: 🔴 1, 21 unch. · avg -0.0%
Benchmark Interpreted Δ Bytecode Δ
simple array destructuring 373,959 → 368,514 -1.5% 262,770 → 254,410 -3.2%
with rest element 246,944 → 235,644 -4.6% 203,886 → 205,342 +0.7%
with defaults 385,812 → 378,131 -2.0% 301,341 → 292,261 -3.0%
skip elements 398,670 → 388,338 -2.6% 283,508 → 276,022 -2.6%
nested array destructuring 172,803 → 160,029 🔴 -7.4% 87,755 → 86,234 -1.7%
swap variables 505,395 → 479,331 -5.2% 326,613 → 326,084 -0.2%
simple object destructuring 315,390 → 301,946 -4.3% 404,199 → 403,245 -0.2%
with defaults 347,729 → 337,593 -2.9% 536,768 → 562,258 +4.7%
with renaming 329,067 → 324,509 -1.4% 434,587 → 434,018 -0.1%
nested object destructuring 154,986 → 149,505 -3.5% 190,293 → 198,408 +4.3%
rest properties 190,471 → 183,971 -3.4% 178,757 → 177,633 -0.6%
object parameter 97,864 → 94,086 -3.9% 144,270 → 150,739 +4.5%
array parameter 123,973 → 119,498 -3.6% 109,553 → 101,820 🔴 -7.1%
mixed destructuring in map 33,812 → 33,056 -2.2% 33,161 → 34,386 +3.7%
forEach with array destructuring 65,219 → 60,884 -6.6% 41,582 → 40,014 -3.8%
map with array destructuring 64,490 → 60,300 -6.5% 41,566 → 42,252 +1.6%
filter with array destructuring 66,894 → 63,081 -5.7% 46,610 → 46,077 -1.1%
reduce with array destructuring 73,793 → 69,814 -5.4% 45,322 → 46,066 +1.6%
map with object destructuring 74,766 → 72,844 -2.6% 86,413 → 86,293 -0.1%
map with nested destructuring 61,935 → 60,689 -2.0% 83,700 → 84,267 +0.7%
map with rest in destructuring 42,557 → 40,641 -4.5% 23,431 → 23,791 +1.5%
map with defaults in destructuring 57,642 → 55,830 -3.1% 64,143 → 64,269 +0.2%
fibonacci.js — Interp: 8 unch. · avg -3.4% · Bytecode: 8 unch. · avg -0.5%
Benchmark Interpreted Δ Bytecode Δ
recursive fib(15) 324 → 317 -2.3% 834 → 827 -0.9%
recursive fib(20) 29 → 29 -2.4% 76 → 74 -2.0%
recursive fib(15) typed 336 → 321 -4.6% 878 → 873 -0.6%
recursive fib(20) typed 30 → 29 -2.8% 79 → 79 -0.9%
iterative fib(20) via reduce 12,079 → 11,899 -1.5% 17,578 → 17,617 +0.2%
iterator fib(20) 9,507 → 9,342 -1.7% 18,539 → 18,060 -2.6%
iterator fib(20) via Iterator.from + take 15,711 → 14,795 -5.8% 19,995 → 20,573 +2.9%
iterator fib(20) last value via reduce 11,963 → 11,274 -5.8% 14,909 → 14,860 -0.3%
for-of.js — Interp: 7 unch. · avg -3.1% · Bytecode: 7 unch. · avg -0.2%
Benchmark Interpreted Δ Bytecode Δ
for...of with 10-element array 47,025 → 45,329 -3.6% 161,656 → 162,169 +0.3%
for...of with 100-element array 5,424 → 5,233 -3.5% 17,315 → 17,424 +0.6%
for...of with string (10 chars) 34,134 → 33,576 -1.6% 87,428 → 87,828 +0.5%
for...of with Set (10 elements) 47,667 → 45,821 -3.9% 149,696 → 147,184 -1.7%
for...of with Map entries (10 entries) 30,068 → 28,821 -4.1% 27,709 → 27,338 -1.3%
for...of with destructuring 40,173 → 39,644 -1.3% 36,468 → 35,017 -4.0%
for-await-of with sync array 45,210 → 43,630 -3.5% 120,241 → 125,668 +4.5%
helpers/bench-module.js — Interp: 0 · Bytecode: 0
Benchmark Interpreted Δ Bytecode Δ
iterators.js — Interp: 20 unch. · avg -4.2% · Bytecode: 🟢 1, 19 unch. · avg +0.8%
Benchmark Interpreted Δ Bytecode Δ
Iterator.from({next}).toArray() — 20 elements 15,787 → 15,139 -4.1% 20,058 → 19,864 -1.0%
Iterator.from({next}).toArray() — 50 elements 6,883 → 6,667 -3.1% 8,809 → 9,277 +5.3%
spread pre-wrapped iterator — 20 elements 11,796 → 11,377 -3.6% 20,041 → 19,976 -0.3%
Iterator.from({next}).forEach — 50 elements 4,781 → 4,545 -4.9% 5,374 → 5,827 🟢 +8.4%
Iterator.from({next}).reduce — 50 elements 4,846 → 4,595 -5.2% 5,599 → 5,373 -4.0%
wrap array iterator 165,834 → 155,679 -6.1% 172,026 → 182,171 +5.9%
wrap plain {next()} object 10,957 → 10,620 -3.1% 14,319 → 14,142 -1.2%
map + toArray (50 elements) 4,739 → 4,634 -2.2% 5,960 → 5,966 +0.1%
filter + toArray (50 elements) 4,660 → 4,472 -4.0% 5,745 → 5,818 +1.3%
take(10) + toArray (50 element source) 28,611 → 27,336 -4.5% 36,110 → 36,071 -0.1%
drop(40) + toArray (50 element source) 6,910 → 6,594 -4.6% 8,951 → 9,142 +2.1%
chained map + filter + take (100 element source) 8,297 → 8,186 -1.3% 10,254 → 10,315 +0.6%
some + every (50 elements) 2,720 → 2,642 -2.9% 3,498 → 3,469 -0.8%
find (50 elements) 5,948 → 5,720 -3.8% 7,272 → 7,168 -1.4%
array.values().map().filter().toArray() 8,334 → 7,975 -4.3% 9,775 → 9,975 +2.1%
array.values().take(5).toArray() 215,171 → 203,592 -5.4% 235,305 → 232,646 -1.1%
array.values().drop(45).toArray() 200,648 → 189,715 -5.4% 215,488 → 212,728 -1.3%
map.entries() chained helpers 10,456 → 9,820 -6.1% 5,987 → 6,133 +2.4%
set.values() chained helpers 17,450 → 16,748 -4.0% 19,916 → 19,569 -1.7%
string iterator map + toArray 13,784 → 13,062 -5.2% 14,685 → 14,822 +0.9%
json.js — Interp: 20 unch. · avg -2.0% · Bytecode: 🟢 1, 19 unch. · avg +2.3%
Benchmark Interpreted Δ Bytecode Δ
parse simple object 177,801 → 169,792 -4.5% 176,689 → 179,771 +1.7%
parse nested object 107,995 → 104,071 -3.6% 103,867 → 106,397 +2.4%
parse array of objects 62,576 → 61,915 -1.1% 62,806 → 64,734 +3.1%
parse large flat object 68,977 → 67,893 -1.6% 66,856 → 69,625 +4.1%
parse mixed types 79,578 → 79,327 -0.3% 80,093 → 83,635 +4.4%
stringify simple object 199,912 → 192,333 -3.8% 203,992 → 209,523 +2.7%
stringify nested object 109,332 → 106,973 -2.2% 112,679 → 114,756 +1.8%
stringify array of objects 61,017 → 59,881 -1.9% 61,062 → 62,503 +2.4%
stringify mixed types 89,283 → 86,448 -3.2% 90,002 → 92,770 +3.1%
reviver doubles numbers 49,506 → 48,210 -2.6% 53,976 → 51,775 -4.1%
reviver filters properties 41,150 → 40,198 -2.3% 41,642 → 43,484 +4.4%
reviver on nested object 51,844 → 51,411 -0.8% 54,419 → 53,165 -2.3%
reviver on array 32,800 → 32,090 -2.2% 31,104 → 34,014 🟢 +9.4%
replacer function doubles numbers 47,818 → 46,826 -2.1% 52,036 → 52,367 +0.6%
replacer function excludes properties 61,566 → 59,958 -2.6% 60,599 → 63,855 +5.4%
array replacer (allowlist) 113,127 → 109,725 -3.0% 118,234 → 117,385 -0.7%
stringify with 2-space indent 95,544 → 93,559 -2.1% 99,202 → 102,473 +3.3%
stringify with tab indent 96,650 → 95,616 -1.1% 100,451 → 100,413 -0.0%
parse then stringify 55,313 → 55,877 +1.0% 58,102 → 58,592 +0.8%
stringify then parse 33,887 → 34,005 +0.3% 35,483 → 36,446 +2.7%
jsx.jsx — Interp: 21 unch. · avg -3.9% · Bytecode: 21 unch. · avg -0.5%
Benchmark Interpreted Δ Bytecode Δ
simple element 217,663 → 207,241 -4.8% 311,935 → 321,032 +2.9%
self-closing element 223,761 → 212,006 -5.3% 347,388 → 334,645 -3.7%
element with string attribute 180,892 → 172,052 -4.9% 246,850 → 247,809 +0.4%
element with multiple attributes 161,258 → 152,720 -5.3% 202,868 → 196,339 -3.2%
element with expression attribute 169,985 → 164,699 -3.1% 245,557 → 248,619 +1.2%
text child 215,280 → 206,362 -4.1% 317,614 → 309,747 -2.5%
expression child 212,216 → 203,238 -4.2% 312,334 → 317,393 +1.6%
mixed text and expression 201,715 → 194,537 -3.6% 288,113 → 279,251 -3.1%
nested elements (3 levels) 80,260 → 77,714 -3.2% 116,314 → 119,209 +2.5%
sibling children 60,427 → 58,300 -3.5% 87,157 → 87,712 +0.6%
component element 153,794 → 145,319 -5.5% 220,316 → 220,826 +0.2%
component with children 94,586 → 89,916 -4.9% 138,641 → 136,333 -1.7%
dotted component 128,403 → 123,348 -3.9% 173,039 → 169,953 -1.8%
empty fragment 227,226 → 215,782 -5.0% 368,021 → 361,870 -1.7%
fragment with children 59,753 → 57,792 -3.3% 87,718 → 87,693 -0.0%
spread attributes 112,668 → 110,579 -1.9% 133,091 → 133,418 +0.2%
spread with overrides 98,561 → 94,049 -4.6% 113,973 → 114,251 +0.2%
shorthand props 166,475 → 159,739 -4.0% 232,128 → 231,534 -0.3%
nav bar structure 27,946 → 26,900 -3.7% 38,997 → 38,871 -0.3%
card component tree 32,630 → 31,291 -4.1% 44,490 → 44,515 +0.1%
10 list items via Array.from 14,298 → 14,397 +0.7% 19,699 → 19,342 -1.8%
modules.js — Interp: 9 unch. · avg +1.4% · Bytecode: 🟢 2, 7 unch. · avg +3.4%
Benchmark Interpreted Δ Bytecode Δ
call imported function 474,237 → 476,140 +0.4% 641,543 → 658,408 +2.6%
call two imported functions 261,022 → 264,961 +1.5% 363,423 → 351,168 -3.4%
read imported constant 1,627,541 → 1,670,576 +2.6% 3,371,165 → 3,659,740 🟢 +8.6%
read imported string 1,638,417 → 1,650,683 +0.7% 3,397,177 → 3,647,035 🟢 +7.4%
read JSON string property 1,645,596 → 1,662,405 +1.0% 3,541,243 → 3,661,853 +3.4%
read JSON number property 1,614,304 → 1,651,164 +2.3% 3,478,609 → 3,627,088 +4.3%
read JSON boolean property 1,652,152 → 1,671,011 +1.1% 3,599,951 → 3,657,649 +1.6%
read JSON array property 1,644,942 → 1,650,793 +0.4% 3,613,018 → 3,658,821 +1.3%
read multiple JSON properties 928,753 → 950,511 +2.3% 3,147,354 → 3,298,323 +4.8%
numbers.js — Interp: 🔴 1, 10 unch. · avg -2.4% · Bytecode: 11 unch. · avg -1.2%
Benchmark Interpreted Δ Bytecode Δ
integer arithmetic 517,313 → 522,310 +1.0% 1,481,621 → 1,499,136 +1.2%
floating point arithmetic 586,610 → 609,978 +4.0% 973,363 → 967,135 -0.6%
number coercion 194,113 → 182,871 -5.8% 232,596 → 228,068 -1.9%
toFixed 102,724 → 101,166 -1.5% 110,686 → 111,733 +0.9%
toString 158,712 → 151,824 -4.3% 192,628 → 188,422 -2.2%
valueOf 234,325 → 217,681 🔴 -7.1% 270,330 → 260,910 -3.5%
toPrecision 145,632 → 141,066 -3.1% 169,064 → 162,660 -3.8%
Number.isNaN 316,642 → 317,618 +0.3% 343,925 → 340,754 -0.9%
Number.isFinite 317,216 → 304,683 -4.0% 324,477 → 318,835 -1.7%
Number.isInteger 322,826 → 323,231 +0.1% 351,617 → 348,888 -0.8%
Number.parseInt and parseFloat 263,745 → 248,710 -5.7% 262,240 → 263,483 +0.5%
objects.js — Interp: 🔴 2, 5 unch. · avg -4.1% · Bytecode: 7 unch. · avg +1.1%
Benchmark Interpreted Δ Bytecode Δ
create simple object 483,242 → 462,526 -4.3% 566,038 → 582,194 +2.9%
create nested object 232,442 → 226,815 -2.4% 256,260 → 250,847 -2.1%
create 50 objects via Array.from 9,298 → 8,879 -4.5% 9,770 → 9,936 +1.7%
property read 567,110 → 567,441 +0.1% 426,703 → 433,886 +1.7%
Object.keys 289,133 → 268,694 🔴 -7.1% 311,238 → 319,155 +2.5%
Object.entries 103,580 → 95,777 🔴 -7.5% 112,499 → 110,428 -1.8%
spread operator 179,971 → 174,782 -2.9% 200,310 → 205,435 +2.6%
promises.js — Interp: 🔴 2, 10 unch. · avg -4.4% · Bytecode: 12 unch. · avg -1.6%
Benchmark Interpreted Δ Bytecode Δ
Promise.resolve(value) 556,166 → 529,364 -4.8% 554,995 → 563,553 +1.5%
new Promise(resolve => resolve(value)) 190,643 → 181,017 -5.0% 229,004 → 226,718 -1.0%
Promise.reject(reason) 563,353 → 529,748 -6.0% 547,566 → 552,978 +1.0%
resolve + then (1 handler) 178,373 → 173,087 -3.0% 201,320 → 197,955 -1.7%
resolve + then chain (3 deep) 69,464 → 68,196 -1.8% 79,175 → 77,425 -2.2%
resolve + then chain (10 deep) 21,563 → 21,495 -0.3% 26,004 → 25,254 -2.9%
reject + catch + then 98,668 → 97,098 -1.6% 113,841 → 111,225 -2.3%
resolve + finally + then 83,882 → 81,426 -2.9% 95,236 → 92,221 -3.2%
Promise.all (5 resolved) 31,518 → 29,623 -6.0% 34,228 → 33,230 -2.9%
Promise.race (5 resolved) 34,264 → 31,713 🔴 -7.4% 36,104 → 35,359 -2.1%
Promise.allSettled (5 mixed) 27,206 → 25,523 -6.2% 28,392 → 28,090 -1.1%
Promise.any (5 mixed) 32,382 → 29,976 🔴 -7.4% 33,918 → 33,176 -2.2%
strings.js — Interp: 11 unch. · avg -2.3% · Bytecode: 11 unch. · avg -1.0%
Benchmark Interpreted Δ Bytecode Δ
string concatenation 414,555 → 415,005 +0.1% 325,348 → 325,149 -0.1%
template literal 630,589 → 671,600 +6.5% 648,777 → 655,692 +1.1%
string repeat 408,996 → 394,107 -3.6% 472,015 → 471,102 -0.2%
split and join 140,035 → 135,249 -3.4% 153,731 → 150,533 -2.1%
indexOf and includes 170,113 → 164,676 -3.2% 197,234 → 191,784 -2.8%
toUpperCase and toLowerCase 259,193 → 245,404 -5.3% 330,069 → 323,810 -1.9%
slice and substring 154,715 → 150,846 -2.5% 203,127 → 197,972 -2.5%
trim operations 189,408 → 180,151 -4.9% 244,256 → 242,525 -0.7%
replace and replaceAll 209,195 → 204,336 -2.3% 241,187 → 241,157 -0.0%
startsWith and endsWith 135,715 → 130,472 -3.9% 159,006 → 159,996 +0.6%
padStart and padEnd 197,028 → 191,613 -2.7% 232,099 → 227,189 -2.1%
typed-arrays.js — Interp: 🔴 1, 21 unch. · avg -4.4% · Bytecode: 22 unch. · avg +0.0%
Benchmark Interpreted Δ Bytecode Δ
new Int32Array(0) 338,794 → 320,734 -5.3% 376,835 → 371,330 -1.5%
new Int32Array(100) 312,223 → 291,109 -6.8% 337,186 → 331,577 -1.7%
new Int32Array(1000) 184,167 → 181,993 -1.2% 197,888 → 193,391 -2.3%
new Float64Array(100) 276,325 → 268,392 -2.9% 311,189 → 301,687 -3.1%
Int32Array.from([...]) 186,091 → 175,149 -5.9% 192,269 → 193,903 +0.8%
Int32Array.of(1, 2, 3, 4, 5) 316,350 → 290,107 🔴 -8.3% 361,304 → 359,057 -0.6%
sequential write 100 elements 3,645 → 3,468 -4.9% 15,546 → 16,034 +3.1%
sequential read 100 elements 3,715 → 3,528 -5.0% 10,387 → 10,456 +0.7%
Float64Array write 100 elements 3,404 → 3,283 -3.5% 10,771 → 11,003 +2.2%
fill(42) 45,779 → 46,807 +2.2% 45,970 → 47,362 +3.0%
slice() 205,348 → 198,581 -3.3% 221,874 → 219,745 -1.0%
map(x => x * 2) 8,139 → 7,612 -6.5% 8,824 → 8,974 +1.7%
filter(x => x > 50) 8,445 → 8,131 -3.7% 9,721 → 9,908 +1.9%
reduce (sum) 8,144 → 7,742 -4.9% 7,316 → 7,394 +1.1%
sort() 169,232 → 163,397 -3.4% 173,507 → 173,960 +0.3%
indexOf() 427,499 → 416,710 -2.5% 497,477 → 494,975 -0.5%
reverse() 330,011 → 317,847 -3.7% 357,712 → 359,742 +0.6%
create view over existing buffer 414,132 → 385,701 -6.9% 451,500 → 447,081 -1.0%
subarray() 438,048 → 408,304 -6.8% 532,103 → 519,591 -2.4%
set() from array 574,080 → 551,805 -3.9% 641,273 → 651,529 +1.6%
for-of loop 5,185 → 4,908 -5.3% 17,817 → 17,924 +0.6%
spread into array 17,352 → 16,411 -5.4% 96,537 → 93,851 -2.8%

Measured on ubuntu-latest x64. Changes within ±7% are considered insignificant.

@frostney frostney merged commit 450adec into main Mar 30, 2026
9 checks passed
@frostney frostney deleted the fix/public-json-cli-tests branch March 30, 2026 14:19
@frostney frostney added the internal Refactoring, CI, tooling, cleanup label Apr 9, 2026
@coderabbitai coderabbitai Bot mentioned this pull request Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Refactoring, CI, tooling, cleanup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant