From 3d7a096680078854b06c213403d063128386ab1f Mon Sep 17 00:00:00 2001 From: Tom Mrazauskas Date: Tue, 24 Jan 2023 17:19:09 +0200 Subject: [PATCH 1/9] chore: fix PR number in changelog (#13807) --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73ecc5cc467b..933aa3a6d3a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,9 @@ - `[jest-config, jest-worker]` Use `os.availableParallelism` if available to calculate number of workers to spawn ([#13738](https://github.com/facebook/jest/pull/13738)) - `[@jest/globals, jest-mock]` Add `jest.replaceProperty()` that replaces property value ([#13496](https://github.com/facebook/jest/pull/13496)) - `[jest-haste-map]` ignore Sapling vcs directories (`.sl/`) ([#13674](https://github.com/facebook/jest/pull/13674)) -- `[jest-resolve]` Support subpath imports ([#13705](https://github.com/facebook/jest/pull/13705), [#13723](https://github.com/facebook/jest/pull/13723)), [#13777](https://github.com/facebook/jest/pull/13777)) +- `[jest-resolve]` Support subpath imports ([#13705](https://github.com/facebook/jest/pull/13705), [#13723](https://github.com/facebook/jest/pull/13723), [#13777](https://github.com/facebook/jest/pull/13777)) - `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#13680](https://github.com/facebook/jest/pull/13680)) -- `[jest-runtime]` Add `jest.isEnvironmentTornDown` function ([#13698](https://github.com/facebook/jest/pull/13698)) +- `[jest-runtime]` Add `jest.isEnvironmentTornDown` function ([#13741](https://github.com/facebook/jest/pull/13741)) - `[jest-test-result]` Added `skipped` and `focused` status to `FormattedTestResult` ([#13700](https://github.com/facebook/jest/pull/13700)) - `[jest-transform]` Support for asynchronous `createTransformer` ([#13762](https://github.com/facebook/jest/pull/13762)) From 9fa2a463a0d5b1a7763ef4a28004db082b8bcf6e Mon Sep 17 00:00:00 2001 From: Josh Kelley Date: Wed, 25 Jan 2023 03:58:01 -0500 Subject: [PATCH 2/9] Include symbol keys when diffing objects (#13810) --- CHANGELOG.md | 2 ++ packages/expect-utils/src/utils.ts | 15 +++++++++++++-- .../__tests__/__snapshots__/matchers.test.js.snap | 4 ++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 933aa3a6d3a6..d874dbd4acee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Fixes +- `[@jest/expect-utils]` `toMatchObject` diffs should include `Symbol` properties ([#13810](https://github.com/facebook/jest/pull/13810)) + ### Chore & Maintenance ### Performance diff --git a/packages/expect-utils/src/utils.ts b/packages/expect-utils/src/utils.ts index 32a403ba4874..0c1cc7b243fe 100644 --- a/packages/expect-utils/src/utils.ts +++ b/packages/expect-utils/src/utils.ts @@ -43,6 +43,17 @@ const hasPropertyInObject = (object: object, key: string | symbol): boolean => { ); }; +// Retrieves an object's keys for evaluation by getObjectSubset. This evaluates +// the prototype chain for string keys but not for symbols. (Otherwise, it +// could find values such as a Set or Map's Symbol.toStringTag, with unexpected +// results.) +// +// Compare with subsetEquality's use of Reflect.ownKeys. +const getObjectKeys = (object: object) => [ + ...Object.keys(object), + ...Object.getOwnPropertySymbols(object), +]; + export const getPath = ( object: Record, propertyPath: string | Array, @@ -131,7 +142,7 @@ export const getObjectSubset = ( const trimmed: any = {}; seenReferences.set(object, trimmed); - Object.keys(object) + getObjectKeys(object) .filter(key => hasPropertyInObject(subset, key)) .forEach(key => { trimmed[key] = seenReferences.has(object[key]) @@ -144,7 +155,7 @@ export const getObjectSubset = ( ); }); - if (Object.keys(trimmed).length > 0) { + if (getObjectKeys(trimmed).length > 0) { return trimmed; } } diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index f02029f00d96..31c26a85f106 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -4140,13 +4140,13 @@ exports[`toMatchObject() {pass: false} expect({"a": "a", "c": "d"}).toMatchObjec exports[`toMatchObject() {pass: false} expect({"a": "b", "c": "d", Symbol(jest): "jest"}).toMatchObject({"a": "c", Symbol(jest): Any}) 1`] = ` expect(received).toMatchObject(expected) -- Expected - 2 +- Expected - 1 + Received + 1 Object { - "a": "c", -- Symbol(jest): Any, + "a": "b", + Symbol(jest): Any, } `; From be021fa8b722f1d367833e8f48bbb08e6e3dd687 Mon Sep 17 00:00:00 2001 From: Jesse van Assen Date: Wed, 25 Jan 2023 21:35:54 +0100 Subject: [PATCH 3/9] feat(jest-core): Add newline after Json output (#13817) --- CHANGELOG.md | 2 ++ e2e/__tests__/jsonReporter.test.ts | 8 +++++++- e2e/runJest.ts | 2 ++ packages/jest-core/src/runJest.ts | 9 +++++++-- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d874dbd4acee..ca3b22b37435 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ### Features +- `[jest-core]` Add newlines to JSON output ([#13817](https://github.com/facebook/jest/pull/13817)) + ### Fixes - `[@jest/expect-utils]` `toMatchObject` diffs should include `Symbol` properties ([#13810](https://github.com/facebook/jest/pull/13810)) diff --git a/e2e/__tests__/jsonReporter.test.ts b/e2e/__tests__/jsonReporter.test.ts index 93132ac5e8a7..df2dba4830a1 100644 --- a/e2e/__tests__/jsonReporter.test.ts +++ b/e2e/__tests__/jsonReporter.test.ts @@ -28,6 +28,8 @@ describe('JSON Reporter', () => { runJest('json-reporter', ['--json', `--outputFile=${outputFileName}`]); const testOutput = fs.readFileSync(outputFilePath, 'utf8'); + expect(testOutput.endsWith('\n')).toBe(true); + try { jsonResult = JSON.parse(testOutput); } catch (err: any) { @@ -71,12 +73,16 @@ describe('JSON Reporter', () => { }); it('outputs coverage report', () => { - const result = runJest('json-reporter', ['--json']); + const result = runJest('json-reporter', ['--json'], { + keepTrailingNewline: true, + }); let jsonResult: FormattedTestResults; expect(result.stderr).toMatch(/1 failed, 1 skipped, 2 passed/); expect(result.exitCode).toBe(1); + expect(result.stdout.endsWith('\n')).toBe(true); + try { jsonResult = JSON.parse(result.stdout); } catch (err: any) { diff --git a/e2e/runJest.ts b/e2e/runJest.ts index b5680c6c0d97..aefa390bc93e 100644 --- a/e2e/runJest.ts +++ b/e2e/runJest.ts @@ -20,6 +20,7 @@ import {normalizeIcons} from './Utils'; const JEST_PATH = path.resolve(__dirname, '../packages/jest-cli/bin/jest.js'); type RunJestOptions = { + keepTrailingNewline?: boolean; // keep final newline in output from stdout and stderr nodeOptions?: string; nodePath?: string; skipPkgJsonCheck?: boolean; // don't complain if can't find package.json @@ -97,6 +98,7 @@ function spawnJest( cwd: dir, env, reject: false, + stripFinalNewline: !options.keepTrailingNewline, timeout: options.timeout || 0, }; diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index 5f0d74cb25d1..9aa77a4346ec 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -106,12 +106,17 @@ const processResults = async ( const cwd = tryRealpath(process.cwd()); const filePath = path.resolve(cwd, outputFile); - fs.writeFileSync(filePath, JSON.stringify(formatTestResults(runResults))); + fs.writeFileSync( + filePath, + `${JSON.stringify(formatTestResults(runResults))}\n`, + ); outputStream.write( `Test results written to: ${path.relative(cwd, filePath)}\n`, ); } else { - process.stdout.write(JSON.stringify(formatTestResults(runResults))); + process.stdout.write( + `${JSON.stringify(formatTestResults(runResults))}\n`, + ); } } From c78905c31d4e50f1808f6d53f5f4f6c617be27eb Mon Sep 17 00:00:00 2001 From: Ming Ye Date: Thu, 26 Jan 2023 22:29:47 +0800 Subject: [PATCH 4/9] Implement `numPassingAsserts` of testCaseResult (#13795) --- CHANGELOG.md | 1 + .../customReportersOnCircus.test.ts.snap | 11 +++++ e2e/__tests__/customReportersOnCircus.test.ts | 42 +++++++++++++++++++ .../reporters/AssertionCountsReporter.js | 29 +++++++++++++ packages/expect/__typetests__/expect.test.ts | 1 + .../src/__tests__/assertionCounts.test.ts | 32 ++++++++++++++ .../src/extractExpectedAssertionsErrors.ts | 1 + packages/expect/src/index.ts | 2 + packages/expect/src/jestMatchersObject.ts | 1 + packages/expect/src/types.ts | 1 + .../jestAdapterInit.ts | 3 +- packages/jest-circus/src/utils.ts | 4 +- .../jest-types/__typetests__/expect.test.ts | 1 + packages/jest-types/src/Circus.ts | 2 + 14 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 e2e/__tests__/__snapshots__/customReportersOnCircus.test.ts.snap create mode 100644 e2e/__tests__/customReportersOnCircus.test.ts create mode 100644 e2e/custom-reporters/reporters/AssertionCountsReporter.js diff --git a/CHANGELOG.md b/CHANGELOG.md index ca3b22b37435..fc857b12fcd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Features +- `[expect, jest-circus, @jest/types]` Implement `numPassingAsserts` of testResults to track the number of passing asserts in a test ([#13795](https://github.com/facebook/jest/pull/13795)) - `[jest-core]` Add newlines to JSON output ([#13817](https://github.com/facebook/jest/pull/13817)) ### Fixes diff --git a/e2e/__tests__/__snapshots__/customReportersOnCircus.test.ts.snap b/e2e/__tests__/__snapshots__/customReportersOnCircus.test.ts.snap new file mode 100644 index 000000000000..0867a8829991 --- /dev/null +++ b/e2e/__tests__/__snapshots__/customReportersOnCircus.test.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Custom Reporters Integration on jest-circus valid failing assertion counts for adding reporters 1`] = ` +"onTestCaseResult: adds fail, status: failed, numExpectations: 0 +onTestFileResult testCaseResult 0: adds fail, status: failed, numExpectations: 0" +`; + +exports[`Custom Reporters Integration on jest-circus valid passing assertion counts for adding reporters 1`] = ` +"onTestCaseResult: adds ok, status: passed, numExpectations: 3 +onTestFileResult testCaseResult 0: adds ok, status: passed, numExpectations: 3" +`; diff --git a/e2e/__tests__/customReportersOnCircus.test.ts b/e2e/__tests__/customReportersOnCircus.test.ts new file mode 100644 index 000000000000..c30483085a14 --- /dev/null +++ b/e2e/__tests__/customReportersOnCircus.test.ts @@ -0,0 +1,42 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import {skipSuiteOnJasmine} from '@jest/test-utils'; +import runJest from '../runJest'; + +skipSuiteOnJasmine(); + +describe('Custom Reporters Integration on jest-circus', () => { + test('valid passing assertion counts for adding reporters', () => { + const {stdout} = runJest('custom-reporters', [ + '--config', + JSON.stringify({ + reporters: [ + 'default', + '/reporters/AssertionCountsReporter.js', + ], + }), + 'add.test.js', + ]); + + expect(stdout).toMatchSnapshot(); + }); + + test('valid failing assertion counts for adding reporters', () => { + const {stdout} = runJest('custom-reporters', [ + '--config', + JSON.stringify({ + reporters: [ + 'default', + '/reporters/AssertionCountsReporter.js', + ], + }), + 'addFail.test.js', + ]); + + expect(stdout).toMatchSnapshot(); + }); +}); diff --git a/e2e/custom-reporters/reporters/AssertionCountsReporter.js b/e2e/custom-reporters/reporters/AssertionCountsReporter.js new file mode 100644 index 000000000000..f5c5ac42d2c1 --- /dev/null +++ b/e2e/custom-reporters/reporters/AssertionCountsReporter.js @@ -0,0 +1,29 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +class AssertionCountsReporter { + onTestFileResult(test, testResult, aggregatedResult) { + testResult.testResults.forEach((testCaseResult, index) => { + console.log( + `onTestFileResult testCaseResult ${index}: ${testCaseResult.title}, ` + + `status: ${testCaseResult.status}, ` + + `numExpectations: ${testCaseResult.numPassingAsserts}`, + ); + }); + } + onTestCaseResult(test, testCaseResult) { + console.log( + `onTestCaseResult: ${testCaseResult.title}, ` + + `status: ${testCaseResult.status}, ` + + `numExpectations: ${testCaseResult.numPassingAsserts}`, + ); + } +} + +module.exports = AssertionCountsReporter; diff --git a/packages/expect/__typetests__/expect.test.ts b/packages/expect/__typetests__/expect.test.ts index a34f1c28f4ee..b9e32400f54f 100644 --- a/packages/expect/__typetests__/expect.test.ts +++ b/packages/expect/__typetests__/expect.test.ts @@ -77,6 +77,7 @@ expectType( expectType(this.isExpectingAssertions); expectType(this.isExpectingAssertionsError); expectType(this.isNot); + expectType(this.numPassingAsserts); expectType(this.promise); expectType>(this.suppressedErrors); expectType(this.testPath); diff --git a/packages/expect/src/__tests__/assertionCounts.test.ts b/packages/expect/src/__tests__/assertionCounts.test.ts index 0e45883363b3..f3cdfeb1bf18 100644 --- a/packages/expect/src/__tests__/assertionCounts.test.ts +++ b/packages/expect/src/__tests__/assertionCounts.test.ts @@ -44,3 +44,35 @@ describe('.hasAssertions()', () => { it('hasAssertions not leaking to global state', () => {}); }); + +describe('numPassingAsserts', () => { + it('verify the default value of numPassingAsserts', () => { + const {numPassingAsserts} = jestExpect.getState(); + expect(numPassingAsserts).toBe(0); + }); + + it('verify the resetting of numPassingAsserts after a test', () => { + expect('a').toBe('a'); + expect('a').toBe('a'); + // reset state + jestExpect.extractExpectedAssertionsErrors(); + const {numPassingAsserts} = jestExpect.getState(); + expect(numPassingAsserts).toBe(0); + }); + + it('verify the correctness of numPassingAsserts count for passing test', () => { + expect('a').toBe('a'); + expect('a').toBe('a'); + const {numPassingAsserts} = jestExpect.getState(); + expect(numPassingAsserts).toBe(2); + }); + + it('verify the correctness of numPassingAsserts count for failing test', () => { + expect('a').toBe('a'); + try { + expect('a').toBe('b'); + } catch (error) {} + const {numPassingAsserts} = jestExpect.getState(); + expect(numPassingAsserts).toBe(1); + }); +}); diff --git a/packages/expect/src/extractExpectedAssertionsErrors.ts b/packages/expect/src/extractExpectedAssertionsErrors.ts index d56fb2417f26..9af24602d50a 100644 --- a/packages/expect/src/extractExpectedAssertionsErrors.ts +++ b/packages/expect/src/extractExpectedAssertionsErrors.ts @@ -20,6 +20,7 @@ const resetAssertionsLocalState = () => { assertionCalls: 0, expectedAssertionsNumber: null, isExpectingAssertions: false, + numPassingAsserts: 0, }); }; diff --git a/packages/expect/src/index.ts b/packages/expect/src/index.ts index 88b913e8f181..7c526815d23b 100644 --- a/packages/expect/src/index.ts +++ b/packages/expect/src/index.ts @@ -337,6 +337,8 @@ const makeThrowingMatcher = ( } else { getState().suppressedErrors.push(error); } + } else { + getState().numPassingAsserts++; } }; diff --git a/packages/expect/src/jestMatchersObject.ts b/packages/expect/src/jestMatchersObject.ts index 2cb600be6772..9272e4feed9a 100644 --- a/packages/expect/src/jestMatchersObject.ts +++ b/packages/expect/src/jestMatchersObject.ts @@ -29,6 +29,7 @@ if (!Object.prototype.hasOwnProperty.call(globalThis, JEST_MATCHERS_OBJECT)) { assertionCalls: 0, expectedAssertionsNumber: null, isExpectingAssertions: false, + numPassingAsserts: 0, suppressedErrors: [], // errors that are not thrown immediately. }; Object.defineProperty(globalThis, JEST_MATCHERS_OBJECT, { diff --git a/packages/expect/src/types.ts b/packages/expect/src/types.ts index 2f449b124d94..f3687b5597cb 100644 --- a/packages/expect/src/types.ts +++ b/packages/expect/src/types.ts @@ -65,6 +65,7 @@ export interface MatcherState { isExpectingAssertions: boolean; isExpectingAssertionsError?: Error; isNot?: boolean; + numPassingAsserts: number; promise?: string; suppressedErrors: Array; testPath?: string; diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts index 4556c55185ae..4108fe133547 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -178,7 +178,7 @@ export const runAndTransformResultsToJestFormat = async ({ : ancestorTitles.join(' '), invocations: testResult.invocations, location: testResult.location, - numPassingAsserts: 0, + numPassingAsserts: testResult.numPassingAsserts, retryReasons: testResult.retryReasons, status, title: testResult.testPath[testResult.testPath.length - 1], @@ -238,6 +238,7 @@ const eventHandler = async (event: Circus.Event) => { break; } case 'test_done': { + event.test.numPassingAsserts = jestExpect.getState().numPassingAsserts; _addSuppressedErrors(event.test); _addExpectedAssertionErrors(event.test); break; diff --git a/packages/jest-circus/src/utils.ts b/packages/jest-circus/src/utils.ts index 7eeb2dfb2f3a..d45bf21e91f5 100644 --- a/packages/jest-circus/src/utils.ts +++ b/packages/jest-circus/src/utils.ts @@ -78,6 +78,7 @@ export const makeTest = ( invocations: 0, mode, name: convertDescriptorToString(name), + numPassingAsserts: 0, parent, retryReasons: [], seenDone: false, @@ -363,6 +364,7 @@ export const makeSingleTestResult = ( errorsDetailed, invocations: test.invocations, location, + numPassingAsserts: test.numPassingAsserts, retryReasons: test.retryReasons.map(_getError).map(getErrorStack), status, testPath: Array.from(testPath), @@ -484,7 +486,7 @@ export const parseSingleTestResult = ( : ancestorTitles.join(' '), invocations: testResult.invocations, location: testResult.location, - numPassingAsserts: 0, + numPassingAsserts: testResult.numPassingAsserts, retryReasons: Array.from(testResult.retryReasons), status, title: testResult.testPath[testResult.testPath.length - 1], diff --git a/packages/jest-types/__typetests__/expect.test.ts b/packages/jest-types/__typetests__/expect.test.ts index 79b68993379b..e1178fc54b74 100644 --- a/packages/jest-types/__typetests__/expect.test.ts +++ b/packages/jest-types/__typetests__/expect.test.ts @@ -446,6 +446,7 @@ expectType( expectType(this.isExpectingAssertions); expectType(this.isExpectingAssertionsError); expectType(this.isNot); + expectType(this.numPassingAsserts); expectType(this.promise); expectType>(this.suppressedErrors); expectType(this.testPath); diff --git a/packages/jest-types/src/Circus.ts b/packages/jest-types/src/Circus.ts index 7ed5023d6caf..c94c74a20e70 100644 --- a/packages/jest-types/src/Circus.ts +++ b/packages/jest-types/src/Circus.ts @@ -185,6 +185,7 @@ export type TestResult = { invocations: number; status: TestStatus; location?: {column: number; line: number} | null; + numPassingAsserts: number; retryReasons: Array; testPath: Array; }; @@ -245,6 +246,7 @@ export type TestEntry = { mode: TestMode; concurrent: boolean; name: TestName; + numPassingAsserts: number; parent: DescribeBlock; startedAt?: number | null; duration?: number | null; From fbf0fa89905da217bdcc81c494634d73b8575de9 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 26 Jan 2023 15:30:06 +0100 Subject: [PATCH 5/9] fix(runtime): handle missing `replaceProperty` (#13823) --- CHANGELOG.md | 1 + packages/jest-runtime/src/index.ts | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc857b12fcd7..eccb30f33648 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixes - `[@jest/expect-utils]` `toMatchObject` diffs should include `Symbol` properties ([#13810](https://github.com/facebook/jest/pull/13810)) +- `[jest-runtime]` Handle missing `replaceProperty` ([#13823](https://github.com/facebook/jest/pull/13823)) ### Chore & Maintenance diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index ae0f8bde2ca9..f050d0d01e58 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2319,9 +2319,14 @@ export default class Runtime { 'Your test environment does not support `mocked`, please update it.', ); }); - const replaceProperty = this._moduleMocker.replaceProperty.bind( - this._moduleMocker, - ); + const replaceProperty = + typeof this._moduleMocker.replaceProperty === 'function' + ? this._moduleMocker.replaceProperty.bind(this._moduleMocker) + : () => { + throw new Error( + 'Your test environment does not support `jest.replaceProperty` - please ensure its Jest dependencies are updated to version 29.4 or later', + ); + }; const setTimeout = (timeout: number) => { this._environment.global[testTimeoutSymbol] = timeout; From 88841055e3a1a76601aa617c9f56c52a34f71df7 Mon Sep 17 00:00:00 2001 From: Tom Mrazauskas Date: Thu, 26 Jan 2023 16:38:20 +0200 Subject: [PATCH 6/9] fix(@jest/types): add partial support for `done` callbacks in typings of `each` (#13756) --- CHANGELOG.md | 1 + packages/babel-jest/src/__tests__/index.ts | 30 +++------------ .../src/__tests__/hooksError.test.ts | 11 +----- .../jest-types/__typetests__/each.test.ts | 38 ++++++++++++++----- packages/jest-types/src/Global.ts | 8 ++-- 5 files changed, 40 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eccb30f33648..92ba35679346 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - `[@jest/expect-utils]` `toMatchObject` diffs should include `Symbol` properties ([#13810](https://github.com/facebook/jest/pull/13810)) - `[jest-runtime]` Handle missing `replaceProperty` ([#13823](https://github.com/facebook/jest/pull/13823)) +- `[@jest/types]` Add partial support for `done` callbacks in typings of `each` ([#13756](https://github.com/facebook/jest/pull/13756)) ### Chore & Maintenance diff --git a/packages/babel-jest/src/__tests__/index.ts b/packages/babel-jest/src/__tests__/index.ts index e0bda219a20e..189d6609a7cc 100644 --- a/packages/babel-jest/src/__tests__/index.ts +++ b/packages/babel-jest/src/__tests__/index.ts @@ -107,38 +107,20 @@ test('Returns source string with inline maps when no transformOptions is passed describe('caller option correctly merges from defaults and options', () => { test.each([ [ - { - supportsDynamicImport: true, - supportsStaticESM: true, - }, - { - supportsDynamicImport: true, - supportsStaticESM: true, - }, + {supportsDynamicImport: true, supportsStaticESM: true}, + {supportsDynamicImport: true, supportsStaticESM: true}, ], [ - { - supportsDynamicImport: false, - supportsStaticESM: false, - }, - { - supportsDynamicImport: false, - supportsStaticESM: false, - }, + {supportsDynamicImport: false, supportsStaticESM: false}, + {supportsDynamicImport: false, supportsStaticESM: false}, ], [ {supportsStaticESM: false}, - { - supportsDynamicImport: false, - supportsStaticESM: false, - }, + {supportsDynamicImport: false, supportsStaticESM: false}, ], [ {supportsDynamicImport: true}, - { - supportsDynamicImport: true, - supportsStaticESM: false, - }, + {supportsDynamicImport: true, supportsStaticESM: false}, ], ])('%j -> %j', (input, output) => { defaultBabelJestTransformer.process(sourceString, 'dummy_path.js', { diff --git a/packages/jest-circus/src/__tests__/hooksError.test.ts b/packages/jest-circus/src/__tests__/hooksError.test.ts index a7a08414d43e..08c135ffe03f 100644 --- a/packages/jest-circus/src/__tests__/hooksError.test.ts +++ b/packages/jest-circus/src/__tests__/hooksError.test.ts @@ -10,16 +10,7 @@ import circus from '../'; describe.each(['beforeEach', 'beforeAll', 'afterEach', 'afterAll'] as const)( '%s hooks error throwing', fn => { - test.each([ - ['String'], - [1], - [[]], - [{}], - [Symbol('hello')], - [true], - [null], - [undefined], - ])( + test.each(['String', 1, [], {}, Symbol('hello'), true, null, undefined])( `${fn} throws an error when %p is provided as a first argument to it`, el => { expect(() => { diff --git a/packages/jest-types/__typetests__/each.test.ts b/packages/jest-types/__typetests__/each.test.ts index 3c9212ca5ed4..cc3965cd3e96 100644 --- a/packages/jest-types/__typetests__/each.test.ts +++ b/packages/jest-types/__typetests__/each.test.ts @@ -28,19 +28,27 @@ const objectTable = [ // test.each expectType( - test.each(list)('some test', a => { + test.each(list)('some test', (a, done) => { expectType(a); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( - test.each(list)('some test', a => { - expectType(a); - }), + test.each(list)( + 'some test', + a => { + expectType(a); + }, + 1000, + ), ); expectType( - test.each(tupleList)('some test', b => { + test.each(tupleList)('some test', (b, done) => { expectType<'one' | 'two' | 'three'>(b); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( @@ -54,8 +62,10 @@ expectType( ); expectType( - test.each([3, 4, 'seven'])('some test', c => { + test.each([3, 4, 'seven'])('some test', (c, done) => { expectType(c); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( @@ -134,11 +144,13 @@ expectType( ); expectType( - test.each(objectTable)('some test', ({a, b, expected, extra}) => { + test.each(objectTable)('some test', ({a, b, expected, extra}, done) => { expectType(a); expectType(b); expectType(expected); expectType(extra); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( @@ -148,11 +160,13 @@ expectType( {a: 5, b: 6, expected: 'eleven'}, ])( 'some test', - ({a, b, expected, extra}) => { + ({a, b, expected, extra}, done) => { expectType(a); expectType(b); expectType(expected); expectType(extra); + + expectType<(reason?: string | Error) => void>(done); }, 1000, ), @@ -164,10 +178,12 @@ expectType( ${1} | ${1} | ${2} ${1} | ${2} | ${3} ${2} | ${1} | ${3} - `('some test', ({a, b, expected}) => { + `('some test', ({a, b, expected}, done) => { expectType(a); expectType(b); expectType(expected); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( @@ -185,9 +201,11 @@ expectType( item | expected ${'a'} | ${true} ${'b'} | ${false} - `('some test', ({item, expected}) => { + `('some test', ({item, expected}, done) => { expectType(item); expectType(expected); + + expectType<(reason?: string | Error) => void>(done); }), ); expectType( diff --git a/packages/jest-types/src/Global.ts b/packages/jest-types/src/Global.ts index 6a1bbecb235a..87b9449be23b 100644 --- a/packages/jest-types/src/Global.ts +++ b/packages/jest-types/src/Global.ts @@ -59,7 +59,7 @@ interface Each { // when the table is an array of object literals >(table: ReadonlyArray): ( name: string | NameLike, - fn: (arg: T) => ReturnType, + fn: (arg: T, done: DoneFn) => ReturnType, timeout?: number, ) => void; @@ -80,14 +80,14 @@ interface Each { // when the table is a tuple or array (table: ReadonlyArray): ( name: string | NameLike, - fn: (arg: T) => ReturnType, + fn: (arg: T, done: DoneFn) => ReturnType, timeout?: number, ) => void; // when the table is a template literal (strings: TemplateStringsArray, ...expressions: Array): ( name: string | NameLike, - fn: (arg: Record) => ReturnType, + fn: (arg: Record, done: DoneFn) => ReturnType, timeout?: number, ) => void; @@ -97,7 +97,7 @@ interface Each { ...expressions: Array ): ( name: string | NameLike, - fn: (arg: T) => ReturnType, + fn: (arg: T, done: DoneFn) => ReturnType, timeout?: number, ) => void; } From 6ab67bf126d9da16e93edb40d67161b40a6710fd Mon Sep 17 00:00:00 2001 From: Matteo Dell'Acqua <82184604+MatteoH2O1999@users.noreply.github.com> Date: Thu, 26 Jan 2023 16:00:55 +0100 Subject: [PATCH 7/9] Add new default reporter for github actions (#13626) --- CHANGELOG.md | 1 + docs/Configuration.md | 6 +- packages/jest-core/src/TestScheduler.ts | 5 +- .../src/GitHubActionsReporter.ts | 341 +++++++++- .../__tests__/GitHubActionsReporter.test.ts | 621 +++++++++++++++--- .../GitHubActionsReporter.test.ts.snap | 126 +++- .../version-29.4/Configuration.md | 6 +- 7 files changed, 991 insertions(+), 115 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ba35679346..e334667cf3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - `[expect, jest-circus, @jest/types]` Implement `numPassingAsserts` of testResults to track the number of passing asserts in a test ([#13795](https://github.com/facebook/jest/pull/13795)) - `[jest-core]` Add newlines to JSON output ([#13817](https://github.com/facebook/jest/pull/13817)) +- `[@jest/reporters]` New functionality for Github Actions Reporter: automatic log folding ([#13626](https://github.com/facebook/jest/pull/13626)) ### Fixes diff --git a/docs/Configuration.md b/docs/Configuration.md index 0a071c26c713..eebddd813855 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -1278,12 +1278,12 @@ export default config; #### GitHub Actions Reporter -If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages: +If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages and (if used with `'silent: false'`) print logs with github group features for easy navigation. Note that `'default'` should not be used in this case as `'github-actions'` will handle that already, so remember to also include `'summary'`. If you wish to use it only for annotations simply leave only the reporter without options as the default value of `'silent'` is `'true'`: ```js tab /** @type {import('jest').Config} */ const config = { - reporters: ['default', 'github-actions'], + reporters: [['github-actions', {silent: false}], 'summary'], }; module.exports = config; @@ -1293,7 +1293,7 @@ module.exports = config; import type {Config} from 'jest'; const config: Config = { - reporters: ['default', 'github-actions'], + reporters: [['github-actions', {silent: false}], 'summary'], }; export default config; diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index ad96154c2fbb..38dc47adedd4 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -347,7 +347,10 @@ class TestScheduler { : this.addReporter(new DefaultReporter(this._globalConfig)); break; case 'github-actions': - GITHUB_ACTIONS && this.addReporter(new GitHubActionsReporter()); + GITHUB_ACTIONS && + this.addReporter( + new GitHubActionsReporter(this._globalConfig, options), + ); break; case 'summary': summary = true; diff --git a/packages/jest-reporters/src/GitHubActionsReporter.ts b/packages/jest-reporters/src/GitHubActionsReporter.ts index 7d244d728852..7d439b182111 100644 --- a/packages/jest-reporters/src/GitHubActionsReporter.ts +++ b/packages/jest-reporters/src/GitHubActionsReporter.ts @@ -5,8 +5,15 @@ * LICENSE file in the root directory of this source tree. */ +import chalk = require('chalk'); import stripAnsi = require('strip-ansi'); -import type {Test, TestResult} from '@jest/test-result'; +import type { + AggregatedResult, + AssertionResult, + Test, + TestContext, + TestResult, +} from '@jest/test-result'; import type {Config} from '@jest/types'; import { formatPath, @@ -26,10 +33,68 @@ type AnnotationOptions = { const titleSeparator = ' \u203A '; +type PerformanceInfo = { + end: number; + runtime: number; + slow: boolean; + start: number; +}; + +type ResultTreeLeaf = { + name: string; + passed: boolean; + duration: number; + children: Array; +}; + +type ResultTreeNode = { + name: string; + passed: boolean; + children: Array; +}; + +type ResultTree = { + children: Array; + name: string; + passed: boolean; + performanceInfo: PerformanceInfo; +}; + export default class GitHubActionsReporter extends BaseReporter { static readonly filename = __filename; + private readonly options: {silent: boolean}; + + constructor( + _globalConfig: Config.GlobalConfig, + reporterOptions: {silent?: boolean} = {silent: true}, + ) { + super(); + this.options = { + silent: + typeof reporterOptions.silent === 'boolean' + ? reporterOptions.silent + : true, + }; + } + + override onTestResult( + test: Test, + testResult: TestResult, + aggregatedResults: AggregatedResult, + ): void { + this.generateAnnotations(test, testResult); + if (!this.options.silent) { + this.printFullResult(test.context, testResult); + } + if (this.isLastTestSuite(aggregatedResults)) { + this.printFailedTestLogs(test, aggregatedResults); + } + } - onTestFileResult({context}: Test, {testResults}: TestResult): void { + private generateAnnotations( + {context}: Test, + {testResults}: TestResult, + ): void { testResults.forEach(result => { const title = [...result.ancestorTitles, result.title].join( titleSeparator, @@ -81,4 +146,276 @@ export default class GitHubActionsReporter extends BaseReporter { `\n::${type} file=${file},line=${line},title=${title}::${message}`, ); } + + private isLastTestSuite(results: AggregatedResult): boolean { + const passedTestSuites = results.numPassedTestSuites; + const failedTestSuites = results.numFailedTestSuites; + const totalTestSuites = results.numTotalTestSuites; + const computedTotal = passedTestSuites + failedTestSuites; + if (computedTotal < totalTestSuites) { + return false; + } else if (computedTotal === totalTestSuites) { + return true; + } else { + throw new Error( + `Sum(${computedTotal}) of passed (${passedTestSuites}) and failed (${failedTestSuites}) test suites is greater than the total number of test suites (${totalTestSuites}). Please report the bug at https://github.com/facebook/jest/issues`, + ); + } + } + + private printFullResult(context: TestContext, results: TestResult): void { + const rootDir = context.config.rootDir; + let testDir = results.testFilePath.replace(rootDir, ''); + testDir = testDir.slice(1, testDir.length); + const resultTree = this.getResultTree( + results.testResults, + testDir, + results.perfStats, + ); + this.printResultTree(resultTree); + } + + private arrayEqual(a1: Array, a2: Array): boolean { + if (a1.length !== a2.length) { + return false; + } + for (let index = 0; index < a1.length; index++) { + const element = a1[index]; + if (element !== a2[index]) { + return false; + } + } + return true; + } + + private arrayChild(a1: Array, a2: Array): boolean { + if (a1.length - a2.length !== 1) { + return false; + } + for (let index = 0; index < a2.length; index++) { + const element = a2[index]; + if (element !== a1[index]) { + return false; + } + } + return true; + } + + private getResultTree( + suiteResult: Array, + testPath: string, + suitePerf: PerformanceInfo, + ): ResultTree { + const root: ResultTree = { + children: [], + name: testPath, + passed: true, + performanceInfo: suitePerf, + }; + const branches: Array> = []; + suiteResult.forEach(element => { + if (element.ancestorTitles.length === 0) { + let passed = true; + if (element.status !== 'passed') { + root.passed = false; + passed = false; + } + const duration = element.duration || 1; + root.children.push({ + children: [], + duration, + name: element.title, + passed, + }); + } else { + let alreadyInserted = false; + for (let index = 0; index < branches.length; index++) { + if ( + this.arrayEqual(branches[index], element.ancestorTitles.slice(0, 1)) + ) { + alreadyInserted = true; + break; + } + } + if (!alreadyInserted) { + branches.push(element.ancestorTitles.slice(0, 1)); + } + } + }); + branches.forEach(element => { + const newChild = this.getResultChildren(suiteResult, element); + if (!newChild.passed) { + root.passed = false; + } + root.children.push(newChild); + }); + return root; + } + + private getResultChildren( + suiteResult: Array, + ancestors: Array, + ): ResultTreeNode { + const node: ResultTreeNode = { + children: [], + name: ancestors[ancestors.length - 1], + passed: true, + }; + const branches: Array> = []; + suiteResult.forEach(element => { + let passed = true; + let duration = element.duration; + if (!duration || isNaN(duration)) { + duration = 1; + } + if (this.arrayEqual(element.ancestorTitles, ancestors)) { + if (element.status !== 'passed') { + node.passed = false; + passed = false; + } + node.children.push({ + children: [], + duration, + name: element.title, + passed, + }); + } else if ( + this.arrayChild( + element.ancestorTitles.slice(0, ancestors.length + 1), + ancestors, + ) + ) { + let alreadyInserted = false; + for (let index = 0; index < branches.length; index++) { + if ( + this.arrayEqual( + branches[index], + element.ancestorTitles.slice(0, ancestors.length + 1), + ) + ) { + alreadyInserted = true; + break; + } + } + if (!alreadyInserted) { + branches.push(element.ancestorTitles.slice(0, ancestors.length + 1)); + } + } + }); + branches.forEach(element => { + const newChild = this.getResultChildren(suiteResult, element); + if (!newChild.passed) { + node.passed = false; + } + node.children.push(newChild); + }); + return node; + } + + private printResultTree(resultTree: ResultTree): void { + let perfMs; + if (resultTree.performanceInfo.slow) { + perfMs = ` (${chalk.red.inverse( + `${resultTree.performanceInfo.runtime} ms`, + )})`; + } else { + perfMs = ` (${resultTree.performanceInfo.runtime} ms)`; + } + if (resultTree.passed) { + this.startGroup( + `${chalk.bold.green.inverse('PASS')} ${resultTree.name}${perfMs}`, + ); + resultTree.children.forEach(child => { + this.recursivePrintResultTree(child, true, 1); + }); + this.endGroup(); + } else { + this.log( + ` ${chalk.bold.red.inverse('FAIL')} ${resultTree.name}${perfMs}`, + ); + resultTree.children.forEach(child => { + this.recursivePrintResultTree(child, false, 1); + }); + } + } + + private recursivePrintResultTree( + resultTree: ResultTreeNode | ResultTreeLeaf, + alreadyGrouped: boolean, + depth: number, + ): void { + if (resultTree.children.length === 0) { + if (!('duration' in resultTree)) { + throw new Error('Expected a leaf. Got a node.'); + } + let numberSpaces = depth; + if (!alreadyGrouped) { + numberSpaces++; + } + const spaces = ' '.repeat(numberSpaces); + let resultSymbol; + if (resultTree.passed) { + resultSymbol = chalk.green('\u2713'); + } else { + resultSymbol = chalk.red('\u00D7'); + } + this.log( + `${spaces + resultSymbol} ${resultTree.name} (${ + resultTree.duration + } ms)`, + ); + } else { + if (resultTree.passed) { + if (alreadyGrouped) { + this.log(' '.repeat(depth) + resultTree.name); + resultTree.children.forEach(child => { + this.recursivePrintResultTree(child, true, depth + 1); + }); + } else { + this.startGroup(' '.repeat(depth) + resultTree.name); + resultTree.children.forEach(child => { + this.recursivePrintResultTree(child, true, depth + 1); + }); + this.endGroup(); + } + } else { + this.log(' '.repeat(depth + 1) + resultTree.name); + resultTree.children.forEach(child => { + this.recursivePrintResultTree(child, false, depth + 1); + }); + } + } + } + + private printFailedTestLogs( + context: Test, + testResults: AggregatedResult, + ): boolean { + const rootDir = context.context.config.rootDir; + const results = testResults.testResults; + let written = false; + results.forEach(result => { + let testDir = result.testFilePath; + testDir = testDir.replace(rootDir, ''); + testDir = testDir.slice(1, testDir.length); + if (result.failureMessage) { + if (!written) { + this.log(''); + written = true; + } + this.startGroup(`Errors thrown in ${testDir}`); + this.log(result.failureMessage); + this.endGroup(); + } + }); + return written; + } + + private startGroup(title: string): void { + this.log(`::group::${title}`); + } + + private endGroup(): void { + this.log('::endgroup::'); + } } diff --git a/packages/jest-reporters/src/__tests__/GitHubActionsReporter.test.ts b/packages/jest-reporters/src/__tests__/GitHubActionsReporter.test.ts index 19ced0720956..a78c9aa00db2 100644 --- a/packages/jest-reporters/src/__tests__/GitHubActionsReporter.test.ts +++ b/packages/jest-reporters/src/__tests__/GitHubActionsReporter.test.ts @@ -5,133 +5,550 @@ * LICENSE file in the root directory of this source tree. */ -import type {Test, TestCaseResult, TestResult} from '@jest/test-result'; +import type { + AggregatedResult, + AssertionResult, + Test, + TestCaseResult, + TestResult, +} from '@jest/test-result'; +import type {Config} from '@jest/types'; import GitHubActionsReporter from '../GitHubActionsReporter'; +afterEach(() => { + jest.clearAllMocks(); +}); + const mockedStderrWrite = jest .spyOn(process.stderr, 'write') .mockImplementation(() => true); -afterEach(() => { - jest.clearAllMocks(); -}); +describe('annotations', () => { + const reporter = new GitHubActionsReporter({} as Config.GlobalConfig); + + const testMeta = { + context: {config: {rootDir: '/user/project'}}, + } as Test; + + const expectationsErrorMessage = + 'Error: \x1B[2mexpect(\x1B[22m\x1B[31mreceived\x1B[39m\x1B[2m).\x1B[22mtoBe\x1B[2m(\x1B[22m\x1B[32mexpected\x1B[39m\x1B[2m) // Object.is equality\x1B[22m\n' + + '\n' + + 'Expected: \x1B[32m1\x1B[39m\n' + + 'Received: \x1B[31m10\x1B[39m\n' + + ' at Object.toBe (/user/project/__tests__/example.test.js:20:14)\n' + + ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + + ' at new Promise ()\n' + + ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + + ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + + ' at processTicksAndRejections (node:internal/process/task_queues:95:5)\n' + + ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + + ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + + ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)\n' + + ' at runAndTransformResultsToJestFormat (/user/project/jest/packages/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:135:21)'; + + const referenceErrorMessage = + 'ReferenceError: abc is not defined\n' + + ' at Object.abc (/user/project/__tests__/example.test.js:25:12)\n' + + ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + + ' at new Promise ()\n' + + ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + + ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + + ' at processTicksAndRejections (node:internal/process/task_queues:95:5)\n' + + ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + + ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + + ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:90:9)\n' + + ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)'; + + const retryErrorMessage = + 'Error: \x1B[2mexpect(\x1B[22m\x1B[31mreceived\x1B[39m\x1B[2m).\x1B[22mtoBeFalsy\x1B[2m()\x1B[22m\n' + + '\n' + + 'Received: \x1B[31mtrue\x1B[39m\n' + + ' at Object.toBeFalsy (/user/project/__tests__/example.test.js:19:20)\n' + + ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + + ' at new Promise ()\n' + + ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + + ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + + ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + + ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + + ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:90:9)\n' + + ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)\n' + + ' at runAndTransformResultsToJestFormat (/user/project/jest/packages/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:135:21)'; + + const testCaseResult = { + ancestorTitles: [] as Array, + failureMessages: [expectationsErrorMessage], + title: 'example test', + } as TestCaseResult; + + describe('logs error annotation', () => { + test('when an expectation fails to pass', () => { + reporter['generateAnnotations'](testMeta, { + testResults: [ + { + ...testCaseResult, + failureMessages: [expectationsErrorMessage], + }, + ], + } as TestResult); -const reporter = new GitHubActionsReporter(); - -const testMeta = { - context: {config: {rootDir: '/user/project'}}, -} as Test; - -const expectationsErrorMessage = - 'Error: \x1B[2mexpect(\x1B[22m\x1B[31mreceived\x1B[39m\x1B[2m).\x1B[22mtoBe\x1B[2m(\x1B[22m\x1B[32mexpected\x1B[39m\x1B[2m) // Object.is equality\x1B[22m\n' + - '\n' + - 'Expected: \x1B[32m1\x1B[39m\n' + - 'Received: \x1B[31m10\x1B[39m\n' + - ' at Object.toBe (/user/project/__tests__/example.test.js:20:14)\n' + - ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + - ' at new Promise ()\n' + - ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + - ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + - ' at processTicksAndRejections (node:internal/process/task_queues:95:5)\n' + - ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + - ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + - ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)\n' + - ' at runAndTransformResultsToJestFormat (/user/project/jest/packages/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:135:21)'; - -const referenceErrorMessage = - 'ReferenceError: abc is not defined\n' + - ' at Object.abc (/user/project/__tests__/example.test.js:25:12)\n' + - ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + - ' at new Promise ()\n' + - ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + - ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + - ' at processTicksAndRejections (node:internal/process/task_queues:95:5)\n' + - ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + - ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + - ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:90:9)\n' + - ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)'; - -const retryErrorMessage = - 'Error: \x1B[2mexpect(\x1B[22m\x1B[31mreceived\x1B[39m\x1B[2m).\x1B[22mtoBeFalsy\x1B[2m()\x1B[22m\n' + - '\n' + - 'Received: \x1B[31mtrue\x1B[39m\n' + - ' at Object.toBeFalsy (/user/project/__tests__/example.test.js:19:20)\n' + - ' at Promise.then.completed (/user/project/jest/packages/jest-circus/build/utils.js:333:28)\n' + - ' at new Promise ()\n' + - ' at callAsyncCircusFn (/user/project/jest/packages/jest-circus/build/utils.js:259:10)\n' + - ' at _callCircusTest (/user/project/jest/packages/jest-circus/build/run.js:276:40)\n' + - ' at _runTest (/user/project/jest/packages/jest-circus/build/run.js:208:3)\n' + - ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:96:9)\n' + - ' at _runTestsForDescribeBlock (/user/project/jest/packages/jest-circus/build/run.js:90:9)\n' + - ' at run (/user/project/jest/packages/jest-circus/build/run.js:31:3)\n' + - ' at runAndTransformResultsToJestFormat (/user/project/jest/packages/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:135:21)'; - -const testCaseResult = { - ancestorTitles: [] as Array, - failureMessages: [expectationsErrorMessage], - title: 'example test', -} as TestCaseResult; - -describe('logs error annotation', () => { - test('when an expectation fails to pass', () => { - reporter.onTestFileResult(testMeta, { - testResults: [ + expect(mockedStderrWrite).toHaveBeenCalledTimes(1); + expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); + }); + + test('when a test has reference error', () => { + reporter['generateAnnotations']( + {...testMeta, path: '/user/project/__tests__/example.test.js:25:12'}, { - ...testCaseResult, - failureMessages: [expectationsErrorMessage], - }, - ], - } as TestResult); + testResults: [ + { + ...testCaseResult, + failureMessages: [referenceErrorMessage], + }, + ], + } as TestResult, + ); + + expect(mockedStderrWrite).toHaveBeenCalledTimes(1); + expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); + }); - expect(mockedStderrWrite).toHaveBeenCalledTimes(1); - expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); + test('when test is wrapped in describe block', () => { + reporter['generateAnnotations'](testMeta, { + testResults: [ + { + ...testCaseResult, + ancestorTitles: ['describe'], + }, + ], + } as TestResult); + + expect(mockedStderrWrite).toHaveBeenCalledTimes(1); + expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); + }); }); - test('when a test has reference error', () => { - reporter.onTestFileResult( - {...testMeta, path: '/user/project/__tests__/example.test.js:25:12'}, - { + describe('logs warning annotation before logging errors', () => { + test('when test result includes retry reasons', () => { + reporter['generateAnnotations'](testMeta, { testResults: [ { ...testCaseResult, - failureMessages: [referenceErrorMessage], + failureMessages: [retryErrorMessage], + retryReasons: [retryErrorMessage], }, ], - } as TestResult, - ); + } as TestResult); - expect(mockedStderrWrite).toHaveBeenCalledTimes(1); - expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); + expect(mockedStderrWrite).toHaveBeenCalledTimes(2); + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); }); +}); - test('when test is wrapped in describe block', () => { - reporter.onTestFileResult(testMeta, { - testResults: [ +describe('logs', () => { + test('can be instantiated', () => { + const gha = new GitHubActionsReporter({} as Config.GlobalConfig); + expect(gha).toBeTruthy(); + expect(gha).toBeInstanceOf(GitHubActionsReporter); + }); + + describe('Result tree generation', () => { + test('failed single test without describe', () => { + const testResults = [ { - ...testCaseResult, - ancestorTitles: ['describe'], + ancestorTitles: [], + duration: 10, + status: 'failed', + title: 'test', }, - ], - } as TestResult); + ] as unknown as Array; + const suitePerf = { + end: 30, + runtime: 20, + slow: false, + start: 10, + }; + const expectedResults = { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: false, + }, + ], + name: '/', + passed: false, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); - expect(mockedStderrWrite).toHaveBeenCalledTimes(1); - expect(mockedStderrWrite.mock.calls[0]).toMatchSnapshot(); - }); -}); + const generated = gha['getResultTree'](testResults, '/', suitePerf); + + expect(mockedStderrWrite).not.toHaveBeenCalled(); + expect(generated).toEqual(expectedResults); + }); + + test('passed single test without describe', () => { + const testResults = [ + { + ancestorTitles: [], + duration: 10, + status: 'passed', + title: 'test', + }, + ] as unknown as Array; + const suitePerf = { + end: 30, + runtime: 20, + slow: false, + start: 10, + }; + const expectedResults = { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: true, + }, + ], + name: '/', + passed: true, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + const generated = gha['getResultTree'](testResults, '/', suitePerf); + + expect(mockedStderrWrite).not.toHaveBeenCalled(); + expect(generated).toEqual(expectedResults); + }); + + test('failed single test inside describe', () => { + const testResults = [ + { + ancestorTitles: ['Test describe'], + duration: 10, + status: 'failed', + title: 'test', + }, + ] as unknown as Array; + const suitePerf = { + end: 30, + runtime: 20, + slow: false, + start: 10, + }; + const expectedResults = { + children: [ + { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: false, + }, + ], + name: 'Test describe', + passed: false, + }, + ], + name: '/', + passed: false, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + const generated = gha['getResultTree'](testResults, '/', suitePerf); + + expect(mockedStderrWrite).not.toHaveBeenCalled(); + expect(generated).toEqual(expectedResults); + }); -describe('logs warning annotation before logging errors', () => { - test('when test result includes retry reasons', () => { - reporter.onTestFileResult(testMeta, { - testResults: [ + test('passed single test inside describe', () => { + const testResults = [ { - ...testCaseResult, - failureMessages: [retryErrorMessage], - retryReasons: [retryErrorMessage], + ancestorTitles: ['Test describe'], + duration: 10, + status: 'passed', + title: 'test', }, - ], - } as TestResult); + ] as unknown as Array; + const suitePerf = { + end: 30, + runtime: 20, + slow: false, + start: 10, + }; + const expectedResults = { + children: [ + { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: true, + }, + ], + name: 'Test describe', + passed: true, + }, + ], + name: '/', + passed: true, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + const generated = gha['getResultTree'](testResults, '/', suitePerf); + + expect(mockedStderrWrite).not.toHaveBeenCalled(); + expect(generated).toEqual(expectedResults); + }); + }); + + describe('Result tree output', () => { + test('failed single test without describe', () => { + const generatedTree = { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: false, + }, + ], + name: '/', + passed: false, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + gha['printResultTree'](generatedTree); + + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); + + test('passed single test without describe', () => { + const generatedTree = { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: true, + }, + ], + name: '/', + passed: true, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + gha['printResultTree'](generatedTree); + + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); + + test('failed single test inside describe', () => { + const generatedTree = { + children: [ + { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: false, + }, + ], + name: 'Test describe', + passed: false, + }, + ], + name: '/', + passed: false, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + gha['printResultTree'](generatedTree); + + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); + + test('passed single test inside describe', () => { + const generatedTree = { + children: [ + { + children: [ + { + children: [], + duration: 10, + name: 'test', + passed: true, + }, + ], + name: 'Test describe', + passed: true, + }, + ], + name: '/', + passed: true, + performanceInfo: { + end: 30, + runtime: 20, + slow: false, + start: 10, + }, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + + gha['printResultTree'](generatedTree); + + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); + }); + + describe('Reporter interface', () => { + test('onTestResult not last', () => { + const mockTest = { + context: { + config: { + rootDir: '/testDir', + }, + }, + }; + const mockTestResult = { + perfStats: { + runtime: 20, + slow: false, + }, + testFilePath: '/testDir/test1.js', + testResults: [ + { + ancestorTitles: [], + duration: 10, + status: 'passed', + title: 'test1', + }, + ], + }; + const mockResults = { + numFailedTestSuites: 1, + numPassedTestSuites: 1, + numTotalTestSuites: 3, + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + gha['generateAnnotations'] = jest.fn(); + + gha.onTestResult( + mockTest as Test, + mockTestResult as unknown as TestResult, + mockResults as AggregatedResult, + ); + + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); + + test('onTestResult last', () => { + const mockTest = { + context: { + config: { + rootDir: '/testDir', + }, + }, + }; + const mockTestResult = { + failureMessage: 'Failure message', + perfStats: { + runtime: 20, + slow: false, + }, + testFilePath: '/testDir/test1.js', + testResults: [ + { + ancestorTitles: [], + duration: 10, + status: 'passed', + title: 'test1', + }, + ], + }; + const mockResults = { + numFailedTestSuites: 1, + numPassedTestSuites: 2, + numTotalTestSuites: 3, + testResults: [mockTestResult], + }; + const gha = new GitHubActionsReporter({} as Config.GlobalConfig, { + silent: false, + }); + gha['generateAnnotations'] = jest.fn(); + + gha.onTestResult( + mockTest as Test, + mockTestResult as unknown as TestResult, + mockResults as unknown as AggregatedResult, + ); - expect(mockedStderrWrite).toHaveBeenCalledTimes(2); - expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + expect(mockedStderrWrite.mock.calls).toMatchSnapshot(); + }); }); }); diff --git a/packages/jest-reporters/src/__tests__/__snapshots__/GitHubActionsReporter.test.ts.snap b/packages/jest-reporters/src/__tests__/__snapshots__/GitHubActionsReporter.test.ts.snap index 4201d36f388d..1010136fe994 100644 --- a/packages/jest-reporters/src/__tests__/__snapshots__/GitHubActionsReporter.test.ts.snap +++ b/packages/jest-reporters/src/__tests__/__snapshots__/GitHubActionsReporter.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`logs error annotation when a test has reference error 1`] = ` +exports[`annotations logs error annotation when a test has reference error 1`] = ` Array [ " ::error file=/user/project/__tests__/example.test.js,line=25,title=example test::ReferenceError: abc is not defined%0A%0A at Object.abc (__tests__/example.test.js:25:12) @@ -8,7 +8,7 @@ Array [ ] `; -exports[`logs error annotation when an expectation fails to pass 1`] = ` +exports[`annotations logs error annotation when an expectation fails to pass 1`] = ` Array [ " ::error file=/user/project/__tests__/example.test.js,line=20,title=example test::expect(received).toBe(expected) // Object.is equality%0A%0AExpected: 1%0AReceived: 10%0A%0A at Object.toBe (__tests__/example.test.js:20:14) @@ -16,7 +16,7 @@ Array [ ] `; -exports[`logs error annotation when test is wrapped in describe block 1`] = ` +exports[`annotations logs error annotation when test is wrapped in describe block 1`] = ` Array [ " ::error file=/user/project/__tests__/example.test.js,line=20,title=describe › example test::expect(received).toBe(expected) // Object.is equality%0A%0AExpected: 1%0AReceived: 10%0A%0A at Object.toBe (__tests__/example.test.js:20:14) @@ -24,7 +24,7 @@ Array [ ] `; -exports[`logs warning annotation before logging errors when test result includes retry reasons 1`] = ` +exports[`annotations logs warning annotation before logging errors when test result includes retry reasons 1`] = ` Array [ Array [ " @@ -38,3 +38,121 @@ Array [ ], ] `; + +exports[`logs Reporter interface onTestResult last 1`] = ` +Array [ + Array [ + "::group::PASS test1.js (20 ms) +", + ], + Array [ + " ✓ test1 (10 ms) +", + ], + Array [ + "::endgroup:: +", + ], + Array [ + " +", + ], + Array [ + "::group::Errors thrown in test1.js +", + ], + Array [ + "Failure message +", + ], + Array [ + "::endgroup:: +", + ], +] +`; + +exports[`logs Reporter interface onTestResult not last 1`] = ` +Array [ + Array [ + "::group::PASS test1.js (20 ms) +", + ], + Array [ + " ✓ test1 (10 ms) +", + ], + Array [ + "::endgroup:: +", + ], +] +`; + +exports[`logs Result tree output failed single test inside describe 1`] = ` +Array [ + Array [ + " FAIL / (20 ms) +", + ], + Array [ + " Test describe +", + ], + Array [ + " × test (10 ms) +", + ], +] +`; + +exports[`logs Result tree output failed single test without describe 1`] = ` +Array [ + Array [ + " FAIL / (20 ms) +", + ], + Array [ + " × test (10 ms) +", + ], +] +`; + +exports[`logs Result tree output passed single test inside describe 1`] = ` +Array [ + Array [ + "::group::PASS / (20 ms) +", + ], + Array [ + " Test describe +", + ], + Array [ + " ✓ test (10 ms) +", + ], + Array [ + "::endgroup:: +", + ], +] +`; + +exports[`logs Result tree output passed single test without describe 1`] = ` +Array [ + Array [ + "::group::PASS / (20 ms) +", + ], + Array [ + " ✓ test (10 ms) +", + ], + Array [ + "::endgroup:: +", + ], +] +`; diff --git a/website/versioned_docs/version-29.4/Configuration.md b/website/versioned_docs/version-29.4/Configuration.md index 0a071c26c713..eebddd813855 100644 --- a/website/versioned_docs/version-29.4/Configuration.md +++ b/website/versioned_docs/version-29.4/Configuration.md @@ -1278,12 +1278,12 @@ export default config; #### GitHub Actions Reporter -If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages: +If included in the list, the built-in GitHub Actions Reporter will annotate changed files with test failure messages and (if used with `'silent: false'`) print logs with github group features for easy navigation. Note that `'default'` should not be used in this case as `'github-actions'` will handle that already, so remember to also include `'summary'`. If you wish to use it only for annotations simply leave only the reporter without options as the default value of `'silent'` is `'true'`: ```js tab /** @type {import('jest').Config} */ const config = { - reporters: ['default', 'github-actions'], + reporters: [['github-actions', {silent: false}], 'summary'], }; module.exports = config; @@ -1293,7 +1293,7 @@ module.exports = config; import type {Config} from 'jest'; const config: Config = { - reporters: ['default', 'github-actions'], + reporters: [['github-actions', {silent: false}], 'summary'], }; export default config; From e8b207a042469159f69ddd917b563b3054c08448 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 26 Jan 2023 16:07:06 +0100 Subject: [PATCH 8/9] chore: update changelog for release --- CHANGELOG.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e334667cf3c2..472efe9b8e45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,19 @@ ### Features +### Fixes + +### Chore & Maintenance + +### Performance + +## 29.4.1 + +### Features + - `[expect, jest-circus, @jest/types]` Implement `numPassingAsserts` of testResults to track the number of passing asserts in a test ([#13795](https://github.com/facebook/jest/pull/13795)) - `[jest-core]` Add newlines to JSON output ([#13817](https://github.com/facebook/jest/pull/13817)) -- `[@jest/reporters]` New functionality for Github Actions Reporter: automatic log folding ([#13626](https://github.com/facebook/jest/pull/13626)) +- `[@jest/reporters]` Automatic log folding in GitHub Actions Reporter ([#13626](https://github.com/facebook/jest/pull/13626)) ### Fixes @@ -12,10 +22,6 @@ - `[jest-runtime]` Handle missing `replaceProperty` ([#13823](https://github.com/facebook/jest/pull/13823)) - `[@jest/types]` Add partial support for `done` callbacks in typings of `each` ([#13756](https://github.com/facebook/jest/pull/13756)) -### Chore & Maintenance - -### Performance - ## 29.4.0 ### Features From bc84c8a15649aaaefdd624dc83824518c17467ed Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 26 Jan 2023 16:08:27 +0100 Subject: [PATCH 9/9] v29.4.1 --- lerna.json | 2 +- packages/babel-jest/package.json | 2 +- packages/expect-utils/package.json | 2 +- packages/expect/package.json | 2 +- packages/jest-circus/package.json | 2 +- packages/jest-cli/package.json | 2 +- packages/jest-config/package.json | 2 +- packages/jest-console/package.json | 2 +- packages/jest-core/package.json | 2 +- packages/jest-create-cache-key-function/package.json | 2 +- packages/jest-diff/package.json | 2 +- packages/jest-each/package.json | 2 +- packages/jest-environment-jsdom/package.json | 2 +- packages/jest-environment-node/package.json | 2 +- packages/jest-environment/package.json | 2 +- packages/jest-expect/package.json | 2 +- packages/jest-fake-timers/package.json | 2 +- packages/jest-globals/package.json | 2 +- packages/jest-haste-map/package.json | 2 +- packages/jest-jasmine2/package.json | 2 +- packages/jest-leak-detector/package.json | 2 +- packages/jest-matcher-utils/package.json | 2 +- packages/jest-message-util/package.json | 2 +- packages/jest-mock/package.json | 2 +- packages/jest-phabricator/package.json | 2 +- packages/jest-repl/package.json | 2 +- packages/jest-reporters/package.json | 2 +- packages/jest-resolve-dependencies/package.json | 2 +- packages/jest-resolve/package.json | 2 +- packages/jest-runner/package.json | 2 +- packages/jest-runtime/package.json | 2 +- packages/jest-snapshot/package.json | 2 +- packages/jest-test-result/package.json | 2 +- packages/jest-test-sequencer/package.json | 2 +- packages/jest-transform/package.json | 2 +- packages/jest-types/package.json | 2 +- packages/jest-util/package.json | 2 +- packages/jest-validate/package.json | 2 +- packages/jest-watcher/package.json | 2 +- packages/jest-worker/package.json | 2 +- packages/jest/package.json | 2 +- packages/pretty-format/package.json | 2 +- packages/test-globals/package.json | 2 +- packages/test-utils/package.json | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/lerna.json b/lerna.json index d4172ed702f5..06e8963b9d71 100644 --- a/lerna.json +++ b/lerna.json @@ -8,5 +8,5 @@ "syncWorkspaceLock": true } }, - "version": "29.4.0" + "version": "29.4.1" } diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index 3f2d378e7650..7ab741edc2ef 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -1,7 +1,7 @@ { "name": "babel-jest", "description": "Jest plugin to use babel for transformation.", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/expect-utils/package.json b/packages/expect-utils/package.json index 39ccf328a0ad..a8c988fc147a 100644 --- a/packages/expect-utils/package.json +++ b/packages/expect-utils/package.json @@ -1,6 +1,6 @@ { "name": "@jest/expect-utils", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/expect/package.json b/packages/expect/package.json index 201a1e03f34a..dc7eb9ae8f1e 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -1,6 +1,6 @@ { "name": "expect", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index d5cbd8a124de..0e6ddc3e1dc1 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -1,6 +1,6 @@ { "name": "jest-circus", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index 56672ef94b37..3a1907a0ba96 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -1,7 +1,7 @@ { "name": "jest-cli", "description": "Delightful JavaScript Testing.", - "version": "29.4.0", + "version": "29.4.1", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index b9ce0455e6fb..d4939aa242b0 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -1,6 +1,6 @@ { "name": "jest-config", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index 2eaf31ca82dc..ae444d3b3a30 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@jest/console", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index 7796eeeb9d56..685f8b57a634 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -1,7 +1,7 @@ { "name": "@jest/core", "description": "Delightful JavaScript Testing.", - "version": "29.4.0", + "version": "29.4.1", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-create-cache-key-function/package.json b/packages/jest-create-cache-key-function/package.json index 1e3aae844dbf..96a2db818dc4 100644 --- a/packages/jest-create-cache-key-function/package.json +++ b/packages/jest-create-cache-key-function/package.json @@ -1,6 +1,6 @@ { "name": "@jest/create-cache-key-function", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 988ca8067984..beda90b5a3cc 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -1,6 +1,6 @@ { "name": "jest-diff", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index 23927ad4d636..470898fdc2d8 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -1,6 +1,6 @@ { "name": "jest-each", - "version": "29.4.0", + "version": "29.4.1", "description": "Parameterised tests for Jest", "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/jest-environment-jsdom/package.json b/packages/jest-environment-jsdom/package.json index f1d1387c7493..75f6986dbfe6 100644 --- a/packages/jest-environment-jsdom/package.json +++ b/packages/jest-environment-jsdom/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-jsdom", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-environment-node/package.json b/packages/jest-environment-node/package.json index 5f76eecba2d2..39d09c843282 100644 --- a/packages/jest-environment-node/package.json +++ b/packages/jest-environment-node/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-node", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-environment/package.json b/packages/jest-environment/package.json index 5b11de47de99..ea3adc13a6b0 100644 --- a/packages/jest-environment/package.json +++ b/packages/jest-environment/package.json @@ -1,6 +1,6 @@ { "name": "@jest/environment", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-expect/package.json b/packages/jest-expect/package.json index 722de3290b5e..5b52f59b52c9 100644 --- a/packages/jest-expect/package.json +++ b/packages/jest-expect/package.json @@ -1,6 +1,6 @@ { "name": "@jest/expect", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-fake-timers/package.json b/packages/jest-fake-timers/package.json index 0bfad168b862..2cfa99364e43 100644 --- a/packages/jest-fake-timers/package.json +++ b/packages/jest-fake-timers/package.json @@ -1,6 +1,6 @@ { "name": "@jest/fake-timers", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-globals/package.json b/packages/jest-globals/package.json index cdae568e0b3a..7763b4a3b017 100644 --- a/packages/jest-globals/package.json +++ b/packages/jest-globals/package.json @@ -1,6 +1,6 @@ { "name": "@jest/globals", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index b7b2dc67fe8c..d06359213809 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -1,6 +1,6 @@ { "name": "jest-haste-map", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index 05dbc2bb99a1..a9783c10fb36 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -1,6 +1,6 @@ { "name": "jest-jasmine2", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-leak-detector/package.json b/packages/jest-leak-detector/package.json index f51a7018050a..df4c0ff14431 100644 --- a/packages/jest-leak-detector/package.json +++ b/packages/jest-leak-detector/package.json @@ -1,6 +1,6 @@ { "name": "jest-leak-detector", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index e34394e57325..8a20e6682b02 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -1,7 +1,7 @@ { "name": "jest-matcher-utils", "description": "A set of utility functions for expect and related packages", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index d5b1123e9c63..43aef18f9c4b 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-message-util", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-mock/package.json b/packages/jest-mock/package.json index cddb671f471f..b5a45cbc11e5 100644 --- a/packages/jest-mock/package.json +++ b/packages/jest-mock/package.json @@ -1,6 +1,6 @@ { "name": "jest-mock", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-phabricator/package.json b/packages/jest-phabricator/package.json index 0c441c718495..ca7792ad32a9 100644 --- a/packages/jest-phabricator/package.json +++ b/packages/jest-phabricator/package.json @@ -1,6 +1,6 @@ { "name": "jest-phabricator", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index a522fcc96b77..e911d5dff482 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -1,6 +1,6 @@ { "name": "jest-repl", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index 472077e8961c..1ce776ec3764 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -1,7 +1,7 @@ { "name": "@jest/reporters", "description": "Jest's reporters", - "version": "29.4.0", + "version": "29.4.1", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index af06f1b1bd24..d417cc5d44db 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve-dependencies", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index 495c61637544..ac61aa7cc2a7 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index a43f8b1a81f9..c44fe957ced6 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -1,6 +1,6 @@ { "name": "jest-runner", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 078dfa733342..870a84c0a5b9 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -1,6 +1,6 @@ { "name": "jest-runtime", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index 3c9881bf7c44..4aa44908007e 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -1,6 +1,6 @@ { "name": "jest-snapshot", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-test-result/package.json b/packages/jest-test-result/package.json index aca5f5463562..d9f661bffa0b 100644 --- a/packages/jest-test-result/package.json +++ b/packages/jest-test-result/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-result", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-test-sequencer/package.json b/packages/jest-test-sequencer/package.json index 762ad3ef298b..0232a1dd5f34 100644 --- a/packages/jest-test-sequencer/package.json +++ b/packages/jest-test-sequencer/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-sequencer", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-transform/package.json b/packages/jest-transform/package.json index 108b450bb4ec..00e5e466bda3 100644 --- a/packages/jest-transform/package.json +++ b/packages/jest-transform/package.json @@ -1,6 +1,6 @@ { "name": "@jest/transform", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-types/package.json b/packages/jest-types/package.json index 860208481c78..5399efd741c2 100644 --- a/packages/jest-types/package.json +++ b/packages/jest-types/package.json @@ -1,6 +1,6 @@ { "name": "@jest/types", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-util/package.json b/packages/jest-util/package.json index 19cd12f292a5..f60960c2c090 100644 --- a/packages/jest-util/package.json +++ b/packages/jest-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-util", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-validate/package.json b/packages/jest-validate/package.json index 78ec0a1f55ef..2d1d48f44b53 100644 --- a/packages/jest-validate/package.json +++ b/packages/jest-validate/package.json @@ -1,6 +1,6 @@ { "name": "jest-validate", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-watcher/package.json b/packages/jest-watcher/package.json index 1c4491064acb..78897416d2ff 100644 --- a/packages/jest-watcher/package.json +++ b/packages/jest-watcher/package.json @@ -1,7 +1,7 @@ { "name": "jest-watcher", "description": "Delightful JavaScript Testing.", - "version": "29.4.0", + "version": "29.4.1", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/jest-worker/package.json b/packages/jest-worker/package.json index 6214291e4a83..80ef0a4b89c6 100644 --- a/packages/jest-worker/package.json +++ b/packages/jest-worker/package.json @@ -1,6 +1,6 @@ { "name": "jest-worker", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest/package.json b/packages/jest/package.json index 6febc27a64d6..637efbfccfbe 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -1,7 +1,7 @@ { "name": "jest", "description": "Delightful JavaScript Testing.", - "version": "29.4.0", + "version": "29.4.1", "main": "./build/index.js", "types": "./build/index.d.ts", "exports": { diff --git a/packages/pretty-format/package.json b/packages/pretty-format/package.json index 2caaf48650be..6b3dc726692f 100644 --- a/packages/pretty-format/package.json +++ b/packages/pretty-format/package.json @@ -1,6 +1,6 @@ { "name": "pretty-format", - "version": "29.4.0", + "version": "29.4.1", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/test-globals/package.json b/packages/test-globals/package.json index 0f66d3b88970..a2bcf3886242 100644 --- a/packages/test-globals/package.json +++ b/packages/test-globals/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-globals", - "version": "29.4.0", + "version": "29.4.1", "private": true, "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 2f7d4c09dfa8..b064dd1ef7c8 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-utils", - "version": "29.4.0", + "version": "29.4.1", "private": true, "main": "./build/index.js", "types": "./build/index.d.ts",