-
Notifications
You must be signed in to change notification settings - Fork 3.4k
js: add node:test/reporters module #23366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Updated 1:14 AM PT - Oct 8th, 2025
❌ @nektro, your commit b059f03 has 2 failures in
🧪 To try this PR locally: bunx bun-pr 23366 That installs a local version of the PR into your bun-23366 --bun |
WalkthroughAdds 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
Possibly related PRs
Suggested reviewers
Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (1 passed)
Comment |
There was a problem hiding this 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.
📒 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 usebun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; useport: 0
to get a random port
When spawning Bun in tests, usebunExe()
andbunEnv
fromharness
Preferasync/await
in tests; for a single callback, usePromise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
UsetempDir
/tempDirWithFiles
fromharness
for temporary files and directories in tests
For large/repetitive strings in tests, preferBuffer.alloc(count, fill).toString()
over"A".repeat(count)
Import common test utilities fromharness
(e.g.,bunExe
,bunEnv
,tempDirWithFiles
,tmpdirSync
, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and usetoThrow
for synchronous errors
Usedescribe
blocks for grouping,describe.each
for parameterized tests, snapshots withtoMatchSnapshot
, and lifecycle hooks (beforeAll
,beforeEach
,afterEach
); track resources for cleanup inafterEach
Useusing
/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").bunWhen adding debug logs in Zig, create a scoped logger and log via Bun APIs:
const log = bun.Output.scoped(.${SCOPE}, .hidden);
thenlog("...", .{})
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 thenode:test
pattern, which also requires thenode:
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 theHardcodedModule
enum is properly coordinated with the corresponding map entry (line 2764) and alias entry (line 2904), and follows the same pattern asnode:test
.
2904-2904
: LGTM!The use of
nodeEntryOnlyPrefix
is correct here, ensuring thatnode:test/reporters
only resolves with thenode:
prefix, consistent with thenode: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 fromAGENTS
toAGENT
; ensure no references toAGENTS
remain and thatAGENT
is the intended variable.src/js/internal/test/reporter/lcov.ts (1)
8-105
: LCOV reporter implementation looks solidStreaming 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 designCJS require with string literals, default export object, and lazy wiring to internal reporters look good.
exec: { | ||
__proto__: null, | ||
configurable: true, | ||
value: OriginalRegExpPrototypeExec, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
if (failedTests.length > 0) { | ||
yield `\n${colors.red}Failed tests:${colors.white}\n\n`; | ||
for (const test of failedTests) { | ||
yield formatTestReport("test:fail", test); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
function isSkipped(node) { | ||
return ( | ||
(node?.children && ArrayPrototypeSome.$apply(node.children, c => c.tag === "skipped")) || node?.attrs?.failures | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
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"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
found while investigating #23062