-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
test_runner: fix Date serialization in TAP reporter YAML output #58762
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
Review requested:
|
I could certainly see someone wanting the ISO string when that's the only difference. What about the case where actual vs expected are not both native Dates? |
const tapReporterPath = require.resolve('../../lib/internal/test_runner/reporter/tap.js'); | ||
const fs = require('fs'); | ||
const tapReporterSource = fs.readFileSync(tapReporterPath, 'utf8'); | ||
|
||
// Verify that the fix is present in the source code | ||
// The fix adds an early return after Date processing to prevent object enumeration | ||
assert(tapReporterSource.includes('return result; // Early return to prevent processing Date as object'), | ||
'TAP reporter should contain the Date serialization fix'); | ||
|
||
// Verify that Date ISO conversion happens with the early return | ||
assert(tapReporterSource.includes('DatePrototypeToISOString(value)'), | ||
'Date processing should be present'); | ||
|
||
// Verify the exact pattern: Date processing followed by early return | ||
const fixPattern = /DatePrototypeToISOString\(value\);[\s\S]*?return result; \/\/ Early return to prevent processing Date as object/; | ||
assert(fixPattern.test(tapReporterSource), | ||
'Date processing should be followed by early return to prevent object processing'); |
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.
This kind of test is way too fragile and white-box.
A general suggestion (which also applies here): coupling a test with implementation details leads to tests that are not resistant against refactoring.
Furthermore, this test doesn’t check the actual output, but only that the code is present and must be changed.
I would suggest adding a snapshot test in this case, as it covers only the behaviour without checking internal logic!
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.
Thanks for the excellent feedback! You're absolutely right about both points:
🔧 Mixed Date/Non-Date Edge Cases
I tested the scenarios where actual vs expected aren't both native Dates, and they work correctly with the fix:
// Date vs String - shows clear distinction
expected: '2023-01-01T12:00:00.000Z' // String (with quotes)
actual: 2023-01-01T13:00:00.000Z // Date (clean ISO)
// Date vs Object - proper object enumeration vs clean Date
expected: { toISOString: [Function], valueOf: [Function] }
actual: 2023-01-01T13:00:00.000Z
The fix correctly handles all combinations because it only affects Date object serialization specifically.
🧪 Replaced Fragile White-Box Test with Robust Behavioral Testing
You're absolutely right that the original test was too fragile and implementation-coupled. I've completely rewritten the testing approach:
❌ Before (fragile):
// Checking implementation details - breaks on refactoring
assert(tapReporterSource.includes('return result; // Early return...'))
✅ After (robust):
test/fixtures/test-runner/output/tap_date_serialization.js
- Test scenarios with various Date combinationstest/fixtures/test-runner/output/tap_date_serialization.snapshot
- Expected TAP output- Added to
test/parallel/test-runner-output.mjs
- Integrated with existing snapshot testing
This approach:
- ✅ Tests actual behavior, not implementation details
- ✅ Resistant to refactoring (tests TAP output format)
- ✅ Covers edge cases (Date vs Date, Date vs String, nested Dates)
- ✅ Validates that Date objects don't leak their methods/properties
- ✅ Follows Node.js testing patterns
The snapshot test ensures clean output like expected: 2023-01-01T12:00:00.000Z
instead of verbose object dumps, which addresses the ISO string visibility concern too.
@pmarchini review |
@Ronitsabhaya75 this is a bit rude. Let us remember our pleases and thank-yous 🙂 Also, this PR and most of your comments very much seem purely AI generated. Whilst this is not specifically disallowed, it significantly lowers confidence and raises other concerns about the contribution. |
I didn't meant in rude way. I Tagged him because he left the comment and would suggest me if i need edit. It's not AI generated completely AI helped me FR😭 I'm really sorry if it was seem that way |
I figured that was why 🙂 "could you re-review please" sounds much nicer. RE: AI generated I get almost identical output from ChatGPT 🙃 Again, using AI is not forbidden, and many of us use AI assistance. The concern is when it's used as a replacement. |
If you think so, I can close this one and make another one. I understand the concern. |
No need for that—that's just extra work for everyone 😉 And I don't mean to discourage you: We're happy to have your contributions 🙂 |
fix(test_runner): prevent Date object property enumeration in TAP YAML output
Problem
When Date objects appeared in test assertion errors (e.g., in
expected
andactual
values), the TAP reporter'sjsToYaml
function would:This resulted in verbose, cluttered YAML output like:
Instead of the clean, expected output:
Solution
Added an early return in the
jsToYaml
function after Date objects are converted to ISO strings, preventing them from being processed as regular objects with enumerable properties.File changed:
lib/internal/test_runner/reporter/tap.js
Testing
test/parallel/test-tap-yaml-date-serialization.js
Verification
You can test this fix by running:
The output should show clean ISO strings like
expected: 2023-01-01T12:00:00.000Z
instead of Date object properties.Impact