Skip to content

Commit

Permalink
implement TestTag and enable run for watch mode (jest-community#809)
Browse files Browse the repository at this point in the history
  • Loading branch information
connectdotz authored Jan 1, 2022
1 parent 2688e64 commit 5251851
Show file tree
Hide file tree
Showing 22 changed files with 977 additions and 499 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "vscode-jest",
"displayName": "Jest",
"description": "Use Facebook's Jest With Pleasure.",
"version": "4.3.0-rc.1",
"version": "4.3.0",
"publisher": "Orta",
"engines": {
"vscode": "^1.59.0"
"vscode": "^1.63.0"
},
"author": {
"name": "Orta Therox, ConnectDotz & Sean Poulter",
Expand Down Expand Up @@ -443,7 +443,8 @@
"lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" \"*.json\" \"*.js\" ",
"test": "jest",
"watch-test": "yarn test -- --watch",
"tsc": "tsc --noEmit"
"tsc": "tsc --noEmit",
"update-vscode-type": "npx vscode-dts main; mv ./vscode.d.ts ./typings"
},
"dependencies": {
"istanbul-lib-coverage": "^3.0.0",
Expand Down
61 changes: 32 additions & 29 deletions src/JestExt/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,7 @@ import { resultsWithoutAnsiEscapeSequence } from '../TestResults/TestResult';
import { CoverageMapData } from 'istanbul-lib-coverage';
import { Logging } from '../logging';
import { createProcessSession, ProcessSession } from './process-session';
import {
DebugFunction,
JestExtContext,
JestSessionEvents,
JestExtSessionContext,
JestRunEvent,
} from './types';
import { JestExtContext, JestSessionEvents, JestExtSessionContext, JestRunEvent } from './types';
import * as messaging from '../messaging';
import { SupportedLanguageIds } from '../appGlobals';
import { createJestExtContext, getExtensionResourceSettings, prefixWorkspace } from './helper';
Expand Down Expand Up @@ -310,24 +304,24 @@ export class JestExt {
public triggerUpdateSettings(newSettings?: PluginResourceSettings): Promise<void> {
const updatedSettings =
newSettings ?? getExtensionResourceSettings(this.extContext.workspace.uri);
this.extContext = createJestExtContext(this.extContext.workspace, updatedSettings);

// debug
this.testResultProvider.verbose = updatedSettings.debugMode ?? false;

// coverage
const showCoverage = this.coverageOverlay.enabled ?? updatedSettings.showCoverageOnLoad;
this.coverageOverlay.dispose();
updatedSettings.showCoverageOnLoad = showCoverage;

this.coverageOverlay.dispose();
this.coverageOverlay = new CoverageOverlay(
this.vscodeContext,
this.coverageMapProvider,
updatedSettings.showCoverageOnLoad,
updatedSettings.coverageFormatter,
updatedSettings.coverageColors
);
this.extContext.runnerWorkspace.collectCoverage = showCoverage;
this.coverageOverlay.enabled = showCoverage;

this.extContext = createJestExtContext(this.extContext.workspace, updatedSettings);

return this.startSession(true);
}
Expand Down Expand Up @@ -415,7 +409,7 @@ export class JestExt {
}

//** commands */
public debugTests: DebugFunction = async (
public debugTests = async (
document: vscode.TextDocument | string,
...ids: DebugTestIdentifier[]
): Promise<void> => {
Expand All @@ -437,22 +431,23 @@ export class JestExt {
let testId: DebugTestIdentifier | undefined;
switch (ids.length) {
case 0:
return;
//no testId, will run all tests in the file
break;
case 1:
testId = ids[0];
break;
default:
testId = await selectTest(ids);
// if nothing is selected, abort
if (!testId) {
return;
}
break;
}

if (!testId) {
return;
}

this.debugConfigurationProvider.prepareTestRun(
typeof document === 'string' ? document : document.fileName,
escapeRegExp(idString('full-name', testId))
testId ? escapeRegExp(idString('full-name', testId)) : '.*'
);

const configs = vscode.workspace
Expand All @@ -463,12 +458,9 @@ export class JestExt {
configs?.find((c) => c.name === 'vscode-jest-tests');

if (!debugConfig) {
messaging.systemWarningMessage(
prefixWorkspace(
this.extContext,
'No debug config named "vscode-jest-tests.v2" or "vscode-jest-tests" found in launch.json, will use a default config.\nIf you encountered debugging problems, feel free to try the setup wizard below'
),
this.setupWizardAction('debugConfig')
this.logging(
'debug',
'No debug config named "vscode-jest-tests.v2" or "vscode-jest-tests" found in launch.json, will use a default config.'
);
debugConfig = this.debugConfigurationProvider.provideDebugConfigurations(
this.extContext.workspace
Expand All @@ -484,13 +476,24 @@ export class JestExt {
}
} else {
const name = editor.document.fileName;
if (
this.processSession.scheduleProcess({
let pInfo;
if (this.testResultProvider.isTestFile(name) !== 'yes') {
// run related tests from source file
pInfo = this.processSession.scheduleProcess({
type: 'by-file',
testFileName: name,
notTestFile: this.testResultProvider.isTestFile(name) !== 'yes',
})
) {
notTestFile: true,
});
} else {
// note: use file-pattern instead of file-path to increase compatibility, such as for angular users.
// However, we should keep an eye on performance, as matching by pattern could be slower than by explicit path.
// If performance ever become an issue, we could consider optimization...
pInfo = this.processSession.scheduleProcess({
type: 'by-file-pattern',
testFileNamePattern: name,
});
}
if (pInfo) {
this.dirtyFiles.delete(name);
return;
}
Expand Down
33 changes: 18 additions & 15 deletions src/JestExt/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { AutoRunMode } from '../StatusBar';
import { pathToJest, pathToConfig, toFilePath } from '../helpers';
import { workspaceLogging } from '../logging';
import { AutoRunAccessor, JestExtContext } from './types';
import { AutoRunAccessor, JestExtContext, RunnerWorkspaceOptions } from './types';
import { CoverageColors } from '../Coverage';

export const isWatchRequest = (request: JestProcessRequest): boolean =>
Expand Down Expand Up @@ -83,23 +83,26 @@ export const createJestExtContext = (
workspaceFolder: vscode.WorkspaceFolder,
settings: PluginResourceSettings
): JestExtContext => {
const currentJestVersion = 20;
const [jestCommandLine, pathToConfig] = getJestCommandSettings(settings);
const runnerWorkspace = new ProjectWorkspace(
toFilePath(settings.rootPath),
jestCommandLine,
pathToConfig,
currentJestVersion,
workspaceFolder.name,
settings.showCoverageOnLoad,
settings.debugMode,
settings.nodeEnv,
settings.shell
);
const createRunnerWorkspace = (options?: RunnerWorkspaceOptions) => {
const ws = workspaceFolder.name;
const currentJestVersion = 20;
const [jestCommandLine, pathToConfig] = getJestCommandSettings(settings);
return new ProjectWorkspace(
toFilePath(settings.rootPath),
jestCommandLine,
pathToConfig,
currentJestVersion,
options?.outputFileSuffix ? `${ws}_${options.outputFileSuffix}` : ws,
options?.collectCoverage ?? settings.showCoverageOnLoad,
settings.debugMode,
settings.nodeEnv,
settings.shell
);
};
return {
workspace: workspaceFolder,
settings,
runnerWorkspace,
createRunnerWorkspace,
loggingFactory: workspaceLogging(workspaceFolder.name, settings.debugMode ?? false),
autoRun: AutoRun(settings),
};
Expand Down
34 changes: 24 additions & 10 deletions src/JestExt/process-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
requestString,
QueueType,
JestProcessInfo,
JestProcessRequestTransform,
} from '../JestProcessManagement';
import { JestTestProcessType } from '../Settings';
import { RunTestListener, ListTestFileListener } from './process-listeners';
Expand All @@ -24,6 +25,14 @@ export type InternalRequestBase =
};

export type JestExtRequestType = JestProcessRequestBase | InternalRequestBase;
const isJestProcessRequestBase = (request: JestExtRequestType): request is JestProcessRequestBase =>
// eslint-disable-next-line @typescript-eslint/no-explicit-any
typeof (request as any).transform === 'function';
const getTransform = (request: JestExtRequestType): JestProcessRequestTransform | undefined => {
if (isJestProcessRequestBase(request)) {
return request.transform;
}
};

const ProcessScheduleStrategy: Record<JestTestProcessType, ScheduleStrategy> = {
// abort if there is already an pending request
Expand All @@ -36,19 +45,19 @@ const ProcessScheduleStrategy: Record<JestTestProcessType, ScheduleStrategy> = {

// abort if there is already identical pending request
'by-file': {
queue: 'blocking',
queue: 'blocking-2',
dedup: { filterByStatus: ['pending'] },
},
'by-file-test': {
queue: 'blocking',
queue: 'blocking-2',
dedup: { filterByStatus: ['pending'], filterByContent: true },
},
'by-file-pattern': {
queue: 'blocking',
queue: 'blocking-2',
dedup: { filterByStatus: ['pending'] },
},
'by-file-test-pattern': {
queue: 'blocking',
queue: 'blocking-2',
dedup: { filterByStatus: ['pending'], filterByContent: true },
},
'not-test': {
Expand Down Expand Up @@ -130,6 +139,11 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes
};

const createProcessRequest = (request: JestExtRequestType): JestProcessRequest => {
const transform = (pRequest: JestProcessRequest): JestProcessRequest => {
const t = getTransform(request);
return t ? t(pRequest) : pRequest;
};

const lSession = listenerSession;
switch (request.type) {
case 'all-tests':
Expand All @@ -140,11 +154,11 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes
case 'by-file-test':
case 'by-file-test-pattern': {
const schedule = ProcessScheduleStrategy[request.type];
return {
return transform({
...request,
listener: new RunTestListener(lSession),
schedule,
};
});
}
case 'update-snapshot': {
const snapshotRequest = createSnapshotRequest(request.baseRequest);
Expand All @@ -153,21 +167,21 @@ export const createProcessSession = (context: JestExtProcessContext): ProcessSes
queue: 'non-blocking' as QueueType,
};

return {
return transform({
...snapshotRequest,
listener: new RunTestListener(lSession),
schedule,
};
});
}
case 'list-test-files': {
const schedule = ProcessScheduleStrategy['not-test'];
return {
return transform({
...request,
type: 'not-test',
args: ['--listTests', '--json', '--watchAll=false'],
listener: new ListTestFileListener(lSession, request.onResult),
schedule,
};
});
}
}
throw new Error(`Unexpected process type ${request.type}`);
Expand Down
6 changes: 5 additions & 1 deletion src/JestExt/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ export interface AutoRunAccessor {
onStartup: OnStartupType | undefined;
mode: AutoRunMode;
}
export interface RunnerWorkspaceOptions {
outputFileSuffix?: string;
collectCoverage?: boolean;
}
export interface JestExtContext {
settings: PluginResourceSettings;
workspace: vscode.WorkspaceFolder;
runnerWorkspace: ProjectWorkspace;
loggingFactory: LoggingFactory;
autoRun: AutoRunAccessor;
createRunnerWorkspace: (options?: RunnerWorkspaceOptions) => ProjectWorkspace;
}

export interface JestExtSessionContext extends JestExtContext {
Expand Down
13 changes: 10 additions & 3 deletions src/JestProcessManagement/JestProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ export class JestProcess implements JestProcessInfo {
}
break;
case 'by-file': {
options.testFileNamePattern = this.quoteFileName(this.request.testFileName);
const fileName = this.quoteFileName(this.request.testFileName);
args.push('--watchAll=false');
if (this.request.notTestFile) {
args.push('--findRelatedTests');
args.push('--findRelatedTests', fileName);
} else {
options.testFileNamePattern = fileName;
args.push('--runTestsByPath');
}
if (this.request.updateSnapshot) {
args.push('--updateSnapshot');
Expand Down Expand Up @@ -167,7 +170,11 @@ export class JestProcess implements JestProcessInfo {
break;
}

const runner = new Runner(this.extContext.runnerWorkspace, options);
const runnerWorkspace = this.extContext.createRunnerWorkspace(
this.request.schedule.queue === 'blocking-2' ? { outputFileSuffix: '2' } : undefined
);

const runner = new Runner(runnerWorkspace, options);
this.registerListener(runner);

let taskInfo: Omit<RunnerTask, 'promise'>;
Expand Down
Loading

0 comments on commit 5251851

Please sign in to comment.