diff --git a/packages/vitest/src/integrations/snapshot/chai.ts b/packages/vitest/src/integrations/snapshot/chai.ts index 6ee0b0e62d6e..6f9ebbd6b79c 100644 --- a/packages/vitest/src/integrations/snapshot/chai.ts +++ b/packages/vitest/src/integrations/snapshot/chai.ts @@ -52,6 +52,9 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { chai.Assertion.prototype, key, function (this: Record, properties?: object, message?: string) { + const isNot = utils.flag(this, 'negate') + if (isNot) + throw new Error(`${key} cannot be used with "not"`) const expected = utils.flag(this, 'object') const test = utils.flag(this, 'vitest-test') if (typeof properties === 'string' && typeof message === 'undefined') { @@ -75,6 +78,9 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { chai.Assertion.prototype, 'toMatchFileSnapshot', function (this: Record, file: string, message?: string) { + const isNot = utils.flag(this, 'negate') + if (isNot) + throw new Error('toMatchFileSnapshot cannot be used with "not"') const expected = utils.flag(this, 'object') const test = utils.flag(this, 'vitest-test') as Test const errorMessage = utils.flag(this, 'message') @@ -98,6 +104,9 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { chai.Assertion.prototype, 'toMatchInlineSnapshot', function __INLINE_SNAPSHOT__(this: Record, properties?: object, inlineSnapshot?: string, message?: string) { + const isNot = utils.flag(this, 'negate') + if (isNot) + throw new Error('toMatchInlineSnapshot cannot be used with "not"') const test = utils.flag(this, 'vitest-test') const isInsideEach = test && (test.each || test.suite?.each) if (isInsideEach) @@ -129,6 +138,9 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { chai.Assertion.prototype, 'toThrowErrorMatchingSnapshot', function (this: Record, message?: string) { + const isNot = utils.flag(this, 'negate') + if (isNot) + throw new Error('toThrowErrorMatchingSnapshot cannot be used with "not"') const expected = utils.flag(this, 'object') const test = utils.flag(this, 'vitest-test') const promise = utils.flag(this, 'promise') as string | undefined @@ -145,6 +157,9 @@ export const SnapshotPlugin: ChaiPlugin = (chai, utils) => { chai.Assertion.prototype, 'toThrowErrorMatchingInlineSnapshot', function __INLINE_SNAPSHOT__(this: Record, inlineSnapshot: string, message: string) { + const isNot = utils.flag(this, 'negate') + if (isNot) + throw new Error('toThrowErrorMatchingInlineSnapshot cannot be used with "not"') const test = utils.flag(this, 'vitest-test') const isInsideEach = test && (test.each || test.suite?.each) if (isInsideEach) diff --git a/test/fails/fixtures/snapshot-with-not.test.ts b/test/fails/fixtures/snapshot-with-not.test.ts new file mode 100644 index 000000000000..f4de629e2b50 --- /dev/null +++ b/test/fails/fixtures/snapshot-with-not.test.ts @@ -0,0 +1,11 @@ +import { expect, test } from "vitest" + +test.each([ + 'toMatchSnapshot', + 'toMatchFileSnapshot', + 'toMatchInlineSnapshot', + 'toThrowErrorMatchingSnapshot', + 'toThrowErrorMatchingInlineSnapshot', +])('%s should fail with not', (api) => { + (expect(0).not as any)[api]() +}) diff --git a/test/fails/test/__snapshots__/runner.test.ts.snap b/test/fails/test/__snapshots__/runner.test.ts.snap index 5ee589c515ee..6fe18ff23435 100644 --- a/test/fails/test/__snapshots__/runner.test.ts.snap +++ b/test/fails/test/__snapshots__/runner.test.ts.snap @@ -33,6 +33,14 @@ exports[`should fail nested-suite.test.ts > nested-suite.test.ts 1`] = `"Asserti exports[`should fail primitive-error.test.ts > primitive-error.test.ts 1`] = `"Unknown Error: 42"`; +exports[`should fail snapshot-with-not.test.ts > snapshot-with-not.test.ts 1`] = ` +"Error: toThrowErrorMatchingInlineSnapshot cannot be used with "not" +Error: toThrowErrorMatchingSnapshot cannot be used with "not" +Error: toMatchInlineSnapshot cannot be used with "not" +Error: toMatchFileSnapshot cannot be used with "not" +Error: toMatchSnapshot cannot be used with "not"" +`; + exports[`should fail stall.test.ts > stall.test.ts 1`] = ` "TypeError: failure TypeError: failure