Skip to content

Commit

Permalink
Merge d172a5f into d3865e2
Browse files Browse the repository at this point in the history
  • Loading branch information
connectdotz committed Nov 28, 2022
2 parents d3865e2 + d172a5f commit 87fb2c4
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 344 deletions.
6 changes: 6 additions & 0 deletions __mocks__/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ const EventEmitter = jest.fn().mockImplementation(() => {
};
});

const QuickPickItemKind = {
Separator: -1,
Default: 0,
};

export = {
CodeLens,
languages,
Expand All @@ -118,4 +123,5 @@ export = {
TestMessage,
TestRunRequest,
ViewColumn,
QuickPickItemKind,
};
230 changes: 94 additions & 136 deletions src/setup-wizard/tasks/setup-jest-cmdline.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import * as path from 'path';
/**
* setup rootPath and jestCommandLine
*/
import * as vscode from 'vscode';

import {
showActionInputBox,
showActionMessage,
getConfirmation,
showActionMenu,
jsonOut,
actionItem,
getWizardSettings,
createSaveConfig,
validateCommandLine,
selectWorkspace,
toActionButton,
validateRootPath,
} from '../wizard-helper';
import { WizardStatus, ActionableMenuItem, SetupTask, WizardContext } from '../types';
import { ansiEsc } from '../../JestExt/output-terminal';

export const CLSetupActionId = {
acceptExisting: 0,
edit: 1,
upgrade: 2,
info: 3,
editInvalidCmdLine: 4,
acceptInvalidCmdLine: 5,
jestCommandLine: 0,
rootPath: 1,
editJestCommandLine: 2,
editRootPath: 3,
saveSettings: 4,
separator: 10,
};

export const setupJestCmdLine: SetupTask = async (
Expand All @@ -37,156 +37,114 @@ export const setupJestCmdLine: SetupTask = async (
const saveConfig = createSaveConfig(context);
const settings = getWizardSettings(workspace);

const handleInvalidCmdLine = async (
cmdLine: string,
msg: string,
editAction: (value: string) => Promise<WizardStatus>,
acceptAction: (value: string) => Promise<WizardStatus>
): Promise<WizardStatus> => {
message(`found invalid command line: "${cmdLine}"`);
return showActionMessage(
'warning',
msg,
{
id: CLSetupActionId.editInvalidCmdLine,
title: 'Yes',
isCloseAffordance: true,
action: () => editAction(cmdLine),
},
{
id: CLSetupActionId.acceptInvalidCmdLine,
title: 'No',
isCloseAffordance: false,
action: () => acceptAction(cmdLine),
}
);
};
const save = async (cmdLine: string): Promise<WizardStatus> => {
const save = async (): Promise<WizardStatus> => {
await saveConfig({
name: `jest.jestCommandLine`,
value: path.normalize(cmdLine),
value: settings.jestCommandLine,
});
message(`jestCommandLine saved: ${settings.jestCommand}`);
await saveConfig({
name: `jest.rootPath`,
value: settings.rootPath,
});
message(`rootPath saved: ${settings.rootPath}`);

message(`settings updated: jestCommandLine=${cmdLine}`);

return 'success';
return 'exit';
};

const edit = async (cmdLine?: string): Promise<WizardStatus> => {
let editedValue = await showActionInputBox({
const editJestCmdLine = async (): Promise<WizardStatus> => {
const editedValue = await showActionInputBox<string>({
title: 'Enter Jest Command Line',
value: cmdLine,
value: settings.jestCommandLine,
prompt: 'Note: the command line should match how you run jest tests in terminal ',
enableBackButton: true,
verbose: context.verbose,
});
editedValue = editedValue?.trim();
if (!editedValue) {
message(
`jest command line did not change: jest.jestCommandLine = ${
settings.jestCommandLine ? `"${settings.jestCommandLine}"` : settings.jestCommandLine
}`
);
return 'abort';
}
const error = validateCommandLine(editedValue);
if (error) {
return handleInvalidCmdLine(
editedValue,
`Invalid command line:\n"${error}"\n\nDo you want to change it?`,
edit,
save
);
}
message(`=> jest command line updated: "${editedValue}"`);
return save(editedValue);
settings.jestCommandLine = editedValue;
return 'success';
};
const editRootPath = async (): Promise<WizardStatus> => {
const editedValue = await showActionInputBox<string>({
title: 'Enter Root Path (if different from workspace root)',
value: settings.rootPath,
prompt: 'the directory to start jest command',
enableBackButton: true,
verbose: context.verbose,
});
settings.rootPath = editedValue;
return 'success';
};

const withExistingSettings = async (): Promise<WizardStatus> => {
message(`found existing setting:\n${jsonOut(settings)}\n`);

const editJestCmdLineButton = toActionButton(
CLSetupActionId.editJestCommandLine,
'edit',
'edit jestCommandLine',
() => editJestCmdLine()
);
const editRootPathButton = toActionButton(
CLSetupActionId.editRootPath,
'edit',
'edit rootPath',
() => editRootPath()
);
const showMenu = async (): Promise<WizardStatus> => {
const menuItems: ActionableMenuItem<WizardStatus>[] = [];
let placeholder: string;

if (settings.jestCommandLine) {
const error = validateCommandLine(settings.jestCommandLine);
if (error) {
return handleInvalidCmdLine(
settings.jestCommandLine,
`Existing jestCommandLine might be invalid: "${error}".\n\nDo you want to change it?`,
edit,
() => Promise.resolve('success')
message(
`jestCommandLine "${settings.jestCommandLine}" is not valid:\r\n ${error}`,
'error'
);
settings.jestCommandLine = undefined;
}
}
if (settings.rootPath) {
if (!validateRootPath(workspace, settings.rootPath)) {
message(`rootPath "${settings.rootPath}" is not valid:\r\n`, 'error');
settings.rootPath = undefined;
}
const value = settings.jestCommandLine;
placeholder = 'found existing "jestCommandLine"';
menuItems.push(
actionItem(
CLSetupActionId.acceptExisting,
'$(check) Use current jestCommandLine',
`jest.jestCommandLine=${value}`,
() => Promise.resolve('success')
),
actionItem(
CLSetupActionId.edit,
'$(edit) Edit command line',
`manually change the command line "${value}"`,
() => edit(value)
)
);
} else if (settings.pathToJest) {
const configPath = settings['pathToConfig'];
const configArg = configPath ? ` --config ${configPath}` : '';
const settingName = configPath ? 'jest.pathToJest, jest.pathToConfig' : 'jest.pathToJest';
const value = `${settings['pathToJest']}${configArg}`;
placeholder = `upgrade deprecated ${settingName} to jestCommandLine`;
message(
ansiEsc(
'warn',
'!!! "jestToPath" and "pathToConfig" are deprecated, it is replaced by "jest.jestCommandLine"'
),
'new-line'
);
menuItems.push(
actionItem(
CLSetupActionId.upgrade,
`Upgrade existing ${settingName}`,
`set jest.jestCommandLine="${value}"`,
() => edit(value)
)
);
} else {
console.error('no expected settings found in ', settings);
throw new Error('no expected settings found, should not be here');
}

return showActionMenu<WizardStatus>(menuItems, {
title: 'Set up Jest Command Line',
placeholder,
menuItems.push(
{
id: CLSetupActionId.jestCommandLine,
label: `${settings.rootPath}`,
detail: 'rootPath: the directory to start jest test from, if differ from workspace root',
buttons: [editRootPathButton],
},
{
id: CLSetupActionId.jestCommandLine,
label: `${settings.jestCommandLine}`,
detail: 'jestCommandLine: the command to start jest test',
buttons: [editJestCmdLineButton],
},
{
id: CLSetupActionId.separator,
kind: vscode.QuickPickItemKind.Separator,
label: '',
},
{
id: CLSetupActionId.saveSettings,
label: `$(settings-gear) Save Settings`,
detail: 'save the settings above and exit',
action: save,
}
);

const menuStatus = await showActionMenu<WizardStatus>(menuItems, {
title: 'Set up Jest Command Line and Root Path',
placeholder: 'update rootPath and jestCommandLine settings below',
enableBackButton: true,
verbose: context.verbose,
allowNoAction: true,
});
};
const withoutExistingSettings = async (): Promise<WizardStatus> => {
const canRun = await getConfirmation(
'info',
'Are you able to run jest tests from the terminal ?',
'Yes',
'No',
'no'
);
if (!canRun) {
// abort the wizard
const msg =
'Looks like you are not able to run jest tests from terminal...\r\n\r\n' +
'Please note a working jest test env is a prerequisite for vscode-jest. Feel free to relaunch the setup-tool when you are ready';
message(msg, 'error');
return 'abort';
if (menuStatus !== 'success') {
return menuStatus;
}
return edit();
return showMenu();
};

return settings.jestCommandLine || settings.pathToJest
? withExistingSettings()
: withoutExistingSettings();
return showMenu();
};
6 changes: 5 additions & 1 deletion src/setup-wizard/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as vscode from 'vscode';
import { JestExtOutput } from '../JestExt/output-terminal';
import { JestExtAutoRunSetting } from '../Settings';

export interface WizardContext {
debugConfigProvider: vscode.DebugConfigurationProvider;
Expand All @@ -13,7 +14,7 @@ export type WizardStatus = 'success' | 'error' | 'abort' | 'exit' | undefined;
export type WizardAction<T> = () => Promise<T>;
interface ActionableComp<T> {
id: number;
action: WizardAction<T>;
action?: WizardAction<T>;
}
export type ActionableMenuItem<T = WizardStatus> = vscode.QuickPickItem & ActionableComp<T>;
export type ActionableButton<T = WizardStatus> = vscode.QuickInputButton & ActionableComp<T>;
Expand All @@ -37,6 +38,8 @@ export interface ActionMenuOptions<T = WizardStatus> extends AllowBackButton, Ve
value?: string;
rightButtons?: ActionableButton<T>[];
selectItemIdx?: number;
// if true, treat action item/button without action as no-op; otherwise exit with "undefined"
allowNoAction?: boolean;
}

// actionable input box
Expand All @@ -58,6 +61,7 @@ type JestSettingKey = typeof JestSettings[number];
// prettier-ignore
export type WizardSettings =
{ [key in JestSettingKey]?: string } &
{ ['autoRun']?: JestExtAutoRunSetting} &
{ ['configurations']?: vscode.DebugConfiguration[] } &
{ ['absoluteRootPath']?: string };

Expand Down

0 comments on commit 87fb2c4

Please sign in to comment.