diff --git a/packages/vitest/src/node/reporters/base.ts b/packages/vitest/src/node/reporters/base.ts index b7c88409f..d87474bc8 100644 --- a/packages/vitest/src/node/reporters/base.ts +++ b/packages/vitest/src/node/reporters/base.ts @@ -617,6 +617,7 @@ export abstract class BaseReporter implements Reporter { const failedTests = tests.filter(i => i.result?.state === 'fail') const failedTotal = countTestErrors(failedSuites) + countTestErrors(failedTests) + // TODO: error divider should take into account merged errors for counting let current = 1 const errorDivider = () => this.error(`${c.red(c.dim(divider(`[${current++}/${failedTotal}]`, undefined, 1)))}\n`) @@ -677,7 +678,7 @@ export abstract class BaseReporter implements Reporter { if (error?.stack) { previous = errorsQueue.find((i) => { - if (i[0]?.stack !== error.stack) { + if (i[0]?.stack !== error.stack || i[0]?.diff !== error.diff) { return false } diff --git a/test/reporters/fixtures/merge-errors/basic.test.ts b/test/reporters/fixtures/merge-errors/basic.test.ts new file mode 100644 index 000000000..52b08fd3a --- /dev/null +++ b/test/reporters/fixtures/merge-errors/basic.test.ts @@ -0,0 +1,25 @@ +import { expect, test } from "vitest"; + +// not merged +test.for([1, 2])("test-a %$", (n) => { + expect(n).toBe(0); +}); + +// merged +test.for([1, 2])("test-b %$", (n) => { + expect(1).toBe(0); +}); + +// not merged +test.each([ + { + actual: ["a".repeat(50)], + expected: ["b".repeat(50)], + }, + { + actual: ["c".repeat(50)], + expected: ["d".repeat(50)], + }, +])("test-c %$", async ({ actual, expected }) => { + expect(actual).toEqual(expect.arrayContaining(expected)); +}); diff --git a/test/reporters/tests/__snapshots__/default.test.ts.snap b/test/reporters/tests/__snapshots__/default.test.ts.snap new file mode 100644 index 000000000..8dc9e6eae --- /dev/null +++ b/test/reporters/tests/__snapshots__/default.test.ts.snap @@ -0,0 +1,110 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`default reporter > merge identical errors 1`] = ` +" +⎯⎯⎯⎯⎯⎯⎯ Failed Tests 6 ⎯⎯⎯⎯⎯⎯⎯ + + FAIL basic.test.ts > test-a 1 +AssertionError: expected 1 to be +0 // Object.is equality + +- Expected ++ Received + +- 0 ++ 1 + + ❯ basic.test.ts:5:13 + 3| // not merged + 4| test.for([1, 2])("test-a %$", (n) => { + 5| expect(n).toBe(0); + | ^ + 6| }); + 7| + +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/6]⎯ + + FAIL basic.test.ts > test-a 2 +AssertionError: expected 2 to be +0 // Object.is equality + +- Expected ++ Received + +- 0 ++ 2 + + ❯ basic.test.ts:5:13 + 3| // not merged + 4| test.for([1, 2])("test-a %$", (n) => { + 5| expect(n).toBe(0); + | ^ + 6| }); + 7| + +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/6]⎯ + + FAIL basic.test.ts > test-b 1 + FAIL basic.test.ts > test-b 2 +AssertionError: expected 1 to be +0 // Object.is equality + +- Expected ++ Received + +- 0 ++ 1 + + ❯ basic.test.ts:10:13 + 8| // merged + 9| test.for([1, 2])("test-b %$", (n) => { + 10| expect(1).toBe(0); + | ^ + 11| }); + 12| + +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/6]⎯ + + FAIL basic.test.ts > test-c 1 +AssertionError: expected [ Array(1) ] to deeply equal ArrayContaining{…} + +- Expected ++ Received + +- ArrayContaining [ +- "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", ++ [ ++ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + ] + + ❯ basic.test.ts:24:18 + 22| }, + 23| ])("test-c %$", async ({ actual, expected }) => { + 24| expect(actual).toEqual(expect.arrayContaining(expected)); + | ^ + 25| }); + 26| + +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/6]⎯ + + FAIL basic.test.ts > test-c 2 +AssertionError: expected [ Array(1) ] to deeply equal ArrayContaining{…} + +- Expected ++ Received + +- ArrayContaining [ +- "dddddddddddddddddddddddddddddddddddddddddddddddddd", ++ [ ++ "cccccccccccccccccccccccccccccccccccccccccccccccccc", + ] + + ❯ basic.test.ts:24:18 + 22| }, + 23| ])("test-c %$", async ({ actual, expected }) => { + 24| expect(actual).toEqual(expect.arrayContaining(expected)); + | ^ + 25| }); + 26| + +⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/6]⎯ + +" +`; diff --git a/test/reporters/tests/default.test.ts b/test/reporters/tests/default.test.ts index b75c85a27..89f365f7e 100644 --- a/test/reporters/tests/default.test.ts +++ b/test/reporters/tests/default.test.ts @@ -290,4 +290,13 @@ describe('default reporter', async () => { expect(stderr).toMatch('FAIL > { name: fails, meta: Failing test added this } (Custom getFullName here') }) + + test('merge identical errors', async () => { + const { stderr } = await runVitest({ + root: 'fixtures/merge-errors', + reporters: [['default', { isTTY: true, summary: false }]], + config: false, + }) + expect(stderr).toMatchSnapshot() + }) }, 120000)