Hi there.
:warning: I'm not sure if this is actually a bug. Happy to ask the question elsewhere if it's not!
I'm trying to create a custom inline snapshot matcher. I couldn't find any relevant documentation so have been bouncing off what's already written for custom snapshot matchers.
Here's a minimal working repro of what I'm about to describe.
The custom matcher looks something like this:
// src/to-match-inline-custom-snapshot.ts
export function toMatchInlineCustomSnapshot(received) {
return toMatchInlineSnapshot.call(this, received);
}
When I use that custom matcher in a seperate test file, it places the inline snapshot inside the custom matcher file, instead of in the test file:
// src/__tests__/to-match-inline-custom-snapshot.test.ts
test('inline custom snapshot', () => {
// @ts-ignore
expect('extra long string oh my gerd').toMatchInlineCustomSnapshot(
// I'd like the snapshot to appear here...
);
});
// ...but the snapshot appears in src/to-match-inline-custom-snapshot.ts
export function toMatchInlineCustomSnapshot(received) {
return toMatchInlineSnapshot.call(
this,
received,
`"extra long string oh my gerd"`
);
}
I've dug through the source code a bit, and have ended up at getTopFrame. It looks like getTopFrame will return the first relevant frame it finds after filtering etc, and this is used as the location to output the inline snapshot.
However, in this case there are two relevant frames it has to consider. One is the file the custom matcher is in, and the other is the actual test file. The filtered stack frames list looks something like this:
[
'Error',
' at SnapshotState._addSnapshot (/jest-inline-custom-matcher/node_modules/jest-snapshot/build/State.js:66:38)',
' at Object.call (/jest-inline-custom-matcher/src/to-match-inline-custom-snapshot.ts:4:32)',
' at Object.toMatchInlineCustomSnapshot (/jest-inline-custom-matcher/src/__tests__/to-match-inline-custom-snapshot.test.ts:5:42)'
];
It looks like getTopFrame hits the src/to-match-inline-custom-snapshot.ts line and returns that immediately, which is why the inline snapshot ends up in that file.
So assuming I've understood the intent correctly, my question is:
Should getTopFrame indeed return the top frame, which in this case would be the src/__tests__/to-match-custom-snapshot.ts line?
... or is there a simpler way around all of this that I've completely missed? 馃槄
Thanks!
This is a bug (or potentially a missing feature). Not sure how to best support it, though... @azz any ideas?
This was discussed a bit on twitter with @Haroenv & @rickhanlonii.
https://twitter.com/lucasazzola/status/1102546183979884544
Jest would need to be able to figure out that the call is coming from a custom matcher and skip those frames in order for this to work.
It's working "as expected" but probably not as the user expects.
Thanks for the replies :pray:
For now I've got a brittle little hack working that involves setting a custom error (with modified stack) on the context I'm calling toMatchInlineSnapshot with.
Remains to be seen whether this is actually fit for production. Will see where I end up 馃槄
Most helpful comment
This was discussed a bit on twitter with @Haroenv & @rickhanlonii.
https://twitter.com/lucasazzola/status/1102546183979884544
It's working "as expected" but probably not as the user expects.