Skip to content

Commit d297070

Browse files
committed
Make e3-testsuite integration automatically use common locations
1 parent c541993 commit d297070

File tree

3 files changed

+101
-13
lines changed

3 files changed

+101
-13
lines changed

integration/vscode/ada/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,8 +718,7 @@
718718
"properties": {
719719
"e3-testsuite.testsuitePath": {
720720
"type": "string",
721-
"description": "Path to testsuite.py",
722-
"default": "testsuite.py"
721+
"description": "Path to testsuite.py"
723722
},
724723
"e3-testsuite.python": {
725724
"type": "string",

integration/vscode/ada/src/e3Testsuite.ts

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,19 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
8282

8383
const testData: Map<vscode.TestItem, TestInfo> = new Map();
8484

85+
const ts: Testsuite = getTestsuite();
8586
let rootItem: vscode.TestItem;
87+
8688
controller.refreshHandler = async function () {
8789
controller.items.replace([]);
8890
testData.clear();
8991

90-
const ts: Testsuite = getTestsuite();
91-
9292
if (!existsSync(ts.uri.fsPath)) {
9393
return;
9494
}
9595

9696
rootItem = this.createTestItem(
97-
getRootItemId(),
97+
getRootItemId(ts),
9898
vscode.workspace.asRelativePath(ts.uri),
9999
ts.uri,
100100
);
@@ -179,8 +179,6 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
179179
request: vscode.TestRunRequest,
180180
token: vscode.CancellationToken,
181181
): Promise<void> => {
182-
const ts = getTestsuite();
183-
184182
const enableEventSystem: boolean =
185183
vscode.workspace.getConfiguration('e3-testsuite').get('enableEventSystem') ?? true;
186184

@@ -193,7 +191,7 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
193191
}
194192

195193
function onlyRootSelected(rq: vscode.TestRunRequest) {
196-
return rq.include?.length === 1 && rq.include[0].id === getRootItemId();
194+
return rq.include?.length === 1 && rq.include[0].id === getRootItemId(ts);
197195
}
198196

199197
if (request.include && !onlyRootSelected(request)) {
@@ -536,7 +534,7 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
536534
reportResult(run, result.status, targetItem, messages);
537535
}
538536

539-
if (existsSync(getTestsuite().uri.fsPath)) {
537+
if (existsSync(ts.uri.fsPath)) {
540538
void vscode.window.withProgress(
541539
{
542540
location: vscode.ProgressLocation.Notification,
@@ -551,13 +549,47 @@ export function activateE3TestsuiteIntegration(context: vscode.ExtensionContext)
551549
}
552550
}
553551

554-
function getRootItemId(): string {
555-
return getTestsuite().uri.toString();
552+
function getRootItemId(ts: Testsuite): string {
553+
return ts.uri.toString();
556554
}
557555

558-
function getTestsuite() {
556+
/**
557+
* Retrieves the testsuite configuration for the current workspace.
558+
*
559+
* This function determines the testsuite path by first checking the user's configuration.
560+
* If no path is configured, it automatically searches through predefined candidate locations
561+
* and uses the first existing file. It also retrieves the Python executable configuration.
562+
*
563+
* @returns {Testsuite} An object containing the testsuite URI and Python executable path
564+
*
565+
* @remarks
566+
* The function searches for testsuite files in the following order:
567+
* 1. 'testsuite.py' in the workspace root
568+
* 2. 'testsuite/testsuite.py' relative to workspace root
569+
*
570+
* If no testsuite file is found, it defaults to the first candidate path.
571+
* The Python executable defaults to 'python' if not configured.
572+
*
573+
* @throws Will throw an error if no workspace folders are available
574+
*/
575+
export function getTestsuite() {
576+
const wsPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
577+
559578
const config = vscode.workspace.getConfiguration('e3-testsuite');
560-
const tsPath = config.get<string>('testsuitePath') ?? 'testsuite.py';
579+
const configuredPath = config.get<string>('testsuitePath');
580+
581+
let tsPath;
582+
if (configuredPath) {
583+
tsPath = configuredPath;
584+
} else {
585+
/**
586+
* Automatically look through candidates and return the first one that exists.
587+
*/
588+
const candidates = ['testsuite.py', path.join('testsuite', 'testsuite.py')];
589+
tsPath =
590+
candidates.map((p) => path.join(wsPath, p)).find((p) => existsSync(p)) ?? candidates[0];
591+
}
592+
561593
const python = config.get<string>('python') ?? 'python';
562594

563595
const tsAbsUri: vscode.Uri = path.isAbsolute(tsPath)

integration/vscode/ada/test/e3-testsuite/e3_testsuite.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
import { CancellationTokenSource } from 'vscode-languageclient';
1515
import * as e3 from '../../src/e3Testsuite';
1616
import { activate } from '../utils';
17+
import fs from 'fs';
1718

1819
/**
1920
* Interface for capturing test execution results
@@ -514,6 +515,62 @@ suite('e3-testsuite', function () {
514515
await config.update('args', originalArgs, false);
515516
}
516517
});
518+
519+
test('Auto-detect testsuite.py path', function () {
520+
const config = workspace.getConfiguration('e3-testsuite');
521+
const originalPath = config.get<string>('testsuitePath');
522+
523+
try {
524+
// Clear any configured path to test auto-detection
525+
config.update('testsuitePath', undefined, false);
526+
527+
const detectedPath = e3.getTestsuite().uri.fsPath;
528+
const expectedPath = path.join(
529+
workspace.workspaceFolders![0].uri.fsPath,
530+
'testsuite.py',
531+
);
532+
533+
assert.strictEqual(
534+
detectedPath,
535+
expectedPath,
536+
`Auto-detected path '${detectedPath}' does not match expected '${expectedPath}'`,
537+
);
538+
539+
// Test with testsuite.py in a subdirectory
540+
const originalTestsuitePath = path.join(
541+
workspace.workspaceFolders![0].uri.fsPath,
542+
'testsuite.py',
543+
);
544+
const subDirPath = path.join(workspace.workspaceFolders![0].uri.fsPath, 'testsuite');
545+
const movedTestsuitePath = path.join(subDirPath, 'testsuite.py');
546+
547+
// Create subdirectory and move testsuite.py
548+
fs.mkdirSync(subDirPath, { recursive: true });
549+
fs.renameSync(originalTestsuitePath, movedTestsuitePath);
550+
551+
try {
552+
const detectedPathInSubdir = e3.getTestsuite().uri.fsPath;
553+
assert.strictEqual(
554+
detectedPathInSubdir,
555+
movedTestsuitePath,
556+
`Auto-detected path '${detectedPathInSubdir}' does not match ` +
557+
`expected '${movedTestsuitePath}'`,
558+
);
559+
} finally {
560+
// Move testsuite.py back to original location
561+
fs.renameSync(movedTestsuitePath, originalTestsuitePath);
562+
// Clean up the subdirectory if it's empty
563+
try {
564+
fs.rmdirSync(subDirPath);
565+
} catch {
566+
// Ignore if directory is not empty or doesn't exist
567+
}
568+
}
569+
} finally {
570+
// Restore original configuration
571+
config.update('testsuitePath', originalPath, false);
572+
}
573+
});
517574
});
518575

519576
interface TestResultItem {

0 commit comments

Comments
 (0)