From 3ce02b056158df7c7719f1491bf737eb95fae4d6 Mon Sep 17 00:00:00 2001 From: Willian Agostini Date: Wed, 17 Jan 2024 21:41:14 -0300 Subject: [PATCH] feat: add message of total tests to run --- .../legacy-code-todo-rewrite/jestAdapter.ts | 1 + .../jestAdapterInit.ts | 28 +++++++++++++++++++ packages/jest-core/src/ReporterDispatcher.ts | 11 ++++++++ packages/jest-core/src/TestScheduler.ts | 6 ++++ packages/jest-jasmine2/src/index.ts | 10 +++++-- packages/jest-jasmine2/src/reporter.ts | 13 +++++++-- packages/jest-reporters/src/BaseReporter.ts | 2 ++ .../jest-reporters/src/DefaultReporter.ts | 4 +++ packages/jest-reporters/src/Status.ts | 14 +++++++++- packages/jest-reporters/src/types.ts | 4 +++ packages/jest-test-result/src/types.ts | 1 + 11 files changed, 89 insertions(+), 5 deletions(-) diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts index e80bbfba4809..dd02cb5a0d95 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts @@ -104,6 +104,7 @@ const jestAdapter = async ( const results = await runAndTransformResultsToJestFormat({ config, globalConfig, + sendMessageToJest, setupAfterEnvPerfStats, testPath, }); 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 5c71ce1aafa4..fbf2f3e8fc39 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapterInit.ts @@ -30,6 +30,7 @@ import { addEventHandler, dispatch, getState as getRunnerState, + getState, } from '../state'; import testCaseReportHandler from '../testCaseReportHandler'; import {unhandledRejectionHandler} from '../unhandledRejectionHandler'; @@ -143,17 +144,44 @@ export const initialize = async ({ return {globals: globalsObject, snapshotState}; }; +const countNumberOfTests = (describeBlock: Circus.DescribeBlock) => { + let numberOfTests = 0; + + for (const child of describeBlock.children) { + switch (child.type) { + case 'describeBlock': + numberOfTests += countNumberOfTests(child); + break; + + case 'test': + numberOfTests++; + break; + } + } + + return numberOfTests; +}; + export const runAndTransformResultsToJestFormat = async ({ config, globalConfig, + sendMessageToJest, setupAfterEnvPerfStats, testPath, }: { config: Config.ProjectConfig; globalConfig: Config.GlobalConfig; + sendMessageToJest?: TestFileEvent; testPath: string; setupAfterEnvPerfStats: Config.SetupAfterEnvPerfStats; }): Promise => { + const {rootDescribeBlock} = getState(); + if (sendMessageToJest) + sendMessageToJest('test-file-num-of-tests', [ + testPath, + countNumberOfTests(rootDescribeBlock), + ]); + const runResult: Circus.RunResult = await run(); let numFailingTests = 0; diff --git a/packages/jest-core/src/ReporterDispatcher.ts b/packages/jest-core/src/ReporterDispatcher.ts index 451bb5bd6102..212e15543f22 100644 --- a/packages/jest-core/src/ReporterDispatcher.ts +++ b/packages/jest-core/src/ReporterDispatcher.ts @@ -92,6 +92,17 @@ export default class ReporterDispatcher { } } + async onNumberOfTests( + testPath: string, + numberOfTests: number, + ): Promise { + for (const reporter of this._reporters) { + if (reporter.onNumberOfTests) { + await reporter.onNumberOfTests(testPath, numberOfTests); + } + } + } + async onRunComplete( testContexts: Set, results: AggregatedResult, diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index 090b650f55a7..1fcee8a45a40 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -272,6 +272,12 @@ class TestScheduler { this._dispatcher.onTestCaseResult(test, testCaseResult); }, ), + testRunner.on( + 'test-file-num-of-tests', + ([testPath, numberOfTests]) => { + this._dispatcher.onNumberOfTests(testPath, numberOfTests); + }, + ), ]; await testRunner.runTests(tests, watcher, testRunnerOptions); diff --git a/packages/jest-jasmine2/src/index.ts b/packages/jest-jasmine2/src/index.ts index 00562172fff9..b0ac94b372ff 100644 --- a/packages/jest-jasmine2/src/index.ts +++ b/packages/jest-jasmine2/src/index.ts @@ -8,7 +8,7 @@ import * as path from 'path'; import type {JestEnvironment} from '@jest/environment'; import {getCallsite} from '@jest/source-map'; -import type {TestResult} from '@jest/test-result'; +import type {TestFileEvent, TestResult} from '@jest/test-result'; import type {Config, Global} from '@jest/types'; import type Runtime from 'jest-runtime'; import type {SnapshotState} from 'jest-snapshot'; @@ -31,8 +31,14 @@ export default async function jasmine2( environment: JestEnvironment, runtime: Runtime, testPath: string, + sendMessageToJest?: TestFileEvent, ): Promise { - const reporter = new JasmineReporter(globalConfig, config, testPath); + const reporter = new JasmineReporter( + globalConfig, + config, + testPath, + sendMessageToJest, + ); const jasmineFactory = runtime.requireInternalModule( JASMINE, diff --git a/packages/jest-jasmine2/src/reporter.ts b/packages/jest-jasmine2/src/reporter.ts index 4182b370cc3d..1fb53e1afd20 100644 --- a/packages/jest-jasmine2/src/reporter.ts +++ b/packages/jest-jasmine2/src/reporter.ts @@ -7,6 +7,7 @@ import { type AssertionResult, + type TestFileEvent, type TestResult, createEmptyTestResult, } from '@jest/test-result'; @@ -27,11 +28,13 @@ export default class Jasmine2Reporter implements Reporter { private readonly _resultsPromise: Promise; private readonly _startTimes: Map; private readonly _testPath: string; + private readonly _sendMessageToJest?: TestFileEvent; constructor( globalConfig: Config.GlobalConfig, config: Config.ProjectConfig, testPath: string, + sendMessageToJest?: TestFileEvent, ) { this._globalConfig = globalConfig; this._config = config; @@ -41,10 +44,16 @@ export default class Jasmine2Reporter implements Reporter { this._resolve = null; this._resultsPromise = new Promise(resolve => (this._resolve = resolve)); this._startTimes = new Map(); + this._sendMessageToJest = sendMessageToJest; } - // eslint-disable-next-line @typescript-eslint/no-empty-function - jasmineStarted(_runDetails: RunDetails): void {} + jasmineStarted(_runDetails: RunDetails): void { + if (this._sendMessageToJest && _runDetails.totalSpecsDefined !== undefined) + this._sendMessageToJest('test-file-num-of-tests', [ + this._testPath, + _runDetails.totalSpecsDefined, + ]); + } specStarted(spec: SpecResult): void { this._startTimes.set(spec.id, Date.now()); diff --git a/packages/jest-reporters/src/BaseReporter.ts b/packages/jest-reporters/src/BaseReporter.ts index 1e9f12a0e8e7..cd35aa21f11e 100644 --- a/packages/jest-reporters/src/BaseReporter.ts +++ b/packages/jest-reporters/src/BaseReporter.ts @@ -34,6 +34,8 @@ export default class BaseReporter implements Reporter { /* eslint-disable @typescript-eslint/no-empty-function */ onTestCaseResult(_test: Test, _testCaseResult: TestCaseResult): void {} + onNumberOfTests(_testPath: string, _numberOfTests: number): void {} + onTestResult( _test?: Test, _testResult?: TestResult, diff --git a/packages/jest-reporters/src/DefaultReporter.ts b/packages/jest-reporters/src/DefaultReporter.ts index 288aafb26bd9..e2035a4bb13e 100644 --- a/packages/jest-reporters/src/DefaultReporter.ts +++ b/packages/jest-reporters/src/DefaultReporter.ts @@ -147,6 +147,10 @@ export default class DefaultReporter extends BaseReporter { this._status.addTestCaseResult(test, testCaseResult); } + override onNumberOfTests(testPath: string, numberOfTests: number): void { + this._status.addNumberOfTests(testPath, numberOfTests); + } + override onRunComplete(): void { this.forceFlushBufferedOutput(); this._status.runFinished(); diff --git a/packages/jest-reporters/src/Status.ts b/packages/jest-reporters/src/Status.ts index f6b407df7eb1..f36ed86773e2 100644 --- a/packages/jest-reporters/src/Status.ts +++ b/packages/jest-reporters/src/Status.ts @@ -91,6 +91,7 @@ export default class Status { private _interval?: NodeJS.Timeout; private _aggregatedResults?: AggregatedResult; private _showStatus: boolean; + private _numberOfTests: Map; constructor(private readonly _globalConfig: Config.GlobalConfig) { this._cache = null; @@ -100,6 +101,7 @@ export default class Status { this._emitScheduled = false; this._estimatedTime = 0; this._showStatus = false; + this._numberOfTests = new Map(); } onChange(callback: () => void): void { @@ -134,6 +136,14 @@ export default class Status { this._currentTests.addPassedTest(test.path); } + addNumberOfTests(testPath: string, numberOfTests: number): void { + this._numberOfTests.set(testPath, numberOfTests); + } + + getNumberOfTests(testPath: string): number | undefined { + return this._numberOfTests.get(testPath); + } + testStarted(testPath: string, config: Config.ProjectConfig): void { this._currentTests.add(testPath, config); if (this._showStatus) { @@ -180,8 +190,10 @@ export default class Status { : ''; const prefix = RUNNING + projectDisplayName; + const numberOfTests = this.getNumberOfTests(testPath); + const txtNumberOfTests = numberOfTests ? `of ${numberOfTests}` : ''; const currentTestPassed = `${chalk.bold.green( - `${passedTests} passed`, + `${passedTests} passed ${txtNumberOfTests}`, )}`; content += `${wrapAnsiString( prefix + diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts index a33e6ddd4f65..0f7951b9179e 100644 --- a/packages/jest-reporters/src/types.ts +++ b/packages/jest-reporters/src/types.ts @@ -42,6 +42,10 @@ export interface Reporter { test: Test, testCaseResult: TestCaseResult, ) => Promise | void; + readonly onNumberOfTests?: ( + testPath: string, + numberOfTests: number, + ) => Promise | void; readonly onRunStart?: ( results: AggregatedResult, options: ReporterOnStartOptions, diff --git a/packages/jest-test-result/src/types.ts b/packages/jest-test-result/src/types.ts index 7200d5a73da8..5f0ed91f4eb8 100644 --- a/packages/jest-test-result/src/types.ts +++ b/packages/jest-test-result/src/types.ts @@ -205,6 +205,7 @@ export type TestContext = { // Typings for `sendMessageToJest` events export type TestEvents = { + 'test-file-num-of-tests': [string, number]; 'test-file-start': [Test]; 'test-file-success': [Test, TestResult]; 'test-file-failure': [Test, SerializableError];