Skip to content

Commit

Permalink
Add a command copilot calls back to ensure testing is set up (#24128)
Browse files Browse the repository at this point in the history
  • Loading branch information
connor4312 authored Sep 19, 2024
1 parent 3fcb3fa commit cac5bb2
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 1 deletion.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"onDebugInitialConfigurations",
"onLanguage:python",
"onDebugResolve:python",
"onCommand:python.copilotSetupTests",
"workspaceContains:mspythonconfig.json",
"workspaceContains:pyproject.toml",
"workspaceContains:Pipfile",
Expand Down Expand Up @@ -1517,6 +1518,11 @@
}
]
},
"copilot": {
"tests": {
"getSetupConfirmation": "python.copilotSetupTests"
}
},
"scripts": {
"package": "gulp clean && gulp prePublishBundle && vsce package -o ms-python-insiders.vsix",
"prePublish": "gulp clean && gulp prePublishNonBundle",
Expand Down
1 change: 1 addition & 0 deletions src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
[Commands.Exec_In_Terminal_Icon]: [undefined, Uri];
[Commands.Debug_In_Terminal]: [Uri];
[Commands.Tests_Configure]: [undefined, undefined | CommandSource, undefined | Uri];
[Commands.Tests_CopilotSetup]: [undefined | Uri];
[Commands.LaunchTensorBoard]: [TensorBoardEntrypoint, TensorBoardEntrypointTrigger];
['workbench.view.testing.focus']: [];
['cursorMove']: [
Expand Down
1 change: 1 addition & 0 deletions src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export namespace Commands {
export const Start_REPL = 'python.startREPL';
export const Start_Native_REPL = 'python.startNativeREPL';
export const Tests_Configure = 'python.configureTests';
export const Tests_CopilotSetup = 'python.copilotSetupTests';
export const TriggerEnvironmentSelection = 'python.triggerEnvSelection';
export const ViewOutput = 'python.viewOutput';
}
Expand Down
1 change: 1 addition & 0 deletions src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ export namespace Testing {
export const errorUnittestExecution = l10n.t('Unittest test execution error');
export const cancelPytestExecution = l10n.t('Canceled pytest test execution');
export const errorPytestExecution = l10n.t('pytest test execution error');
export const copilotSetupMessage = l10n.t('Confirm your Python testing framework to enable test discovery.');
}

export namespace OutdatedDebugger {
Expand Down
1 change: 1 addition & 0 deletions src/client/testing/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export interface ITestsHelper {

export const ITestConfigurationService = Symbol('ITestConfigurationService');
export interface ITestConfigurationService {
hasConfiguredTests(wkspace: Uri): boolean;
displayTestFrameworkError(wkspace: Uri): Promise<void>;
selectTestRunner(placeHolderMessage: string): Promise<UnitTestProduct | undefined>;
enableTest(wkspace: Uri, product: UnitTestProduct): Promise<void>;
Expand Down
5 changes: 5 additions & 0 deletions src/client/testing/configuration/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ export class UnitTestConfigurationService implements ITestConfigurationService {
this.workspaceService = serviceContainer.get<IWorkspaceService>(IWorkspaceService);
}

public hasConfiguredTests(wkspace: Uri): boolean {
const settings = this.configurationService.getSettings(wkspace);
return settings.testing.pytestEnabled || settings.testing.unittestEnabled || false;
}

public async displayTestFrameworkError(wkspace: Uri): Promise<void> {
const settings = this.configurationService.getSettings(wkspace);
let enabledCount = settings.testing.pytestEnabled ? 1 : 0;
Expand Down
27 changes: 26 additions & 1 deletion src/client/testing/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

import { inject, injectable } from 'inversify';
import { ConfigurationChangeEvent, Disposable, Uri, tests, TestResultState, WorkspaceFolder } from 'vscode';
import { ConfigurationChangeEvent, Disposable, Uri, tests, TestResultState, WorkspaceFolder, Command } from 'vscode';
import { IApplicationShell, ICommandManager, IContextKeyManager, IWorkspaceService } from '../common/application/types';
import * as constants from '../common/constants';
import '../common/extensions';
Expand Down Expand Up @@ -170,6 +170,31 @@ export class UnitTestManagementService implements IExtensionActivationService {
this.testController?.refreshTestData(resource, { forceRefresh: true });
},
),
commandManager.registerCommand(constants.Commands.Tests_CopilotSetup, (resource?: Uri):
| { message: string; command: Command }
| undefined => {
const wkspaceFolder =
this.workspaceService.getWorkspaceFolder(resource) || this.workspaceService.workspaceFolders?.at(0);
if (!wkspaceFolder) {
return undefined;
}

const configurationService = this.serviceContainer.get<ITestConfigurationService>(
ITestConfigurationService,
);
if (configurationService.hasConfiguredTests(wkspaceFolder.uri)) {
return undefined;
}

return {
message: Testing.copilotSetupMessage,
command: {
title: Testing.configureTests,
command: constants.Commands.Tests_Configure,
arguments: [undefined, constants.CommandSource.ui, resource],
},
};
}),
);
}

Expand Down
9 changes: 9 additions & 0 deletions src/test/testing/configuration.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,15 @@ suite('Unit Tests - ConfigurationService', () => {
expect(selectedItem).to.be.equal(undefined, 'invalid value');
appShell.verifyAll();
});
test('Correctly returns hasConfiguredTests', () => {
let enabled = false;
unitTestSettings.setup((u) => u.unittestEnabled).returns(() => false);
unitTestSettings.setup((u) => u.pytestEnabled).returns(() => enabled);

expect(testConfigService.target.hasConfiguredTests(workspaceUri)).to.equal(false);
enabled = true;
expect(testConfigService.target.hasConfiguredTests(workspaceUri)).to.equal(true);
});
test('Prompt to enable a test if a test framework is not enabled', async () => {
unitTestSettings.setup((u) => u.pytestEnabled).returns(() => false);
unitTestSettings.setup((u) => u.unittestEnabled).returns(() => false);
Expand Down

0 comments on commit cac5bb2

Please sign in to comment.