Skip to content

Commit

Permalink
fix "Jest: Run All Test" command blocked by watch mode run (#1132)
Browse files Browse the repository at this point in the history
* fix "Jest: Run All Test" command blocked by watch mode run

* remove unnecessary default switch statement
  • Loading branch information
connectdotz committed Mar 28, 2024
1 parent ea3816c commit ab4e5c6
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/JestExt/core.ts
Expand Up @@ -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;
}
Expand Down
87 changes: 53 additions & 34 deletions src/JestExt/process-session.ts
Expand Up @@ -33,36 +33,44 @@ const getTransform = (request: JestExtRequestType): JestProcessRequestTransform
}
};

const ProcessScheduleStrategy: Record<JestTestProcessType, ScheduleStrategy> = {
// 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'] },
};
}
};

export interface ProcessSession {
Expand Down Expand Up @@ -127,22 +135,32 @@ 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),
schedule,
});
}
case 'list-test-files': {
const schedule = ProcessScheduleStrategy['not-test'];
const schedule = getScheduleStrategy('not-test');
return transform({
...request,
type: 'not-test',
Expand All @@ -165,7 +183,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' });
Expand Down
1 change: 1 addition & 0 deletions src/JestProcessManagement/types.ts
Expand Up @@ -62,6 +62,7 @@ export type JestProcessRequestSimple =
| {
type: Extract<JestTestProcessType, 'all-tests'>;
updateSnapshot?: boolean;
nonBlocking?: boolean;
}
| {
type: Extract<JestTestProcessType, 'by-file'>;
Expand Down
8 changes: 2 additions & 6 deletions src/test-provider/test-item-data.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion tests/JestExt/core.test.ts
Expand Up @@ -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 {
Expand Down
17 changes: 17 additions & 0 deletions tests/JestExt/process-session.test.ts
Expand Up @@ -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}
Expand Down Expand Up @@ -143,6 +144,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() };
Expand Down
5 changes: 2 additions & 3 deletions tests/test-provider/test-item-data.test.ts
Expand Up @@ -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' });
Expand Down

0 comments on commit ab4e5c6

Please sign in to comment.