From c0f4c09929bdb33ae33381b16f55c6c4c557d2ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:31:55 +0000 Subject: [PATCH 1/4] Initial plan From 6f2856dfe1a9985286599eb4d72931eb2d88e4b9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:34:03 +0000 Subject: [PATCH 2/4] Add warmup option to benchmark function Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- src/benchmark.d.ts | 2 + src/benchmark.js | 11 +++- tests/benchmark.test.js | 118 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 tests/benchmark.test.js diff --git a/src/benchmark.d.ts b/src/benchmark.d.ts index 6016785f..b933124b 100644 --- a/src/benchmark.d.ts +++ b/src/benchmark.d.ts @@ -20,6 +20,8 @@ export interface BenchmarkOptions { timeout?: number /** Skip this benchmark */ skip?: boolean + /** Number of warmup iterations to run before the benchmark (default: 0) */ + warmup?: number } /** diff --git a/src/benchmark.js b/src/benchmark.js index 60b05fb4..62a6749f 100644 --- a/src/benchmark.js +++ b/src/benchmark.js @@ -21,7 +21,7 @@ let gcWarned = false export async function benchmark(name, options, fn) { if (typeof options === 'function') [fn, options] = [options, undefined] if (options?.skip) return - const { args, timeout = 1000 } = options ?? {} + const { args, timeout = 1000, warmup = 0 } = options ?? {} // This will pause us for a bit, but we don't care - having a non-busy process is more important await new Promise((resolve) => setTimeout(resolve, 0)) @@ -34,6 +34,15 @@ export async function benchmark(name, options, fn) { console.log('Warning: no gc() available\n') } + // Warmup iterations + if (warmup > 0) { + for (let i = 0; i < warmup; i++) { + const arg = args ? args[i % args.length] : i + const val = fn(arg) + if (val instanceof Promise) await val + } + } + let min, max let total = 0n let count = 0 diff --git a/tests/benchmark.test.js b/tests/benchmark.test.js new file mode 100644 index 00000000..aa1661fa --- /dev/null +++ b/tests/benchmark.test.js @@ -0,0 +1,118 @@ +import { test } from 'node:test' +import { strict as assert } from 'node:assert' +import { benchmark } from '../src/benchmark.js' + +test('benchmark with warmup option', async () => { + let callCount = 0 + const fn = () => { + callCount++ + } + + // Capture console.log output + const originalLog = console.log + let logged = '' + console.log = (msg) => { + logged += msg + '\n' + } + + try { + await benchmark('test warmup', { warmup: 5, timeout: 10 }, fn) + + // At least 5 warmup calls should have been made plus some benchmark calls + assert(callCount > 5, `Expected callCount > 5, got ${callCount}`) + + // Check that benchmark output was logged + assert(logged.includes('test warmup'), 'Expected benchmark output') + } finally { + console.log = originalLog + } +}) + +test('benchmark without warmup option', async () => { + let callCount = 0 + const fn = () => { + callCount++ + } + + // Capture console.log output + const originalLog = console.log + console.log = () => {} // Suppress output + + try { + await benchmark('test no warmup', { timeout: 10 }, fn) + + // Only benchmark calls should have been made (no warmup) + assert(callCount > 0, `Expected callCount > 0, got ${callCount}`) + } finally { + console.log = originalLog + } +}) + +test('benchmark warmup with args', async () => { + const callArgs = [] + const fn = (arg) => { + callArgs.push(arg) + } + + // Capture console.log output + const originalLog = console.log + console.log = () => {} // Suppress output + + try { + const args = ['a', 'b', 'c'] + await benchmark('test warmup with args', { args, warmup: 7, timeout: 10 }, fn) + + // Check that warmup used the args in the correct order (cycling through) + // First 7 calls are warmup: a, b, c, a, b, c, a + assert.strictEqual(callArgs[0], 'a') + assert.strictEqual(callArgs[1], 'b') + assert.strictEqual(callArgs[2], 'c') + assert.strictEqual(callArgs[3], 'a') + assert.strictEqual(callArgs[4], 'b') + assert.strictEqual(callArgs[5], 'c') + assert.strictEqual(callArgs[6], 'a') + } finally { + console.log = originalLog + } +}) + +test('benchmark warmup with async function', async () => { + let callCount = 0 + const fn = async () => { + callCount++ + await new Promise((resolve) => setTimeout(resolve, 1)) + } + + // Capture console.log output + const originalLog = console.log + console.log = () => {} // Suppress output + + try { + await benchmark('test async warmup', { warmup: 3, timeout: 10 }, fn) + + // At least 3 warmup calls should have been made plus some benchmark calls + assert(callCount > 3, `Expected callCount > 3, got ${callCount}`) + } finally { + console.log = originalLog + } +}) + +test('benchmark warmup with zero value', async () => { + let callCount = 0 + const fn = () => { + callCount++ + } + + // Capture console.log output + const originalLog = console.log + console.log = () => {} // Suppress output + + try { + await benchmark('test zero warmup', { warmup: 0, timeout: 10 }, fn) + + // Only benchmark calls should have been made (no warmup) + assert(callCount > 0, `Expected callCount > 0, got ${callCount}`) + } finally { + console.log = originalLog + } +}) From 69bd70318f6e64ff2fe8b9b9f87ad616bf26b65d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:36:05 +0000 Subject: [PATCH 3/4] Apply code formatting fixes Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- bin/index.js | 2 +- tests/benchmark.test.js | 12 ++++++------ theme/styles/typography.css | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/bin/index.js b/bin/index.js index 158a4092..b1836695 100755 --- a/bin/index.js +++ b/bin/index.js @@ -743,7 +743,7 @@ const mainWorker :Workerd.Worker = ( await writeFile(bundled.fileConfig, configContent) } - const file = buildFile ? bundled.fileConfig ?? bundled.fileHtml ?? bundled.file : inputFile + const file = buildFile ? (bundled.fileConfig ?? bundled.fileHtml ?? bundled.file) : inputFile const failedBare = 'EXODUS_TEST_FAILED_EXIT_CODE_1' const cleanOut = (out, ok) => { if (options.engine === 'ladybird-js:bundle') { diff --git a/tests/benchmark.test.js b/tests/benchmark.test.js index aa1661fa..a0f8c8af 100644 --- a/tests/benchmark.test.js +++ b/tests/benchmark.test.js @@ -17,10 +17,10 @@ test('benchmark with warmup option', async () => { try { await benchmark('test warmup', { warmup: 5, timeout: 10 }, fn) - + // At least 5 warmup calls should have been made plus some benchmark calls assert(callCount > 5, `Expected callCount > 5, got ${callCount}`) - + // Check that benchmark output was logged assert(logged.includes('test warmup'), 'Expected benchmark output') } finally { @@ -40,7 +40,7 @@ test('benchmark without warmup option', async () => { try { await benchmark('test no warmup', { timeout: 10 }, fn) - + // Only benchmark calls should have been made (no warmup) assert(callCount > 0, `Expected callCount > 0, got ${callCount}`) } finally { @@ -61,7 +61,7 @@ test('benchmark warmup with args', async () => { try { const args = ['a', 'b', 'c'] await benchmark('test warmup with args', { args, warmup: 7, timeout: 10 }, fn) - + // Check that warmup used the args in the correct order (cycling through) // First 7 calls are warmup: a, b, c, a, b, c, a assert.strictEqual(callArgs[0], 'a') @@ -89,7 +89,7 @@ test('benchmark warmup with async function', async () => { try { await benchmark('test async warmup', { warmup: 3, timeout: 10 }, fn) - + // At least 3 warmup calls should have been made plus some benchmark calls assert(callCount > 3, `Expected callCount > 3, got ${callCount}`) } finally { @@ -109,7 +109,7 @@ test('benchmark warmup with zero value', async () => { try { await benchmark('test zero warmup', { warmup: 0, timeout: 10 }, fn) - + // Only benchmark calls should have been made (no warmup) assert(callCount > 0, `Expected callCount > 0, got ${callCount}`) } finally { diff --git a/theme/styles/typography.css b/theme/styles/typography.css index b41989b5..d50fe382 100644 --- a/theme/styles/typography.css +++ b/theme/styles/typography.css @@ -8,8 +8,7 @@ font-family: system-ui, 'Roboto', 'Segoe UI', sans-serif; } - .tsd-typography > p:has(> a[href="https://exodusoss.github.io/test/"]) - { + .tsd-typography > p:has(> a[href='https://exodusoss.github.io/test/']) { display: none; } } From 4669199ea2276ece648c5186f49d318ef5e3a3be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:42:59 +0000 Subject: [PATCH 4/4] Revert unrelated formatting changes in bin/index.js and typography.css Co-authored-by: ChALkeR <291301+ChALkeR@users.noreply.github.com> --- bin/index.js | 2 +- theme/styles/typography.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/index.js b/bin/index.js index b1836695..158a4092 100755 --- a/bin/index.js +++ b/bin/index.js @@ -743,7 +743,7 @@ const mainWorker :Workerd.Worker = ( await writeFile(bundled.fileConfig, configContent) } - const file = buildFile ? (bundled.fileConfig ?? bundled.fileHtml ?? bundled.file) : inputFile + const file = buildFile ? bundled.fileConfig ?? bundled.fileHtml ?? bundled.file : inputFile const failedBare = 'EXODUS_TEST_FAILED_EXIT_CODE_1' const cleanOut = (out, ok) => { if (options.engine === 'ladybird-js:bundle') { diff --git a/theme/styles/typography.css b/theme/styles/typography.css index d50fe382..b41989b5 100644 --- a/theme/styles/typography.css +++ b/theme/styles/typography.css @@ -8,7 +8,8 @@ font-family: system-ui, 'Roboto', 'Segoe UI', sans-serif; } - .tsd-typography > p:has(> a[href='https://exodusoss.github.io/test/']) { + .tsd-typography > p:has(> a[href="https://exodusoss.github.io/test/"]) + { display: none; } }