From a7a9b2d96434e3ab0e306aa1c5bf663ccab7df68 Mon Sep 17 00:00:00 2001 From: gjsjohnmurray Date: Thu, 25 Sep 2025 17:05:51 +0100 Subject: [PATCH] Document requirement for `coverage.list` file, and allow it at the top of `relativeTestRoot` --- README.md | 8 ++++++++ src/commonRunTestsHandler.ts | 11 ++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cfc4c3f..4f508e7 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,14 @@ For a workspace using client-side editing, test classes are by default sought in > By setting this at the workspace level you can have different file layouts for different projects. +To gather test coverage data you will need at least one `coverage.list` file in your tree of test classes. See the Test Coverage Tool documentation for information about what this file should contain. + +When using client-side editing your `coverage.list` file(s) must be in or below your `relativeTestRoot` client-side folder. + +When using server-side editing, put a single `coverage.list` file in the server-side folder named in your ^UnitTestRoot global. + +If no `coverage.list` file is found during a coverage run then the output in the Test Results tab of the VS Code Panel will include the line `No code coverage found (!)`. + ## Running Tests VS Code provides several different ways to run tests. diff --git a/src/commonRunTestsHandler.ts b/src/commonRunTestsHandler.ts index 4d98fa1..2b2a01b 100644 --- a/src/commonRunTestsHandler.ts +++ b/src/commonRunTestsHandler.ts @@ -204,7 +204,8 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r } } - // No longer rely on ISFS redirection of /.vscode because since ObjectScript v3.0 it no longer works for client-only workspaces. + // Form the ISFS target folder uri and delete any existing content + // Note that authority here is just server name, no :namespace const testRoot = vscode.Uri.from({ scheme: 'isfs', authority, path: `/_vscode/${namespace}/UnitTestRoot/${username}`, query: "csp&ns=%SYS" }); try { // Limitation of the Atelier API means this can only delete the files, not the folders @@ -214,7 +215,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r console.log(error); } - // Map of uri strings checked for presence of a coverage.list file, recording the relative path of those that were found + // Map of uri strings checked for presence of a coverage.list file, recording the absolute path of those that were found const mapCoverageLists = new Map(); for await (const mapInstance of mapTestClasses) { const key = mapInstance[0]; @@ -230,7 +231,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r if (['isfs', 'isfs-readonly'].includes(sourceBaseUri.scheme)) { continue; } - while (pathParts.length > 1) { + while (pathParts.length > 0) { const currentPath = pathParts.join('/'); // Check for coverage.list file here const coverageListUri = sourceBaseUri.with({ path: sourceBaseUri.path.concat(`${currentPath}/coverage.list`) }); @@ -240,7 +241,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r } try { await vscode.workspace.fs.stat(coverageListUri); - mapCoverageLists.set(coverageListUri.toString(), currentPath); + mapCoverageLists.set(coverageListUri.toString(), testRoot.path.concat(currentPath)); } catch (error) { if (error.code !== vscode.FileSystemError.FileNotFound().code) { console.log(`Error checking for ${coverageListUri.toString()}:`, error); @@ -255,7 +256,7 @@ export async function commonRunTestsHandler(controller: vscode.TestController, r if (path.length > 0) { const coverageListUri = vscode.Uri.parse(uriString, true); try { - await vscode.workspace.fs.copy(coverageListUri, testRoot.with({ path: testRoot.path.concat(`${path}/coverage.list`) })); + await vscode.workspace.fs.copy(coverageListUri, testRoot.with({ path: `${path}/coverage.list` })); } catch (error) { console.log(`Error copying ${coverageListUri.path}:`, error); }