From 6d19bf732f4c6381b7fbe7925bc15093c0a9ffcc Mon Sep 17 00:00:00 2001 From: Vladimir Date: Thu, 17 Feb 2022 11:18:15 +0300 Subject: [PATCH] fix: fix error if toMatchInlineSnapshot is called on resolves/rejects (#773) --- .../src/integrations/chai/jest-expect.ts | 6 ++++-- .../vitest/src/integrations/snapshot/chai.ts | 6 ++++-- .../src/integrations/snapshot/client.ts | 3 ++- .../src/integrations/snapshot/port/state.ts | 19 ++++++++++++++----- test/core/test/snapshot-inline.test.ts | 12 ++++++++++++ 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/vitest/src/integrations/chai/jest-expect.ts b/packages/vitest/src/integrations/chai/jest-expect.ts index 58e09ef34254..f7aa49eeecd6 100644 --- a/packages/vitest/src/integrations/chai/jest-expect.ts +++ b/packages/vitest/src/integrations/chai/jest-expect.ts @@ -491,8 +491,9 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => { ) }) - utils.addProperty(chai.Assertion.prototype, 'resolves', function(this: any) { + utils.addProperty(chai.Assertion.prototype, 'resolves', function __VITEST_RESOLVES__(this: any) { utils.flag(this, 'promise', 'resolves') + utils.flag(this, 'error', new Error('resolves')) const obj = utils.flag(this, 'object') const proxy: any = new Proxy(this, { get: (target, key, receiver) => { @@ -518,8 +519,9 @@ export const JestChaiExpect: ChaiPlugin = (chai, utils) => { return proxy }) - utils.addProperty(chai.Assertion.prototype, 'rejects', function(this: any) { + utils.addProperty(chai.Assertion.prototype, 'rejects', function __VITEST_REJECTS__(this: any) { utils.flag(this, 'promise', 'rejects') + utils.flag(this, 'error', new Error('rejects')) const obj = utils.flag(this, 'object') const wrapper = typeof obj === 'function' ? obj() : obj // for jest compat const proxy: any = new Proxy(this, { diff --git a/packages/vitest/src/integrations/snapshot/chai.ts b/packages/vitest/src/integrations/snapshot/chai.ts index f2e303b3394b..c91d4dfacfb4 100644 --- a/packages/vitest/src/integrations/snapshot/chai.ts +++ b/packages/vitest/src/integrations/snapshot/chai.ts @@ -44,6 +44,7 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { 'toMatchInlineSnapshot', function __VITEST_INLINE_SNAPSHOT__(this: Record, properties?: object, inlineSnapshot?: string, message?: string) { const expected = utils.flag(this, 'object') + const error = utils.flag(this, 'error') if (typeof properties === 'string') { message = inlineSnapshot inlineSnapshot = properties @@ -51,7 +52,7 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { } if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot) - getSnapshotClient().assert(expected, message, true, properties, inlineSnapshot) + getSnapshotClient().assert(expected, message, true, properties, inlineSnapshot, error) }, ) utils.addMethod( @@ -67,7 +68,8 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { 'toThrowErrorMatchingInlineSnapshot', function __VITEST_INLINE_SNAPSHOT__(this: Record, inlineSnapshot: string, message: string) { const expected = utils.flag(this, 'object') - getSnapshotClient().assert(getErrorString(expected), message, true, undefined, inlineSnapshot) + const error = utils.flag(this, 'error') + getSnapshotClient().assert(getErrorString(expected), message, true, undefined, inlineSnapshot, error) }, ) } diff --git a/packages/vitest/src/integrations/snapshot/client.ts b/packages/vitest/src/integrations/snapshot/client.ts index 3a12d733e03e..3ab414637456 100644 --- a/packages/vitest/src/integrations/snapshot/client.ts +++ b/packages/vitest/src/integrations/snapshot/client.ts @@ -43,7 +43,7 @@ export class SnapshotClient { this.test = undefined } - assert(received: unknown, message?: string, isInline = false, properties?: object, inlineSnapshot?: string): void { + assert(received: unknown, message?: string, isInline = false, properties?: object, inlineSnapshot?: string, error?: Error): void { if (!this.test) throw new Error('Snapshot cannot be used outside of test') @@ -73,6 +73,7 @@ export class SnapshotClient { testName, received, isInline, + error, inlineSnapshot, }) diff --git a/packages/vitest/src/integrations/snapshot/port/state.ts b/packages/vitest/src/integrations/snapshot/port/state.ts index 7025cd90bba5..fe885200a28c 100644 --- a/packages/vitest/src/integrations/snapshot/port/state.ts +++ b/packages/vitest/src/integrations/snapshot/port/state.ts @@ -9,7 +9,7 @@ import fs from 'fs' import type { Config } from '@jest/types' // import { getStackTraceLines, getTopFrame } from 'jest-message-util' import type { OptionsReceived as PrettyFormatOptions } from 'pretty-format' -import type { SnapshotData, SnapshotMatchOptions, SnapshotStateOptions } from '../../../types' +import type { ParsedStack, SnapshotData, SnapshotMatchOptions, SnapshotStateOptions } from '../../../types' import { slash } from '../../../utils' import { parseStacktrace } from '../../../utils/source-map' import type { InlineSnapshot } from './inlineSnapshot' @@ -87,6 +87,18 @@ export default class SnapshotState { }) } + private _getInlineSnapshotStack(stacks: ParsedStack[]) { + // if called inside resolves/rejects, stacktrace is different + const promiseIndex = stacks.findIndex(i => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/)) + if (promiseIndex !== -1) + return stacks[promiseIndex + 3] + + // inline snapshot function is called __VITEST_INLINE_SNAPSHOT__ + // in integrations/snapshot/chai.ts + const stackIndex = stacks.findIndex(i => i.method.includes('__VITEST_INLINE_SNAPSHOT__')) + return stackIndex !== -1 ? stacks[stackIndex + 2] : null + } + private _addSnapshot( key: string, receivedSerialized: string, @@ -97,10 +109,7 @@ export default class SnapshotState { const error = options.error || new Error('Unknown error') const stacks = parseStacktrace(error, true) stacks.forEach(i => i.file = slash(i.file)) - // inline snapshot function is called __VITEST_INLINE_SNAPSHOT__ - // in integrations/snapshot/chai.ts - const stackIndex = stacks.findIndex(i => i.method.includes('__VITEST_INLINE_SNAPSHOT__')) - const stack = stackIndex !== -1 ? stacks[stackIndex + 2] : null + const stack = this._getInlineSnapshotStack(stacks) if (!stack) { throw new Error( `Vitest: Couldn't infer stack frame for inline snapshot.\n${JSON.stringify(stacks)}`, diff --git a/test/core/test/snapshot-inline.test.ts b/test/core/test/snapshot-inline.test.ts index 4bfabc8ed071..6d043a00162c 100644 --- a/test/core/test/snapshot-inline.test.ts +++ b/test/core/test/snapshot-inline.test.ts @@ -106,3 +106,15 @@ test('literal tag', () => { " `) }) + +test('resolves', async() => { + const getText = async() => 'text' + await expect(getText()).resolves.toMatchInlineSnapshot('"text"') +}) + +test('rejects', async() => { + const getText = async() => { + throw new Error('error') + } + await expect(getText()).rejects.toMatchInlineSnapshot('[Error: error]') +})