Skip to content

Conversation

nektro
Copy link
Member

@nektro nektro commented Oct 8, 2025

found while investigating #23062

@robobun
Copy link
Collaborator

robobun commented Oct 8, 2025

Updated 1:14 AM PT - Oct 8th, 2025

@nektro, your commit b059f03 has 2 failures in Build #28509 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 23366

That installs a local version of the PR into your bun-23366 executable, so you can run:

bun-23366 --bun

@nektro nektro marked this pull request as ready for review October 8, 2025 08:16
Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Walkthrough

Adds built-in support for node:test/reporters, wiring module resolution and natives. Implements internal reporters (dot, junit, spec, tap, lcov) and shared utils, exposes them via a new node module facade. Introduces RegExp hardening utilities. Updates a test to delete AGENT env var instead of AGENTS.

Changes

Cohort / File(s) Summary of changes
Node built-in alias and recognition
src/bun.js/ModuleLoader.zig, src/bun.js/bindings/isBuiltinModule.cpp
Registers node:test/reporters in hardcoded module aliases and builtin module lists to enable resolution as a built-in.
ProcessBinding natives for reporters
src/bun.js/bindings/ProcessBindingNatives.cpp
Adds LUT entries for internal/test/reporter/{dot,junit,lcov,spec,tap,utils} to process.binding("natives").
Primordials RegExp hardening
src/js/internal/primordials.js
Adds hardenRegExp(pattern) and related internal helpers (including RegExpLikeForStringSplitting), exporting hardenRegExp via the default export.
Internal test reporters implementations
src/js/internal/test/reporter/* (dot.ts, junit.ts, lcov.ts, spec.ts, tap.ts, utils.ts)
Introduces reporters: dot (async generator), junit (XML async generator), tap (async generator), spec (Transform stream), lcov (Transform stream), plus shared utilities for formatting, colors, and inspection.
Node reporters facade
src/js/node/test.reporters.ts
Adds the node:test/reporters module default export exposing lazy-loaded reporters: dot, junit, spec, tap, lcov.
Test env adjustment
test/cli/test/claudecode-flag.test.ts
Replaces deletion of testEnv.AGENTS with testEnv.AGENT in beforeAll.

Possibly related PRs

Suggested reviewers

  • dylan-conway
  • taylordotfish

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description does not follow the repository’s required template and is missing both the “What does this PR do?” and “How did you verify your code works?” sections, leaving critical context and verification steps unspecified. Please update the PR description to include the template headings “What does this PR do?” with a summary of changes and “How did you verify your code works?” with the testing or validation steps performed.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly describes the primary purpose of the changes by highlighting the addition of the node:test/reporters module and uses clear, concise wording that aligns with the main feature introduced in this PR. It avoids unnecessary detail and accurately reflects the core functionality being added.

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 625e537 and b059f03.

📒 Files selected for processing (12)
  • src/bun.js/ModuleLoader.zig (3 hunks)
  • src/bun.js/bindings/ProcessBindingNatives.cpp (1 hunks)
  • src/bun.js/bindings/isBuiltinModule.cpp (1 hunks)
  • src/js/internal/primordials.js (3 hunks)
  • src/js/internal/test/reporter/dot.ts (1 hunks)
  • src/js/internal/test/reporter/junit.ts (1 hunks)
  • src/js/internal/test/reporter/lcov.ts (1 hunks)
  • src/js/internal/test/reporter/spec.ts (1 hunks)
  • src/js/internal/test/reporter/tap.ts (1 hunks)
  • src/js/internal/test/reporter/utils.ts (1 hunks)
  • src/js/node/test.reporters.ts (1 hunks)
  • test/cli/test/claudecode-flag.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (17)
test/**

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

Place all tests under the test/ directory

Files:

  • test/cli/test/claudecode-flag.test.ts
test/cli/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/cli/**/*.{js,ts}: Place CLI command tests (e.g., bun install, bun init) under test/cli/
When testing Bun as a CLI, use spawn with bunExe() and bunEnv from harness, and capture stdout/stderr via pipes

Files:

  • test/cli/test/claudecode-flag.test.ts
test/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts}: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable

Files:

  • test/cli/test/claudecode-flag.test.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.ts: Name test files *.test.ts and use bun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; use port: 0 to get a random port
When spawning Bun in tests, use bunExe() and bunEnv from harness
Prefer async/await in tests; for a single callback, use Promise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
Use tempDir/tempDirWithFiles from harness for temporary files and directories in tests
For large/repetitive strings in tests, prefer Buffer.alloc(count, fill).toString() over "A".repeat(count)
Import common test utilities from harness (e.g., bunExe, bunEnv, tempDirWithFiles, tmpdirSync, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and use toThrow for synchronous errors
Use describe blocks for grouping, describe.each for parameterized tests, snapshots with toMatchSnapshot, and lifecycle hooks (beforeAll, beforeEach, afterEach); track resources for cleanup in afterEach
Use using/await using with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests

Files:

  • test/cli/test/claudecode-flag.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: Test files must live under test/ and end with .test.ts or .test.tsx
In tests, always use port: 0; do not hardcode ports or roll your own random port
Prefer normalizeBunSnapshot for snapshotting test output instead of asserting raw strings
Do not write tests that assert absence of crashes (e.g., 'no panic' or 'no uncaught exception')
Use Bun’s Jest-compatible runner (import { test, expect } from "bun:test") for tests
Avoid shell commands like find or grep in tests; use Bun’s Glob and built-in tools instead
Prefer running tests via bun bd test and use provided harness utilities (bunEnv, bunExe, tempDir)
Use Bun.spawn with proper stdio handling and await proc.exited in process-spawning tests

Files:

  • test/cli/test/claudecode-flag.test.ts
test/cli/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place CLI command tests under test/cli/

Files:

  • test/cli/test/claudecode-flag.test.ts
src/js/internal/**

📄 CodeRabbit inference engine (CLAUDE.md)

Place internal modules not exposed to users under src/js/internal/

Files:

  • src/js/internal/primordials.js
  • src/js/internal/test/reporter/spec.ts
  • src/js/internal/test/reporter/tap.ts
  • src/js/internal/test/reporter/junit.ts
  • src/js/internal/test/reporter/lcov.ts
  • src/js/internal/test/reporter/dot.ts
  • src/js/internal/test/reporter/utils.ts
src/js/internal/**/*.{ts,js}

📄 CodeRabbit inference engine (src/js/CLAUDE.md)

Place internal-only modules under internal/

Files:

  • src/js/internal/primordials.js
  • src/js/internal/test/reporter/spec.ts
  • src/js/internal/test/reporter/tap.ts
  • src/js/internal/test/reporter/junit.ts
  • src/js/internal/test/reporter/lcov.ts
  • src/js/internal/test/reporter/dot.ts
  • src/js/internal/test/reporter/utils.ts
src/js/{builtins,node,bun,thirdparty,internal}/**/*.{ts,js}

📄 CodeRabbit inference engine (src/js/CLAUDE.md)

src/js/{builtins,node,bun,thirdparty,internal}/**/*.{ts,js}: Use require() with string literals only (no dynamic requires)
Do not use ESM import syntax; write modules as CommonJS with export default { ... }
Export via export default {} for modules
Use .$call and .$apply; never use .call or .apply
Prefer JSC intrinsics/private $ APIs for performance (e.g., $Array.from, map.$set, $newArrayWithSize, $debug, $assert)
Validate callbacks with $isCallable and throw $ERR_INVALID_ARG_TYPE with the correct parameter name and expected type
Use process.platform and process.arch for platform detection (rely on inlining/dead-code elimination)

Files:

  • src/js/internal/primordials.js
  • src/js/internal/test/reporter/spec.ts
  • src/js/internal/test/reporter/tap.ts
  • src/js/node/test.reporters.ts
  • src/js/internal/test/reporter/junit.ts
  • src/js/internal/test/reporter/lcov.ts
  • src/js/internal/test/reporter/dot.ts
  • src/js/internal/test/reporter/utils.ts
**/*.{cpp,h}

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.{cpp,h}: When exposing a JS class with public Constructor and Prototype, define three C++ types: class Foo : public JSC::DestructibleObject (if it has C++ fields), class FooPrototype : public JSC::JSNonFinalObject, and class FooConstructor : public JSC::InternalFunction
If the class has C++ data members, inherit from JSC::DestructibleObject and provide proper destruction; if it has no C++ fields (only JS properties), avoid a class and use JSC::constructEmptyObject(vm, structure) with putDirectOffset
Prefer placing the subspaceFor implementation in the .cpp file rather than the header when possible

Files:

  • src/bun.js/bindings/ProcessBindingNatives.cpp
  • src/bun.js/bindings/isBuiltinModule.cpp
**/*.cpp

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.cpp: Include "root.h" at the top of C++ binding files to satisfy lints
Define prototype properties using a const HashTableValue array and declare accessors/functions with JSC_DECLARE_* macros
Prototype classes should subclass JSC::JSNonFinalObject, provide create/createStructure, DECLARE_INFO, finishCreation that reifies static properties, and set mayBePrototype on the Structure
Custom getters should use JSC_DEFINE_CUSTOM_GETTER, jsDynamicCast to validate this, and throwThisTypeError on mismatch
Custom setters should use JSC_DEFINE_CUSTOM_SETTER, validate this via jsDynamicCast, and store via WriteBarrier/set semantics
Prototype functions should use JSC_DEFINE_HOST_FUNCTION, validate this with jsDynamicCast, and return encoded JSValue
Constructors should subclass JSC::InternalFunction, return internalFunctionSpace in subspaceFor, set the prototype property as non-configurable/non-writable, and provide create/createStructure
Provide a setup function that builds the Prototype, Constructor, and Structure, and assigns them to the LazyClassStructure initializer
Use the cached Structure via globalObject->m_.get(globalObject) when constructing instances
Expose constructors to Zig via an extern "C" function that returns the constructor from the LazyClassStructure
Provide an extern "C" Bun____toJS function that creates an instance using the cached Structure and returns an EncodedJSValue

Files:

  • src/bun.js/bindings/ProcessBindingNatives.cpp
  • src/bun.js/bindings/isBuiltinModule.cpp
src/bun.js/bindings/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

src/bun.js/bindings/**/*.cpp: When a JS class has a public constructor, implement Foo, FooPrototype, and FooConstructor (JSDestructibleObject, JSNonFinalObject, InternalFunction)
Define class properties using HashTableValue arrays in C++ bindings
Add iso subspaces for classes with C++ fields
Cache structures in ZigGlobalObject for C++-backed classes

Files:

  • src/bun.js/bindings/ProcessBindingNatives.cpp
  • src/bun.js/bindings/isBuiltinModule.cpp
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.zig: Declare the extern C symbol in Zig and export a Zig-friendly alias for use
Wrap the Bun____toJS extern in a Zig method that takes a JSGlobalObject and returns JSC.JSValue

Files:

  • src/bun.js/ModuleLoader.zig
src/bun.js/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)

src/bun.js/**/*.zig: In Zig binding structs, expose generated bindings via pub const js = JSC.Codegen.JS and re-export toJS/fromJS/fromJSDirect
Constructors and prototype methods should return bun.JSError!JSC.JSValue to integrate Zig error handling with JS exceptions
Use parameter name globalObject (not ctx) and accept (*JSC.JSGlobalObject, *JSC.CallFrame) in binding methods/constructors
Implement getters as get(this, globalObject) returning JSC.JSValue and matching the .classes.ts interface
Provide deinit() for resource cleanup and finalize() that calls deinit(); use bun.destroy(this) or appropriate destroy pattern
Access JS call data via CallFrame (argument(i), argumentCount(), thisValue()) and throw errors with globalObject.throw(...)
For properties marked cache: true, use the generated Zig accessors (NameSetCached/GetCached) to work with GC-owned values
In finalize() for objects holding JS references, release them using .deref() before destroy

Files:

  • src/bun.js/ModuleLoader.zig
src/**/*.zig

📄 CodeRabbit inference engine (CLAUDE.md)

In Zig code, manage memory carefully and use defer for cleanup of allocations/resources

src/**/*.zig: Use the # prefix to declare private fields in Zig structs (e.g., struct { #foo: u32 })
Prefer decl literals when initializing values in Zig (e.g., const decl: Decl = .{ .binding = 0, .value = 0 })
Place @import directives at the bottom of Zig files
Use @import("bun") instead of @import("root").bun

When adding debug logs in Zig, create a scoped logger and log via Bun APIs: const log = bun.Output.scoped(.${SCOPE}, .hidden); then log("...", .{})

Files:

  • src/bun.js/ModuleLoader.zig
src/js/node/**

📄 CodeRabbit inference engine (CLAUDE.md)

Organize built-in Node.js compatibility modules under src/js/node/ (e.g., node:fs, node:path)

Files:

  • src/js/node/test.reporters.ts
src/js/node/**/*.{ts,js}

📄 CodeRabbit inference engine (src/js/CLAUDE.md)

Place Node.js compatibility modules (e.g., node:fs, node:path) under node/

Files:

  • src/js/node/test.reporters.ts
🧠 Learnings (1)
📚 Learning: 2025-09-08T00:41:12.052Z
Learnt from: CR
PR: oven-sh/bun#0
File: src/bun.js/bindings/v8/CLAUDE.md:0-0
Timestamp: 2025-09-08T00:41:12.052Z
Learning: Applies to src/bun.js/bindings/v8/test/v8/v8-module/main.cpp : Add a C++ test function in test/v8/v8-module/main.cpp and register it in Init using NODE_SET_METHOD

Applied to files:

  • src/bun.js/bindings/isBuiltinModule.cpp
🧬 Code graph analysis (6)
src/js/internal/primordials.js (1)
src/js/internal/util/inspect.js (1)
  • ObjectDefineProperty (86-86)
src/js/internal/test/reporter/spec.ts (2)
src/js/internal/test/reporter/utils.ts (6)
  • colors (28-30)
  • colors (31-33)
  • colors (34-36)
  • colors (37-39)
  • colors (40-42)
  • colors (43-45)
src/js/internal/util/inspect.js (4)
  • ArrayPrototypeJoin (53-53)
  • ArrayPrototypePop (55-55)
  • ArrayPrototypePush (56-56)
  • ArrayPrototypeUnshift (60-60)
src/js/internal/test/reporter/tap.ts (3)
src/js/internal/primordials.js (3)
  • ArrayPrototypeForEach (80-80)
  • RegExpPrototypeSymbolReplace (95-95)
  • RegExpPrototypeSymbolSplit (97-97)
src/js/internal/util/inspect.js (6)
  • ArrayPrototypeJoin (53-53)
  • ArrayPrototypePush (56-56)
  • DatePrototypeToISOString (64-64)
  • ObjectEntries (87-87)
  • StringPrototypeRepeat (116-116)
  • StringPrototypeReplaceAll (117-117)
src/js/internal/test/reporter/spec.ts (2)
  • type (53-76)
  • type (77-110)
src/js/internal/test/reporter/junit.ts (2)
src/js/internal/util/inspect.js (5)
  • ArrayPrototypeFilter (48-48)
  • ArrayPrototypeJoin (53-53)
  • ArrayPrototypePush (56-56)
  • ObjectEntries (87-87)
  • StringPrototypeRepeat (116-116)
src/js/internal/primordials.js (2)
  • ArrayPrototypeMap (85-85)
  • RegExpPrototypeSymbolReplace (95-95)
src/js/internal/test/reporter/dot.ts (2)
src/js/internal/util/inspect.js (2)
  • ArrayPrototypePush (56-56)
  • MathMax (75-75)
src/js/internal/test/reporter/spec.ts (2)
  • type (53-76)
  • type (77-110)
src/js/internal/test/reporter/utils.ts (3)
src/js/internal/util/inspect.js (2)
  • ArrayPrototypeJoin (53-53)
  • StringPrototypeRepeat (116-116)
src/js/internal/primordials.js (1)
  • RegExpPrototypeSymbolSplit (97-97)
src/js/internal/test/reporter/spec.ts (2)
  • type (53-76)
  • type (77-110)
🔇 Additional comments (8)
src/bun.js/bindings/isBuiltinModule.cpp (1)

82-82: LGTM!

The addition of "node:test/reporters" to the builtin modules list is correctly placed (alphabetically sorted by length) and consistent with the node:test pattern, which also requires the node: prefix.

src/bun.js/bindings/ProcessBindingNatives.cpp (1)

154-159: LGTM!

The additions of internal test reporter module entries are consistent with the existing pattern and properly formatted.

src/bun.js/ModuleLoader.zig (2)

2681-2681: LGTM!

The addition of @"node:test/reporters" to the HardcodedModule enum is properly coordinated with the corresponding map entry (line 2764) and alias entry (line 2904), and follows the same pattern as node:test.


2904-2904: LGTM!

The use of nodeEntryOnlyPrefix is correct here, ensuring that node:test/reporters only resolves with the node: prefix, consistent with the node:test module.

src/js/internal/test/reporter/tap.ts (1)

50-50: Visible below.

test/cli/test/claudecode-flag.test.ts (1)

9-9: Confirm environment variable name
The deletion changed from AGENTS to AGENT; ensure no references to AGENTS remain and that AGENT is the intended variable.

src/js/internal/test/reporter/lcov.ts (1)

8-105: LCOV reporter implementation looks solid

Streaming transform, per-file sections, function/branch/line metrics, and sorting are correct. Uses writableObjectMode and returns chunks safely.

src/js/node/test.reporters.ts (1)

11-58: Lazy getters/factories align with facade design

CJS require with string literals, default export object, and lazy wiring to internal reporters look good.

Comment on lines +200 to +204
exec: {
__proto__: null,
configurable: true,
value: OriginalRegExpPrototypeExec,
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix undefined reference to OriginalRegExpPrototypeExec.

Line 203 references OriginalRegExpPrototypeExec, which is not defined anywhere in this file or the visible context. This will cause a ReferenceError at runtime.

Apply this diff to use the correct variable:

     exec: {
       __proto__: null,
       configurable: true,
-      value: OriginalRegExpPrototypeExec,
+      value: RegExpPrototypeExec,
     },
📝 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.

Suggested change
exec: {
__proto__: null,
configurable: true,
value: OriginalRegExpPrototypeExec,
},
exec: {
__proto__: null,
configurable: true,
value: RegExpPrototypeExec,
},
🤖 Prompt for AI Agents
In src/js/internal/primordials.js around lines 200 to 204, the property value
references an undefined identifier `OriginalRegExpPrototypeExec`; replace that
reference with the correct, existing variable used elsewhere in this module
(e.g. `OriginalRegExpExec`) or, alternatively, declare/assign
`OriginalRegExpPrototypeExec` earlier so it points to the same defined function;
ensure the property uses the exact identifier already defined in this file to
avoid the ReferenceError.

Comment on lines +28 to +33
if (failedTests.length > 0) {
yield `\n${colors.red}Failed tests:${colors.white}\n\n`;
for (const test of failedTests) {
yield formatTestReport("test:fail", test);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Color reset after “Failed tests:” header

Header leaves terminal color as white; reset to avoid bleed.

-    yield `\n${colors.red}Failed tests:${colors.white}\n\n`;
+    yield `\n${colors.red}Failed tests:${colors.reset}\n\n`;
📝 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.

Suggested change
if (failedTests.length > 0) {
yield `\n${colors.red}Failed tests:${colors.white}\n\n`;
for (const test of failedTests) {
yield formatTestReport("test:fail", test);
}
}
if (failedTests.length > 0) {
yield `\n${colors.red}Failed tests:${colors.reset}\n\n`;
for (const test of failedTests) {
yield formatTestReport("test:fail", test);
}
}
🤖 Prompt for AI Agents
In src/js/internal/test/reporter/dot.ts around lines 28 to 33, the header writes
colors.red then colors.white leaving the terminal in white; replace the trailing
colors.white with the colors reset sequence (e.g., colors.reset or the library's
reset token) so the color is properly reset after the "Failed tests:" header to
avoid color bleed.

Comment on lines +60 to +64
function isSkipped(node) {
return (
(node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.failures
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

isSkipped checks wrong attribute

Checks attrs.failures instead of attrs.skipped, skewing suite skip counts.

-function isSkipped(node) {
-  return (
-    (node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.failures
-  );
-}
+function isSkipped(node) {
+  return (
+    (node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.skipped
+  );
+}
📝 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.

Suggested change
function isSkipped(node) {
return (
(node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.failures
);
}
function isSkipped(node) {
return (
(node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.skipped
);
}
🤖 Prompt for AI Agents
In src/js/internal/test/reporter/junit.ts around lines 60 to 64, the isSkipped
function is checking node?.attrs?.failures instead of the skipped attribute,
causing suites to be counted as skipped incorrectly; update the condition to
check node?.attrs?.skipped (or explicitly compare to a truthy/"true" value if
attrs store strings) so the function detects skipped tests correctly, e.g.,
replace the attrs.failures check with attrs.skipped while preserving the
existing null-safe access and ArrayPrototypeSome usage.

Comment on lines +33 to +51
const results = [
`\n${reporterColorMap["test:fail"]}${reporterUnicodeSymbolMap["test:fail"]}failing tests:${colors.white}\n`,
];

for (let i = 0; i < this.#failedTests.length; i++) {
const test = this.#failedTests[i];
const formattedErr = formatTestReport("test:fail", test);

if (test.file) {
const relPath = relative(this.#cwd, test.file);
const location = `test at ${relPath}:${test.line}:${test.column}`;
ArrayPrototypePush.$apply(results, location);
}

ArrayPrototypePush.$apply(results, formattedErr);
}

this.#failedTests = []; // Clean up the failed tests
return ArrayPrototypeJoin.$apply(results, "\n");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Color bleed risk in “failing tests” header

Header switches to white and never resets; subsequent output may inherit white.

-    const results = [
-      `\n${reporterColorMap["test:fail"]}${reporterUnicodeSymbolMap["test:fail"]}failing tests:${colors.white}\n`,
-    ];
+    const results = [
+      `\n${reporterColorMap["test:fail"]}${reporterUnicodeSymbolMap["test:fail"]}failing tests:${colors.reset}\n`,
+    ];
📝 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.

Suggested change
const results = [
`\n${reporterColorMap["test:fail"]}${reporterUnicodeSymbolMap["test:fail"]}failing tests:${colors.white}\n`,
];
for (let i = 0; i < this.#failedTests.length; i++) {
const test = this.#failedTests[i];
const formattedErr = formatTestReport("test:fail", test);
if (test.file) {
const relPath = relative(this.#cwd, test.file);
const location = `test at ${relPath}:${test.line}:${test.column}`;
ArrayPrototypePush.$apply(results, location);
}
ArrayPrototypePush.$apply(results, formattedErr);
}
this.#failedTests = []; // Clean up the failed tests
return ArrayPrototypeJoin.$apply(results, "\n");
const results = [
`\n${reporterColorMap["test:fail"]}${reporterUnicodeSymbolMap["test:fail"]}failing tests:${colors.reset}\n`,
];
for (let i = 0; i < this.#failedTests.length; i++) {
const test = this.#failedTests[i];
const formattedErr = formatTestReport("test:fail", test);
if (test.file) {
const relPath = relative(this.#cwd, test.file);
const location = `test at ${relPath}:${test.line}:${test.column}`;
ArrayPrototypePush.$apply(results, location);
}
ArrayPrototypePush.$apply(results, formattedErr);
}
this.#failedTests = []; // Clean up the failed tests
return ArrayPrototypeJoin.$apply(results, "\n");
🤖 Prompt for AI Agents
In src/js/internal/test/reporter/spec.ts around lines 33 to 51, the "failing
tests" header ends with colors.white which forces subsequent output to remain
white; replace the trailing colors.white with the ANSI reset code (e.g.,
colors.reset) or append colors.reset immediately after the header newline so the
header's color is reset and following formattedErr lines use their own colors;
ensure only the header text is colored and then call ArrayPrototypePush with the
reset header string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants