diff --git a/packages/utils/src/source-map.ts b/packages/utils/src/source-map.ts index 738a13cf3f0f..65a5be8bf4b4 100644 --- a/packages/utils/src/source-map.ts +++ b/packages/utils/src/source-map.ts @@ -232,13 +232,14 @@ export function parseStacktrace( ? parseFFOrSafariStackTrace(stack) : parseV8Stacktrace(stack) - // remove assertion helper's internal stacks + // remove vi.defineHelper's internal stacks const helperIndex = stacks.findLastIndex(s => - s.method === '__VITEST_HELPER__' - // firefox - || s.method === 'async*__VITEST_HELPER__' - // webkit - || s.method === 'async __VITEST_HELPER__', + // this covers cases such as + // "__VITEST_HELPER__" + // "__VITEST_HELPER__ [as ]" + // "async*__VITEST_HELPER__" (firefox) + // "async __VITEST_HELPER__" (webkit) + s.method.includes('__VITEST_HELPER__'), ) if (helperIndex >= 0) { stacks = stacks.slice(helperIndex + 1) diff --git a/packages/vitest/src/integrations/vi.ts b/packages/vitest/src/integrations/vi.ts index 4b1822223f5a..f8d94f99ec2e 100644 --- a/packages/vitest/src/integrations/vi.ts +++ b/packages/vitest/src/integrations/vi.ts @@ -612,8 +612,8 @@ function createVitest(): VitestUtils { waitFor, waitUntil, defineHelper: (fn) => { - return function __VITEST_HELPER__(...args: any[]): any { - const result = fn(...args) + return function __VITEST_HELPER__(this: any, ...args: any[]): any { + const result = fn.apply(this, args) if (result && typeof result === 'object' && typeof result.then === 'function') { return (async function __VITEST_HELPER__() { return await result diff --git a/test/cli/fixtures/assertion-helper/basic.test.ts b/test/cli/fixtures/assertion-helper/basic.test.ts index 8431f6ff1fbf..e8df6c7a56da 100644 --- a/test/cli/fixtures/assertion-helper/basic.test.ts +++ b/test/cli/fixtures/assertion-helper/basic.test.ts @@ -104,3 +104,30 @@ const myHelperWithLogs = vi.defineHelper(() => { test("helper with logs", () => { myHelperWithLogs(); }); + +const helperObject = { + prop: 1234, + assertEqualProp: vi.defineHelper(function (this: any, actual: any) { + expect(actual).toEqual(this.prop); + }), + assertEqualPropAsync: vi.defineHelper(async function (this: any, actual: any) { + await new Promise((r) => setTimeout(r, 1)); + expect(actual).toEqual(this.prop); + }), +} + +test("helper with context pass", () => { + helperObject.assertEqualProp(1234); +}); + +test("helper with context fail", () => { + helperObject.assertEqualProp(4321); +}); + +test("async helper with context pass", async () => { + await helperObject.assertEqualPropAsync(1234); +}); + +test("async helper with context fail", async () => { + await helperObject.assertEqualPropAsync(4321); +}); diff --git a/test/cli/test/assertion-helper.test.ts b/test/cli/test/assertion-helper.test.ts index 315d1ad0fec7..9615c4d7ac27 100644 --- a/test/cli/test/assertion-helper.test.ts +++ b/test/cli/test/assertion-helper.test.ts @@ -13,7 +13,7 @@ it('assertion helper', async () => { ❯ basic.test.ts:105:3 - ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 8 ⎯⎯⎯⎯⎯⎯⎯ + ⎯⎯⎯⎯⎯⎯ Failed Tests 10 ⎯⎯⎯⎯⎯⎯⎯ FAIL basic.test.ts > sync AssertionError: expected 'sync' to deeply equal 'x' @@ -29,7 +29,7 @@ it('assertion helper', async () => { 23| }); 24| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/11]⎯ FAIL basic.test.ts > async AssertionError: expected 'async' to deeply equal 'x' @@ -45,7 +45,7 @@ it('assertion helper', async () => { 27| }); 28| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/11]⎯ FAIL basic.test.ts > soft AssertionError: expected 'soft' to deeply equal 'x' @@ -61,7 +61,7 @@ it('assertion helper', async () => { 31| }); 32| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/11]⎯ FAIL basic.test.ts > soft async AssertionError: expected 'soft async' to deeply equal 'x' @@ -77,7 +77,7 @@ it('assertion helper', async () => { 35| }); 36| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/11]⎯ FAIL basic.test.ts > nested AssertionError: expected 'nested' to deeply equal 'x' @@ -93,7 +93,7 @@ it('assertion helper', async () => { 47| }); 48| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/11]⎯ FAIL basic.test.ts > multiple soft AssertionError: expected 'first' to deeply equal 'x' @@ -109,7 +109,7 @@ it('assertion helper', async () => { 78| myEqualSoft("second", "y"); 79| }); - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/11]⎯ FAIL basic.test.ts > multiple soft AssertionError: expected 'second' to deeply equal 'y' @@ -125,7 +125,7 @@ it('assertion helper', async () => { 79| }); 80| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/11]⎯ FAIL basic.test.ts > custom error Error: custom error from helper @@ -137,7 +137,7 @@ it('assertion helper', async () => { 88| }); 89| - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/11]⎯ FAIL basic.test.ts > non-helper wrapper AssertionError: expected 'wrapper' to deeply equal 'x' @@ -154,7 +154,45 @@ it('assertion helper', async () => { 94| ❯ basic.test.ts:96:3 - ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/9]⎯ + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/11]⎯ + + FAIL basic.test.ts > helper with context fail + AssertionError: expected 4321 to deeply equal 1234 + + - Expected + + Received + + - 1234 + + 4321 + + ❯ basic.test.ts:124:16 + 122| + 123| test("helper with context fail", () => { + 124| helperObject.assertEqualProp(4321); + | ^ + 125| }); + 126| + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/11]⎯ + + FAIL basic.test.ts > async helper with context fail + AssertionError: expected 4321 to deeply equal 1234 + + - Expected + + Received + + - 1234 + + 4321 + + ❯ basic.test.ts:132:3 + 130| + 131| test("async helper with context fail", async () => { + 132| await helperObject.assertEqualPropAsync(4321); + | ^ + 133| }); + 134| + + ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/11]⎯ " `) @@ -164,9 +202,17 @@ it('assertion helper', async () => { "async": [ "expected 'async' to deeply equal 'x'", ], + "async helper with context fail": [ + "expected 4321 to deeply equal 1234", + ], + "async helper with context pass": "passed", "custom error": [ "custom error from helper", ], + "helper with context fail": [ + "expected 4321 to deeply equal 1234", + ], + "helper with context pass": "passed", "helper with logs": "passed", "multiple soft": [ "expected 'first' to deeply equal 'x'",