Comments (13)
I'm noting that this is probably related to tapjs/stack-utils#61, which has a whole ton of discussion about cause formatting in general. It's probably the place to go to discuss specifics on that mark! (See also jestjs/jest#11935.) But I'm keeping this issue around as tracking for other ways to integrate custom or Node.js-built-in error tracing for tap itself.
from tapjs.
I've done some digging in the source to try to get more familiar with basically how tap works and where changes would be needed, and the give-away (after digging in the reporter code) is that the reporter is most certainly parsing the tap results, with no extra "magic" after the fact to generate new information, so the core test runner is responsible (which generates tap output) is responsible for stack tracing.
Specifically, the function we've gotta look at is TestBase.threw
. Stack tracing is handled here, essentially joining (one for each line) the results of parseStack
. Internal details are super interesting (@tapjs/stack
is cool!) but not relevant for this issue, since they're lower level than processing a thrown error object itself.
I'm not sure what the ideal solution would be for embedding information that isn't a plain stack trace into the results here. I guess the good thing is that YAML Diagnostic blocks aren't standardized? So we can choose to add completely new information here, without altering the existing expected contents of stack
.
Personally, seeing as it's a structured YAML object anyway, I think we should basically allow recursive details here, exactly the same as the current flat shape is reported, just without tapCaught
(since I'm assuming that's only relevant to the top-level error). That means including stack
, at
, and source
for every nested error, as well as cause
(single item recursive) and errors
(array recursive) when applicable. (Oh, and message
for nested errors, too!) It'd be up to the reporter to decide what to do with that data — including not displaying it at all, for example.
Of course, all this means that as-is, cause
and errors
information is just completely discarded — it's not part of the TAP output (i.e. YAML diagnostic block) and so unavailable for processing by reporters.
tap's error reporting for result details is handled by ResultDetails
, and expressly parses the diagnostic object to provide source and stack information (respectively Source
and Stack
). If we add a new key on the diagnostic results - rather than messing with the existing stack
- then we'd need to add a new element for handling recursion, displaying message
and at
information for sure, and maybe a compressed/context-sensitive version of stack
(ala Node.js) and maaaaaaybe source
if an option is set, too.
Actually, if stack
is context-sensitive, we need the top-level stack to be similarly context-sensitive. We could accomplish that in two ways:
- By providing the entire diagnostic structure to
Stack
and a pointer to the current entry in that structure, allowingStack
to infer which lines are duplicates and should be hidden for conciseness - By doing that processing ourselves and just providing a concise stack string to
Stack
from the get-go, and making the recursive component responsible not just for nested stacks, but the top-level one too (since it'll contain the conciseness logic)
I'm definitely inclined more towards the second approach, because it keeps Stack
logic simple, isolates recursive or recursion-sensitive logic into a dedicated component, and avoids "special" behavior for trace reporting on the top-level error, since that's just a case where the root node is also the (only) leaf node.
I might give implementing all of this a shot, since implementation-wise it doesn't sound dreadfully complicated (recursion in TypeScript isn't that hard, right!?), and would be a fun project to get familiar with tap's internals — even if any of this is out of scope for tap or some totally different approach is selected. But no guarantees I'll get anywhere with my code! 👾
from tapjs.
We did it!
We still need to do test cases, and probably some extra-detail adjustments (it doesn't display the error type, nor any otherDiags
-style details; stack beneath heading should possibly also be indented to match Node.js...) — but the essential implementation is all here. See our detailed commit messages if so desired. (We'll try to make a PR happen sometime soon.)
Also some checking against Node.js to make sure everything is, in fact, working precisely as intended (that's where we're pulling the essential appearance, "42 lines matching cause trace" messaging, and a chunk of implementation code from).
from tapjs.
Related Issues (20)
- [FEAT] `--disable-coverage` should imply `--allow-empty-coverage` HOT 5
- [BUG] Coverage map is not working HOT 2
- [BUG] tap.before/tap.teardown are weird when import and requiring `tap` HOT 1
- [BUG] Async and Sync Tests don't run as intended with `@tapjs/mocha-global` HOT 3
- [BUG] mocha-globals before/after hook functions no longer support a done function? HOT 1
- [BUG] mocha-globals beforeEach hooks run for describes too when it should only for it tests HOT 1
- [BUG] Long standing bug in ink is causing crash on start. HOT 3
- [BUG] matchSnapshot returns RangeError HOT 3
- [BUG] TypeError: Cannot read private member #Class from an object whose class did not declare it HOT 3
- [BUG] Timeout error when running Node.js HTTP Server with TAP HOT 3
- [BUG] test context is not passed to subtest if accessed in beforeEach HOT 2
- [BUG] Performance degradation when setTimeout / setImmediate is not used in parent test
- [BUG] Performance degradation when large number of assertions is checked at once, with non-silent reporter
- [FEATURE] I can't use path aliases for typescript projects HOT 1
- [BUG] Tap.END does fully close the project with success HOT 2
- docs: clarify that mockImport is "load with a mocked import" and not "mock the inported thing" HOT 8
- coverage map path in extended configs should be relative to the extended config, not the original config HOT 1
- [BUG] t.context is undefined in t.beforeEach() HOT 1
- [BUG] Typo in manpage -h HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tapjs.