Skip to content

fix(test): allow test functions to override reported location#32732

Merged
bartlomieju merged 2 commits intodenoland:mainfrom
shivamtiwari3:fix/junit-location-symbol
Mar 17, 2026
Merged

fix(test): allow test functions to override reported location#32732
bartlomieju merged 2 commits intodenoland:mainfrom
shivamtiwari3:fix/junit-location-symbol

Conversation

@shivamtiwari3
Copy link
Copy Markdown
Contributor

Summary

Fixes #20047.

In cli/js/40_test.js, testInner now checks whether the registered test function carries a Symbol.for("Deno.test.location") property before falling back to core.currentUserCallSite(). If the symbol is set, its string value (format: "fileName:lineNumber:columnNumber") is parsed and used as the test location. This allows test-helper libraries like @std/testing/bdd to declare the user's source location instead of the library's own call site.


Root Cause

In cli/js/40_test.js:302 (before this fix):

testDesc.location = core.currentUserCallSite();

core.currentUserCallSite() captures the stack frame where Deno.test() is called. When a BDD library such as @std/testing/bdd wraps user tests and calls Deno.test() internally, the captured location is inside the library file (e.g. https://jsr.io/@std/testing/.../bdd.ts), not the user's test file.

The JUnit reporter uses description.location.file_name to both name the <testsuite> element and populate each <testcase classname="...">. With the wrong location, every test registered via bdd.ts is grouped under the library URL:

<!-- Before fix -->
<testsuite name="https://jsr.io/@std/testing/1.0.0/bdd.ts" ...>

This breaks CI test-reporting tools (e.g. dorny/test-reporter, EnricoMi/publish-unit-test-result-action) that rely on the suite name to map results back to source files.


Solution

Before reading core.currentUserCallSite(), check for a well-known symbol on the test function:

const locationOverride = testDesc.fn[SymbolFor("Deno.test.location")];
testDesc.location = locationOverride
  ? parseTestLocation(locationOverride)
  : core.currentUserCallSite();

parseTestLocation splits "fileName:lineNumber:columnNumber" from the right, so URL schemes containing : (e.g. file:///…, https://…) are handled correctly.

A follow-up change to @std/testing/bdd (in the std repo) will set Symbol.for("Deno.test.location") on each wrapped test function to point at the user's source file, completing the fix end-to-end.


Testing

  • Added tests/specs/test/junit_location_override/ — a new spec test that simulates a library-registered test (by setting Symbol.for("Deno.test.location") on the function) alongside an ordinary test, and asserts that the JUnit XML groups them into separate <testsuite> elements with the correct names and line/column numbers.
  • All six existing JUnit spec tests continue to pass unchanged.
test specs::test::hide_stacktraces::reporter_junit ... ok
test specs::test::junit                           ... ok
test specs::test::junit_console_formatting        ... ok
test specs::test::junit_location_override         ... ok  ← new
test specs::test::junit_multiple_test_files       ... ok
test specs::test::junit_nested                    ... ok

Checklist

  • Fixes the root cause (not just the symptom) — the location is captured correctly at registration time
  • New spec test covers the exact scenario from the issue report
  • All existing JUnit spec tests pass
  • No unrelated changes
  • Code style matches surrounding primordials pattern (StringPrototypeLastIndexOf, StringPrototypeSlice, SymbolFor)
  • Read CONTRIBUTING.md and followed its requirements

…bol.for("Deno.test.location")

Root cause: `Deno.test()` always records the call site of `Deno.test()`
itself as the test location. When BDD-style helper libraries (e.g.
`@std/testing/bdd`) call `Deno.test()` internally on behalf of the
user, the recorded location points to the library file rather than the
user's source file. This causes the JUnit reporter (and others) to group
tests under the library URL (e.g. `_test_suite.ts`) instead of the
user's file (fixes denoland#20047).

Fix: Before falling back to `core.currentUserCallSite()`, `testInner`
now checks whether the test function carries a
`Symbol.for("Deno.test.location")` property. If it does, that string
(in `"fileName:lineNumber:columnNumber"` format) is used as the test
location instead. Parsing is done from the right so that URL schemes
that contain `:` (such as `file://` and `https://`) are handled
correctly.

A follow-up change to `@std/testing/bdd` will set this symbol when
registering tests so that the JUnit reporter shows the user's test file.
@bartlomieju bartlomieju changed the title fix(test): allow test functions to override reported location via Symbol.for("Deno.test.location") (fixes #20047) fix(test): allow test functions to override reported location Mar 15, 2026
    - Type-check that the symbol value is a string
    - Validate colon positions exist (not -1 or 0)
    - Check parsed numbers aren't NaN
    - Return null on any invalid input, falling back to currentUserCallSite()
    - Use NumberIsNaN primordial instead of Number.isNaN

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

Thanks

@bartlomieju bartlomieju enabled auto-merge (squash) March 17, 2026 12:00
@bartlomieju bartlomieju merged commit 14bb3e7 into denoland:main Mar 17, 2026
112 checks passed
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.

deno test --reporter junit get incorrect testsuite.name when use deno_std/testing/bdd.ts

2 participants