From cf5b44b07904d5685a1a1fcb58eef5f13103eb97 Mon Sep 17 00:00:00 2001 From: connectdotz Date: Wed, 27 Mar 2024 21:37:43 -0400 Subject: [PATCH 1/2] fix "Jest: Run All Test" command blocked by watch mode run --- src/JestExt/core.ts | 2 +- src/JestExt/process-session.ts | 89 +++++++++++++--------- src/JestProcessManagement/types.ts | 1 + src/test-provider/test-item-data.ts | 8 +- tests/JestExt/core.test.ts | 5 +- tests/JestExt/process-session.test.ts | 16 ++++ tests/test-provider/test-item-data.test.ts | 5 +- 7 files changed, 81 insertions(+), 45 deletions(-) diff --git a/src/JestExt/core.ts b/src/JestExt/core.ts index c42a89b89..e1602e56d 100644 --- a/src/JestExt/core.ts +++ b/src/JestExt/core.ts @@ -621,7 +621,7 @@ export class JestExt { await this.exitDeferMode(); if (!editor) { - if (this.processSession.scheduleProcess({ type: 'all-tests' })) { + if (this.processSession.scheduleProcess({ type: 'all-tests', nonBlocking: true })) { this.dirtyFiles.clear(); return; } diff --git a/src/JestExt/process-session.ts b/src/JestExt/process-session.ts index da789af99..f0aac752b 100644 --- a/src/JestExt/process-session.ts +++ b/src/JestExt/process-session.ts @@ -33,36 +33,46 @@ const getTransform = (request: JestExtRequestType): JestProcessRequestTransform } }; -const ProcessScheduleStrategy: Record = { - // abort if there is already an pending request - 'all-tests': { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }, - 'watch-tests': { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }, - 'watch-all-tests': { - queue: 'blocking', - dedupe: { filterByStatus: ['pending'] }, - }, - - // abort if there is already identical pending request - 'by-file': { - queue: 'blocking-2', - dedupe: { filterByStatus: ['pending'] }, - }, - 'by-file-test': { - queue: 'blocking-2', - dedupe: { filterByStatus: ['pending'], filterByContent: true }, - }, - 'by-file-pattern': { - queue: 'blocking-2', - dedupe: { filterByStatus: ['pending'] }, - }, - 'by-file-test-pattern': { - queue: 'blocking-2', - dedupe: { filterByStatus: ['pending'], filterByContent: true }, - }, - 'not-test': { - queue: 'non-blocking', - dedupe: { filterByStatus: ['pending'] }, - }, +const getScheduleStrategy = (requestType: JestTestProcessType): ScheduleStrategy => { + switch (requestType) { + // abort if there is already an pending request + case 'all-tests': + return { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }; + case 'watch-tests': + return { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }; + case 'watch-all-tests': + return { + queue: 'blocking', + dedupe: { filterByStatus: ['pending'] }, + }; + case 'by-file': + return { + queue: 'blocking-2', + dedupe: { filterByStatus: ['pending'] }, + }; + case 'by-file-test': + return { + queue: 'blocking-2', + dedupe: { filterByStatus: ['pending'], filterByContent: true }, + }; + case 'by-file-pattern': + return { + queue: 'blocking-2', + dedupe: { filterByStatus: ['pending'] }, + }; + case 'by-file-test-pattern': + return { + queue: 'blocking-2', + dedupe: { filterByStatus: ['pending'], filterByContent: true }, + }; + case 'not-test': + return { + queue: 'non-blocking', + dedupe: { filterByStatus: ['pending'] }, + }; + default: + throw new Error(`Unexpected request type ${requestType}`); + } }; export interface ProcessSession { @@ -127,14 +137,24 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes const lSession = listenerSession; switch (request.type) { - case 'all-tests': + case 'all-tests': { + const schedule = getScheduleStrategy(request.type); + if (request.nonBlocking) { + schedule.queue = 'blocking-2'; + } + return transform({ + ...request, + listener: new RunTestListener(lSession), + schedule, + }); + } case 'watch-all-tests': case 'watch-tests': case 'by-file': case 'by-file-pattern': case 'by-file-test': case 'by-file-test-pattern': { - const schedule = ProcessScheduleStrategy[request.type]; + const schedule = getScheduleStrategy(request.type); return transform({ ...request, listener: new RunTestListener(lSession), @@ -142,7 +162,7 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes }); } case 'list-test-files': { - const schedule = ProcessScheduleStrategy['not-test']; + const schedule = getScheduleStrategy('not-test'); return transform({ ...request, type: 'not-test', @@ -165,7 +185,8 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes } if (context.settings.runMode.config.runAllTestsOnStartup) { - scheduleProcess({ type: 'all-tests' }); + // on startup, run all tests in blocking mode always + scheduleProcess({ type: 'all-tests', nonBlocking: false }); } if (context.settings.runMode.config.type === 'watch') { scheduleProcess({ type: 'watch-tests' }); diff --git a/src/JestProcessManagement/types.ts b/src/JestProcessManagement/types.ts index 2cc404cb0..115ac1960 100644 --- a/src/JestProcessManagement/types.ts +++ b/src/JestProcessManagement/types.ts @@ -62,6 +62,7 @@ export type JestProcessRequestSimple = | { type: Extract; updateSnapshot?: boolean; + nonBlocking?: boolean; } | { type: Extract; diff --git a/src/test-provider/test-item-data.ts b/src/test-provider/test-item-data.ts index 0c627498b..4bfa4af7c 100644 --- a/src/test-provider/test-item-data.ts +++ b/src/test-provider/test-item-data.ts @@ -11,7 +11,7 @@ import { TestSuitChangeEvent } from '../TestResults/test-result-events'; import { Debuggable, ItemCommand, TestItemData } from './types'; import { JestTestProviderContext } from './test-provider-context'; import { JestTestRun } from './jest-test-run'; -import { JestProcessInfo, JestProcessRequest } from '../JestProcessManagement'; +import { JestProcessInfo } from '../JestProcessManagement'; import { GENERIC_ERROR, LONG_RUNNING_TESTS, getExitErrorDef } from '../errors'; import { tiContextManager } from './test-item-context-manager'; import { runModeDescription } from '../JestExt/run-mode'; @@ -153,12 +153,8 @@ export class WorkspaceRoot extends TestItemDataBase { } getJestRunRequest(itemCommand?: ItemCommand): JestExtRequestType { - const transform = (request: JestProcessRequest) => { - request.schedule.queue = 'blocking-2'; - return request; - }; const updateSnapshot = itemCommand === ItemCommand.updateSnapshot; - return { type: 'all-tests', updateSnapshot, transform }; + return { type: 'all-tests', nonBlocking: true, updateSnapshot }; } discoverTest(run: JestTestRun): void { const testList = this.context.ext.testResultProvider.getTestList(); diff --git a/tests/JestExt/core.test.ts b/tests/JestExt/core.test.ts index edd8ebfce..80528ca97 100644 --- a/tests/JestExt/core.test.ts +++ b/tests/JestExt/core.test.ts @@ -875,7 +875,10 @@ describe('JestExt', () => { dirtyFiles.clear = jest.fn(); await sut.runAllTests(); - expect(mockProcessSession.scheduleProcess).toHaveBeenCalledWith({ type: 'all-tests' }); + expect(mockProcessSession.scheduleProcess).toHaveBeenCalledWith({ + type: 'all-tests', + nonBlocking: true, + }); if (scheduleProcess) { expect(dirtyFiles.clear).toHaveBeenCalled(); } else { diff --git a/tests/JestExt/process-session.test.ts b/tests/JestExt/process-session.test.ts index b7995b156..7e0ba11a4 100644 --- a/tests/JestExt/process-session.test.ts +++ b/tests/JestExt/process-session.test.ts @@ -143,6 +143,22 @@ describe('ProcessSession', () => { expect(requestTypes).toEqual(expectedRequests); } ); + it('if runAllTestsOnStartup is true, it will run all tests in blocking queue', async () => { + expect.hasAssertions(); + const runMode = new RunMode({ type: 'watch', runAllTestsOnStartup: true }); + context.settings = { runMode }; + processManagerMock.numberOfProcesses.mockReturnValue(0); + const session = createProcessSession(context); + await session.start(); + + expect(processManagerMock.scheduleJestProcess).toHaveBeenCalledWith( + expect.objectContaining({ + type: 'all-tests', + schedule: expect.objectContaining({ queue: 'blocking' }), + }), + undefined + ); + }); it('will clear all process before starting new ones', async () => { expect.hasAssertions(); context.settings = { runMode: new RunMode() }; diff --git a/tests/test-provider/test-item-data.test.ts b/tests/test-provider/test-item-data.test.ts index 93f6d8649..a0c682e3f 100644 --- a/tests/test-provider/test-item-data.test.ts +++ b/tests/test-provider/test-item-data.test.ts @@ -693,14 +693,13 @@ describe('test-item-data', () => { process = mockScheduleProcess(context); }); describe('run request', () => { - it('WorkspaceRoot runs all tests in the workspace in blocking-2 queue', () => { + it('WorkspaceRoot runs all tests in the workspace with non-blocking flag', () => { const wsRoot = new WorkspaceRoot(context); const jestRun = createTestRun(); wsRoot.scheduleTest(jestRun); const r = context.ext.session.scheduleProcess.mock.calls[0][0]; expect(r.type).toEqual('all-tests'); - const transformed = r.transform({ schedule: { queue: 'blocking' } }); - expect(transformed.schedule.queue).toEqual('blocking-2'); + expect(r.nonBlocking).toEqual(true); }); it('FolderData runs all tests inside the folder', () => { const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', { fsPath: '/ws-1' }); From d66532629f3adbf37c27db3a5beaaa967834279f Mon Sep 17 00:00:00 2001 From: connectdotz Date: Wed, 27 Mar 2024 21:54:01 -0400 Subject: [PATCH 2/2] remove unnecessary default switch statement --- src/JestExt/process-session.ts | 2 -- tests/JestExt/process-session.test.ts | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/JestExt/process-session.ts b/src/JestExt/process-session.ts index f0aac752b..286ba8fa4 100644 --- a/src/JestExt/process-session.ts +++ b/src/JestExt/process-session.ts @@ -70,8 +70,6 @@ const getScheduleStrategy = (requestType: JestTestProcessType): ScheduleStrategy queue: 'non-blocking', dedupe: { filterByStatus: ['pending'] }, }; - default: - throw new Error(`Unexpected request type ${requestType}`); } }; diff --git a/tests/JestExt/process-session.test.ts b/tests/JestExt/process-session.test.ts index 7e0ba11a4..38fe6a6ab 100644 --- a/tests/JestExt/process-session.test.ts +++ b/tests/JestExt/process-session.test.ts @@ -50,6 +50,7 @@ describe('ProcessSession', () => { it.each` type | inputProperty | expectedSchedule | expectedExtraProperty ${'all-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined} + ${'all-tests'} | ${{ nonBlocking: true }} | ${{ queue: 'blocking-2', dedupe: { filterByStatus: ['pending'] } }} | ${undefined} ${'all-tests'} | ${{ transform }} | ${{ queue: 'blocking-2', dedupe: { filterByStatus: ['pending'] } }} | ${undefined} ${'watch-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined} ${'watch-all-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}