Skip to content

Commit ab4e5c6

Browse files
authored
fix "Jest: Run All Test" command blocked by watch mode run (#1132)
* fix "Jest: Run All Test" command blocked by watch mode run * remove unnecessary default switch statement
1 parent ea3816c commit ab4e5c6

File tree

7 files changed

+80
-45
lines changed

7 files changed

+80
-45
lines changed

src/JestExt/core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ export class JestExt {
621621
await this.exitDeferMode();
622622

623623
if (!editor) {
624-
if (this.processSession.scheduleProcess({ type: 'all-tests' })) {
624+
if (this.processSession.scheduleProcess({ type: 'all-tests', nonBlocking: true })) {
625625
this.dirtyFiles.clear();
626626
return;
627627
}

src/JestExt/process-session.ts

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,36 +33,44 @@ const getTransform = (request: JestExtRequestType): JestProcessRequestTransform
3333
}
3434
};
3535

36-
const ProcessScheduleStrategy: Record<JestTestProcessType, ScheduleStrategy> = {
37-
// abort if there is already an pending request
38-
'all-tests': { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } },
39-
'watch-tests': { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } },
40-
'watch-all-tests': {
41-
queue: 'blocking',
42-
dedupe: { filterByStatus: ['pending'] },
43-
},
44-
45-
// abort if there is already identical pending request
46-
'by-file': {
47-
queue: 'blocking-2',
48-
dedupe: { filterByStatus: ['pending'] },
49-
},
50-
'by-file-test': {
51-
queue: 'blocking-2',
52-
dedupe: { filterByStatus: ['pending'], filterByContent: true },
53-
},
54-
'by-file-pattern': {
55-
queue: 'blocking-2',
56-
dedupe: { filterByStatus: ['pending'] },
57-
},
58-
'by-file-test-pattern': {
59-
queue: 'blocking-2',
60-
dedupe: { filterByStatus: ['pending'], filterByContent: true },
61-
},
62-
'not-test': {
63-
queue: 'non-blocking',
64-
dedupe: { filterByStatus: ['pending'] },
65-
},
36+
const getScheduleStrategy = (requestType: JestTestProcessType): ScheduleStrategy => {
37+
switch (requestType) {
38+
// abort if there is already an pending request
39+
case 'all-tests':
40+
return { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } };
41+
case 'watch-tests':
42+
return { queue: 'blocking', dedupe: { filterByStatus: ['pending'] } };
43+
case 'watch-all-tests':
44+
return {
45+
queue: 'blocking',
46+
dedupe: { filterByStatus: ['pending'] },
47+
};
48+
case 'by-file':
49+
return {
50+
queue: 'blocking-2',
51+
dedupe: { filterByStatus: ['pending'] },
52+
};
53+
case 'by-file-test':
54+
return {
55+
queue: 'blocking-2',
56+
dedupe: { filterByStatus: ['pending'], filterByContent: true },
57+
};
58+
case 'by-file-pattern':
59+
return {
60+
queue: 'blocking-2',
61+
dedupe: { filterByStatus: ['pending'] },
62+
};
63+
case 'by-file-test-pattern':
64+
return {
65+
queue: 'blocking-2',
66+
dedupe: { filterByStatus: ['pending'], filterByContent: true },
67+
};
68+
case 'not-test':
69+
return {
70+
queue: 'non-blocking',
71+
dedupe: { filterByStatus: ['pending'] },
72+
};
73+
}
6674
};
6775

6876
export interface ProcessSession {
@@ -127,22 +135,32 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes
127135

128136
const lSession = listenerSession;
129137
switch (request.type) {
130-
case 'all-tests':
138+
case 'all-tests': {
139+
const schedule = getScheduleStrategy(request.type);
140+
if (request.nonBlocking) {
141+
schedule.queue = 'blocking-2';
142+
}
143+
return transform({
144+
...request,
145+
listener: new RunTestListener(lSession),
146+
schedule,
147+
});
148+
}
131149
case 'watch-all-tests':
132150
case 'watch-tests':
133151
case 'by-file':
134152
case 'by-file-pattern':
135153
case 'by-file-test':
136154
case 'by-file-test-pattern': {
137-
const schedule = ProcessScheduleStrategy[request.type];
155+
const schedule = getScheduleStrategy(request.type);
138156
return transform({
139157
...request,
140158
listener: new RunTestListener(lSession),
141159
schedule,
142160
});
143161
}
144162
case 'list-test-files': {
145-
const schedule = ProcessScheduleStrategy['not-test'];
163+
const schedule = getScheduleStrategy('not-test');
146164
return transform({
147165
...request,
148166
type: 'not-test',
@@ -165,7 +183,8 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes
165183
}
166184

167185
if (context.settings.runMode.config.runAllTestsOnStartup) {
168-
scheduleProcess({ type: 'all-tests' });
186+
// on startup, run all tests in blocking mode always
187+
scheduleProcess({ type: 'all-tests', nonBlocking: false });
169188
}
170189
if (context.settings.runMode.config.type === 'watch') {
171190
scheduleProcess({ type: 'watch-tests' });

src/JestProcessManagement/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export type JestProcessRequestSimple =
6262
| {
6363
type: Extract<JestTestProcessType, 'all-tests'>;
6464
updateSnapshot?: boolean;
65+
nonBlocking?: boolean;
6566
}
6667
| {
6768
type: Extract<JestTestProcessType, 'by-file'>;

src/test-provider/test-item-data.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { TestSuitChangeEvent } from '../TestResults/test-result-events';
1111
import { Debuggable, ItemCommand, TestItemData } from './types';
1212
import { JestTestProviderContext } from './test-provider-context';
1313
import { JestTestRun } from './jest-test-run';
14-
import { JestProcessInfo, JestProcessRequest } from '../JestProcessManagement';
14+
import { JestProcessInfo } from '../JestProcessManagement';
1515
import { GENERIC_ERROR, LONG_RUNNING_TESTS, getExitErrorDef } from '../errors';
1616
import { tiContextManager } from './test-item-context-manager';
1717
import { runModeDescription } from '../JestExt/run-mode';
@@ -153,12 +153,8 @@ export class WorkspaceRoot extends TestItemDataBase {
153153
}
154154

155155
getJestRunRequest(itemCommand?: ItemCommand): JestExtRequestType {
156-
const transform = (request: JestProcessRequest) => {
157-
request.schedule.queue = 'blocking-2';
158-
return request;
159-
};
160156
const updateSnapshot = itemCommand === ItemCommand.updateSnapshot;
161-
return { type: 'all-tests', updateSnapshot, transform };
157+
return { type: 'all-tests', nonBlocking: true, updateSnapshot };
162158
}
163159
discoverTest(run: JestTestRun): void {
164160
const testList = this.context.ext.testResultProvider.getTestList();

tests/JestExt/core.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,7 +875,10 @@ describe('JestExt', () => {
875875
dirtyFiles.clear = jest.fn();
876876

877877
await sut.runAllTests();
878-
expect(mockProcessSession.scheduleProcess).toHaveBeenCalledWith({ type: 'all-tests' });
878+
expect(mockProcessSession.scheduleProcess).toHaveBeenCalledWith({
879+
type: 'all-tests',
880+
nonBlocking: true,
881+
});
879882
if (scheduleProcess) {
880883
expect(dirtyFiles.clear).toHaveBeenCalled();
881884
} else {

tests/JestExt/process-session.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ describe('ProcessSession', () => {
5050
it.each`
5151
type | inputProperty | expectedSchedule | expectedExtraProperty
5252
${'all-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}
53+
${'all-tests'} | ${{ nonBlocking: true }} | ${{ queue: 'blocking-2', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}
5354
${'all-tests'} | ${{ transform }} | ${{ queue: 'blocking-2', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}
5455
${'watch-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}
5556
${'watch-all-tests'} | ${undefined} | ${{ queue: 'blocking', dedupe: { filterByStatus: ['pending'] } }} | ${undefined}
@@ -143,6 +144,22 @@ describe('ProcessSession', () => {
143144
expect(requestTypes).toEqual(expectedRequests);
144145
}
145146
);
147+
it('if runAllTestsOnStartup is true, it will run all tests in blocking queue', async () => {
148+
expect.hasAssertions();
149+
const runMode = new RunMode({ type: 'watch', runAllTestsOnStartup: true });
150+
context.settings = { runMode };
151+
processManagerMock.numberOfProcesses.mockReturnValue(0);
152+
const session = createProcessSession(context);
153+
await session.start();
154+
155+
expect(processManagerMock.scheduleJestProcess).toHaveBeenCalledWith(
156+
expect.objectContaining({
157+
type: 'all-tests',
158+
schedule: expect.objectContaining({ queue: 'blocking' }),
159+
}),
160+
undefined
161+
);
162+
});
146163
it('will clear all process before starting new ones', async () => {
147164
expect.hasAssertions();
148165
context.settings = { runMode: new RunMode() };

tests/test-provider/test-item-data.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,14 +693,13 @@ describe('test-item-data', () => {
693693
process = mockScheduleProcess(context);
694694
});
695695
describe('run request', () => {
696-
it('WorkspaceRoot runs all tests in the workspace in blocking-2 queue', () => {
696+
it('WorkspaceRoot runs all tests in the workspace with non-blocking flag', () => {
697697
const wsRoot = new WorkspaceRoot(context);
698698
const jestRun = createTestRun();
699699
wsRoot.scheduleTest(jestRun);
700700
const r = context.ext.session.scheduleProcess.mock.calls[0][0];
701701
expect(r.type).toEqual('all-tests');
702-
const transformed = r.transform({ schedule: { queue: 'blocking' } });
703-
expect(transformed.schedule.queue).toEqual('blocking-2');
702+
expect(r.nonBlocking).toEqual(true);
704703
});
705704
it('FolderData runs all tests inside the folder', () => {
706705
const parent: any = controllerMock.createTestItem('ws-1', 'ws-1', { fsPath: '/ws-1' });

0 commit comments

Comments
 (0)