From 4c1c674a418186dc8f52a7b9869a37f06f081c40 Mon Sep 17 00:00:00 2001 From: Anthony Leonardo Gracio Date: Fri, 22 Mar 2024 15:17:03 +0000 Subject: [PATCH 1/6] Add logging for didChangeConfiguration event And subscribe to this event before launching the ALS processes. For eng/ide/ada_language_server#1311 --- integration/vscode/ada/src/ExtensionState.ts | 8 ++++++++ integration/vscode/ada/src/extension.ts | 9 +++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/integration/vscode/ada/src/ExtensionState.ts b/integration/vscode/ada/src/ExtensionState.ts index e9843e057..ebb495147 100644 --- a/integration/vscode/ada/src/ExtensionState.ts +++ b/integration/vscode/ada/src/ExtensionState.ts @@ -8,6 +8,7 @@ import { initializeTesting } from './gnattest'; import { GprTaskProvider } from './gprTaskProvider'; import { TERMINAL_ENV_SETTING_NAME } from './helpers'; import { registerTaskProviders } from './taskProviders'; +import { logger } from './extension'; /** * This class encapsulates all state that should be maintained throughout the @@ -125,10 +126,13 @@ export class ExtensionState { // React to changes in configuration to recompute predefined tasks if the user // changes scenario variables' values. public configChanged = (e: vscode.ConfigurationChangeEvent) => { + logger.info('didChangeConfiguration event received'); + if ( e.affectsConfiguration('ada.scenarioVariables') || e.affectsConfiguration('ada.projectFile') ) { + logger.info('project related settings have changed: clearing caches for tasks'); this.clearALSCache(); this.unregisterTaskProviders(); this.registerTaskProviders(); @@ -138,6 +142,10 @@ export class ExtensionState { // a popup to reload the VS Code window and thus restart the // Ada extension. if (e.affectsConfiguration(TERMINAL_ENV_SETTING_NAME)) { + const new_value = vscode.workspace.getConfiguration().get(TERMINAL_ENV_SETTING_NAME); + logger.info(`${TERMINAL_ENV_SETTING_NAME} has changed: show reload popup`); + logger.info(`${TERMINAL_ENV_SETTING_NAME}: ${JSON.stringify(new_value, undefined, 2)}`); + void this.showReloadWindowPopup(); } }; diff --git a/integration/vscode/ada/src/extension.ts b/integration/vscode/ada/src/extension.ts index 9d6dbe311..b0d1d7559 100644 --- a/integration/vscode/ada/src/extension.ts +++ b/integration/vscode/ada/src/extension.ts @@ -140,6 +140,11 @@ async function activateExtension(context: vscode.ExtensionContext) { adaExtState = new ExtensionState(context); context.subscriptions.push(adaExtState); + // Subscribe to the didChangeConfiguration event + context.subscriptions.push( + vscode.workspace.onDidChangeConfiguration(adaExtState.configChanged) + ); + const alsMiddleware: Middleware = { executeCommand: alsCommandExecutor(adaExtState.adaClient), }; @@ -148,10 +153,6 @@ async function activateExtension(context: vscode.ExtensionContext) { await adaExtState.start(); - context.subscriptions.push( - vscode.workspace.onDidChangeConfiguration(adaExtState.configChanged) - ); - /** * Register commands first so that commands such as displaying the extension * Output become available even if the language servers fail to start. From 7f5bb5bcaa42ee201b2635943f8cd17a3ea42b03 Mon Sep 17 00:00:00 2001 From: Elie Richa Date: Fri, 22 Mar 2024 16:40:41 +0000 Subject: [PATCH 2/6] Migrate to debugging vscode tests from the vscode UI --- .vscode/launch.json | 104 ------------------------ .vscode/settings.json.tmpl | 7 ++ .vscode/tasks.json | 10 --- doc/HACKING.md | 2 +- integration/vscode/ada/.vscode-test.mjs | 7 +- 5 files changed, 14 insertions(+), 116 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a7ff0db85..2210805b4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -38,110 +38,6 @@ "PATH": "${env:PATH}" } }, - { - "name": "(vscode) Run testsuite 'general'", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "outFiles": [ - "${workspaceFolder}/integration/vscode/ada/out/**/*.js", - "!**/node_modules/**" - ], - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/integration/vscode/ada", - "--extensionTestsPath=${workspaceFolder}/integration/vscode/ada/out/test/suite/general/index", - "${workspaceFolder}/integration/vscode/ada/test/workspaces/general" - ], - // Below we make the executables of node modules visible to the tests. - // In particular, vscode-tmgrammar-snap is used for syntax highlighting - // tests. - "env": { - "MOCHA_GREP": "${input:testPattern}", - // This is necessary to make the "child" vscode inherit the PATH - // variable set in the workspace settings. Without it in some setups - // (e.g. vscode remote) the child vscode does not get visibility - // over the Ada toolchain available in the parent vscode - // environment. - "PATH": "${env:PATH}", - // This is custom env var that we use in - // integration/vscode/ada/test/suite/index.ts to prevent timeouts in - // tests when debugging - "MOCHA_TIMEOUT": "0", - "MOCHA_ALS_UPDATE": "${input:updateTestRefs}" - }, - "preLaunchTask": "npm: pretest - integration/vscode/ada", - "internalConsoleOptions": "openOnSessionStart" - }, - { - "name": "(vscode) Run testsuite 'gnattest'", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "outFiles": [ - "${workspaceFolder}/integration/vscode/ada/out/**/*.js", - "!**/node_modules/**" - ], - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/integration/vscode/ada", - "--extensionTestsPath=${workspaceFolder}/integration/vscode/ada/out/test/suite/gnattest/index", - "${workspaceFolder}/integration/vscode/ada/test/workspaces/gnattest" - ], - // Below we make the executables of node modules visible to the tests. - // In particular, vscode-tmgrammar-snap is used for syntax highlighting - // tests. - "env": { - "MOCHA_GREP": "${input:testPattern}", - // This is necessary to make the "child" vscode inherit the PATH - // variable set in the workspace settings. Without it in some setups - // (e.g. vscode remote) the child vscode does not get visibility - // over the Ada toolchain available in the parent vscode - // environment. - "PATH": "${env:PATH}", - // This is custom env var that we use in - // integration/vscode/ada/test/suite/index.ts to prevent timeouts in - // tests when debugging - "MOCHA_TIMEOUT": "0", - "MOCHA_ALS_UPDATE": "${input:updateTestRefs}" - }, - "preLaunchTask": "npm: pretest - integration/vscode/ada", - // Switch to Debug Console to see test results - "internalConsoleOptions": "openOnSessionStart" - }, - { - "name": "(vscode) Run testsuite 'workspace_missing_dirs'", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "outFiles": [ - "${workspaceFolder}/integration/vscode/ada/out/**/*.js", - "!**/node_modules/**" - ], - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}/integration/vscode/ada", - "--extensionTestsPath=${workspaceFolder}/integration/vscode/ada/out/test/suite/workspace_missing_dirs/index", - "${workspaceFolder}/integration/vscode/ada/test/workspaces/workspace_missing_dirs" - ], - // Below we make the executables of node modules visible to the tests. - // In particular, vscode-tmgrammar-snap is used for syntax highlighting - // tests. - "env": { - "MOCHA_GREP": "${input:testPattern}", - // This is necessary to make the "child" vscode inherit the PATH - // variable set in the workspace settings. Without it in some setups - // (e.g. vscode remote) the child vscode does not get visibility - // over the Ada toolchain available in the parent vscode - // environment. - "PATH": "${env:PATH}", - // This is custom env var that we use in - // integration/vscode/ada/test/suite/index.ts to prevent timeouts in - // tests when debugging - "MOCHA_TIMEOUT": "0", - "MOCHA_ALS_UPDATE": "${input:updateTestRefs}" - }, - "preLaunchTask": "npm: pretest - integration/vscode/ada", - // Switch to Debug Console to see test results - "internalConsoleOptions": "openOnSessionStart" - }, { "name": "(npm) Launch all vscode tests with npm", "type": "node", diff --git a/.vscode/settings.json.tmpl b/.vscode/settings.json.tmpl index bec9ca153..9abce6387 100644 --- a/.vscode/settings.json.tmpl +++ b/.vscode/settings.json.tmpl @@ -93,5 +93,12 @@ "suite": ["describe", "suite"], "test": ["it", "test"], "extractWith": "syntax" + }, + "extension-test-runner.debugOptions": { + "outFiles": [ + "${workspaceFolder}/integration/vscode/ada/out/**/*.js", + "!**/node_modules/**" + ], + "preLaunchTask": "npm: watch - integration/vscode/ada" } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index a08ae67dd..892357edc 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -45,16 +45,6 @@ "clear": true } }, - { - "type": "npm", - "script": "watch", - "path": "integration/vscode/ada", - "group": "build", - "problemMatcher": ["$tsc-watch"], - "label": "npm: watch - integration/vscode/ada", - "detail": "node ./node_modules/typescript/bin/tsc -watch", - "isBackground": true - }, { "type": "ada", "configuration": { diff --git a/doc/HACKING.md b/doc/HACKING.md index 1c2df3881..1e57578ac 100644 --- a/doc/HACKING.md +++ b/doc/HACKING.md @@ -144,7 +144,7 @@ Run `make vscode-test` to run the VS Code testsuite. If you open the ALS repository in VS Code, it is also possible to run VS Code integration tests using the Testing view. The `integration/vscode/ada/.vscode-test.mjs` contains a configuration allowing to load the tests in the Testing view. -The UI offers ways to run all or a subset of the tests. +The UI offers ways to run or debug one test, a subset of tests or all tests. ### Other tests diff --git a/integration/vscode/ada/.vscode-test.mjs b/integration/vscode/ada/.vscode-test.mjs index 3a5d36d5a..976c77c67 100644 --- a/integration/vscode/ada/.vscode-test.mjs +++ b/integration/vscode/ada/.vscode-test.mjs @@ -78,7 +78,12 @@ export default defineConfig( // now. A workaround is to remove this line. DISPLAY: ':99', }, - launchArgs: ['--user-data-dir', tmpdir], + launchArgs: [ + // It's important to use the --user-data-dir= form. The + // --user-data-dir form sometimes gets considered + // as another workspace root directory. + `--user-data-dir=${tmpdir}`, + ], // Use external installation if provided in the VSCODE env variable useInstallation: process.env.VSCODE ? { fromPath: process.env.VSCODE } : undefined, }; From 664e1458441221ae972e23424c6a098e04be2f8e Mon Sep 17 00:00:00 2001 From: Elie Richa Date: Mon, 18 Mar 2024 11:48:14 +0000 Subject: [PATCH 3/6] Make TS linting apply to test code as well --- integration/vscode/ada/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/vscode/ada/package.json b/integration/vscode/ada/package.json index b0f30a6f1..4ba980d13 100644 --- a/integration/vscode/ada/package.json +++ b/integration/vscode/ada/package.json @@ -881,8 +881,8 @@ "compile": "node ./node_modules/typescript/bin/tsc", "watch": "node ./node_modules/typescript/bin/tsc -watch", "pretest": "npm run compile", - "lint": "eslint \"./src/**/*.{js,ts,tsx}\" --quiet --fix", - "cilint": "eslint \"./src/**/*.{js,ts,tsx}\"", + "lint": "eslint \"./src/**/*.{js,ts,tsx}\" \"./test/**/*.{js,ts,tsx}\" --quiet --fix", + "cilint": "eslint \"./src/**/*.{js,ts,tsx}\" \"./test/**/*.{js,ts,tsx}\"", "test": "vscode-test", "resolve-backtrace": "npx stacktracify", "clean": "node -e \"fs.rmSync('out',{force:true,recursive:true})\"" From 7d9776449f46432bbe60dedb741e2df40536d07b Mon Sep 17 00:00:00 2001 From: Elie Richa Date: Tue, 5 Mar 2024 10:41:03 +0000 Subject: [PATCH 4/6] Implement tests for the GNATtest integration --- integration/vscode/ada/src/gnattest.ts | 20 +- integration/vscode/ada/src/taskProviders.ts | 4 +- .../ada/test/suite/gnattest/gnattest.test.ts | 404 ++++++++++++++++++ 3 files changed, 416 insertions(+), 12 deletions(-) diff --git a/integration/vscode/ada/src/gnattest.ts b/integration/vscode/ada/src/gnattest.ts index 89d9a8fe3..14499e33c 100644 --- a/integration/vscode/ada/src/gnattest.ts +++ b/integration/vscode/ada/src/gnattest.ts @@ -123,7 +123,7 @@ export function initializeTesting(context: vscode.ExtensionContext): vscode.Test /** * Reset and recreate the tree of TestItems based on the GNATtest XML. */ -async function refreshTestItemTree() { +export async function refreshTestItemTree() { controller.items.replace([]); testData.clear(); await addTestsRootLevel(); @@ -142,7 +142,7 @@ async function getGnatTestXmlPath(): Promise { * * @returns the full path to the GNATtest test driver GPR project. */ -async function getGnatTestDriverProjectPath(): Promise { +export async function getGnatTestDriverProjectPath(): Promise { const objDir = await getObjectDir(); const testDriverPath = path.join(objDir, 'gnattest', 'harness', 'test_driver.gpr'); return testDriverPath; @@ -152,7 +152,7 @@ async function getGnatTestDriverProjectPath(): Promise { * * @returns the full path to the GNATtest test driver executable. */ -async function getGnatTestDriverExecPath(): Promise { +export async function getGnatTestDriverExecPath(): Promise { const objDir = await getObjectDir(); const testDriverPath = path.join(objDir, 'gnattest', 'harness', 'test_runner' + exe); return testDriverPath; @@ -399,7 +399,7 @@ export function pathIsReadable(p: string): boolean { * @param item - the TestItem whose children must be computed, or `undefined` if * we should compute the root items of the tree. */ -async function resolveHandler( +export async function resolveHandler( item: TestItem | undefined, recursive = false, token?: CancellationToken @@ -470,7 +470,7 @@ function configureTestExecution(controller: vscode.TestController) { * @param request - the request based on the User selections * @param token - a cancellation token */ -async function runHandler(request: vscode.TestRunRequest, token: vscode.CancellationToken) { +export async function runHandler(request: vscode.TestRunRequest, token?: vscode.CancellationToken) { if ((request.include?.length ?? 0) === 0 && (request.exclude?.length ?? 0) === 0) { /** * Run all tests. This ignores request.exclude which is why we only use @@ -490,7 +490,7 @@ async function runHandler(request: vscode.TestRunRequest, token: vscode.Cancella * controller.items) and request.exclude. It then runs the test driver for each * test, using the --routines argument at each run to select a specific test. */ -async function handleRunRequestedTests(request: vscode.TestRunRequest, token: CancellationToken) { +async function handleRunRequestedTests(request: vscode.TestRunRequest, token?: CancellationToken) { const run = controller.createTestRun(request, undefined, false); try { const requestedRootTests = []; @@ -580,7 +580,7 @@ function prepareAndAppendOutput(run: vscode.TestRun, out: string) { * in {@link handleRunRequestedTests} fails because of GNATtest shortcomings, we * still have this approach of running all tests as a backup. */ -async function handleRunAll(request: vscode.TestRunRequest, token: CancellationToken) { +async function handleRunAll(request: vscode.TestRunRequest, token?: CancellationToken) { const run = controller.createTestRun(request, undefined, false); try { /** @@ -687,7 +687,7 @@ async function buildTestDriver(run: vscode.TestRun) { * @param duration - the duration of execution of the test to be reported along * with the outcome, if the information is available. */ -function determineTestOutcome( +export function determineTestOutcome( test: vscode.TestItem, driverOutput: string, run: vscode.TestRun, @@ -763,7 +763,7 @@ function determineTestOutcome( * @param token - a cancellation token to stop the traversal * @returns the array of leaf TestItems reachable from the given collection. */ -function collectLeafsFromCollection( +export function collectLeafsFromCollection( items: vscode.TestItemCollection, token?: CancellationToken ): vscode.TestItem[] { @@ -783,7 +783,7 @@ function collectLeafsFromCollection( * @param token - a cancellation token to stop the traversal * @returns the array of leaf TestItems reachable from the given TestItem */ -function collectLeafItems(item: TestItem, token?: CancellationToken): vscode.TestItem[] { +export function collectLeafItems(item: TestItem, token?: CancellationToken): vscode.TestItem[] { if (item.children.size > 0) { const res: vscode.TestItem[] = []; item.children.forEach((i) => { diff --git a/integration/vscode/ada/src/taskProviders.ts b/integration/vscode/ada/src/taskProviders.ts index 63bbc2512..4154f2b03 100644 --- a/integration/vscode/ada/src/taskProviders.ts +++ b/integration/vscode/ada/src/taskProviders.ts @@ -18,9 +18,9 @@ import assert from 'assert'; import commandExists from 'command-exists'; import * as vscode from 'vscode'; -import { adaExtState, logger } from './extension'; -import { AdaMain, getAdaMains, getProjectFile, getSymbols } from './helpers'; import { SymbolKind } from 'vscode'; +import { adaExtState } from './extension'; +import { AdaMain, getAdaMains, getProjectFile, getSymbols } from './helpers'; export const ADA_TASK_TYPE = 'ada'; diff --git a/integration/vscode/ada/test/suite/gnattest/gnattest.test.ts b/integration/vscode/ada/test/suite/gnattest/gnattest.test.ts index 3d395253f..a984f7269 100644 --- a/integration/vscode/ada/test/suite/gnattest/gnattest.test.ts +++ b/integration/vscode/ada/test/suite/gnattest/gnattest.test.ts @@ -1,7 +1,411 @@ +/* eslint-disable @typescript-eslint/restrict-template-expressions */ +/* eslint-disable max-len */ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +import assert from 'assert'; +import { spawnSync } from 'child_process'; +import { + anything, + capture, + instance, + mock, + reset, + resetCalls, + spy, + verify, + when, +} from 'ts-mockito'; +import { TestController, TestItem, TestItemCollection, TestMessage, TestRun } from 'vscode'; +import { adaExtState } from '../../../src/extension'; +import { + collectLeafItems, + collectLeafsFromCollection, + controller, + determineTestOutcome, + getGnatTestDriverExecPath, + getGnatTestDriverProjectPath, + refreshTestItemTree, + resolveHandler, + runHandler, +} from '../../../src/gnattest'; import { activate } from '../utils'; suite('GNATtest Integration Tests', function () { this.beforeAll(async () => { await activate(); + const cmd = ['gnattest', '-P', await adaExtState.getProjectFile()]; + const cp = spawnSync(cmd[0], cmd.slice(1)); + if (cp.status != 0) { + assert.fail( + `'${cmd.join(' ')}' had status code ${cp.status} and output:\n + ${cp.stdout.toLocaleString()}\n${cp.stderr.toLocaleString()}` + ); + } + }); + + test('Resolving tests', async () => { + /** + * First initialization of the test tree + */ + await refreshTestItemTree(); + + /** + * Check initial test list + */ + assert.equal( + getTestTree(controller), + ` +[speed1.ads] +[speed2.ads] +`.trim() + ); + + /** + * Resolve one item and check the outcome + */ + await resolveHandler(controller.items.get('speed2.ads')); + assert.equal( + getTestTree(controller), + ` +[speed1.ads] +[speed2.ads] + [Desired_Speed 10:13] + [Set_Desired_Speed 12:14] + [Adjust_Speed 16:14] +`.trim() + ); + + /** + * Now perform recursive resolution of the same node. + */ + await resolveHandler(controller.items.get('speed2.ads'), true); + assert.equal( + getTestTree(controller), + ` +[speed1.ads] +[speed2.ads] + [Desired_Speed 10:13] + [speed2.ads:10] + [Set_Desired_Speed 12:14] + [speed2.ads:12] + [Adjust_Speed 16:14] + [speed2.ads:16] +`.trim() + ); + + /** + * Now resolve all nodes recursively + */ + await resolveAllTestTree(); + assert.equal( + getTestTree(controller), + ` +[speed1.ads] + [Speed 12:13] + [speed1.ads:12] + [Adjust_Speed 13:14] + [speed1.ads:13] +[speed2.ads] + [Desired_Speed 10:13] + [speed2.ads:10] + [Set_Desired_Speed 12:14] + [speed2.ads:12] + [Adjust_Speed 16:14] + [speed2.ads:16] +`.trim() + ); + }); + + /** + * This tests the choice of IDs and labels for tests in vscode + */ + test('IDs and labels', async () => { + /** + * Resolve all nodes recursively + * + * Even though column information is available in the GNATtest XML, only + * line information is include in test IDs. So a test ID recognized by + * GNATtest is :. + */ + await resolveAllTestTree(); + assert.equal( + getTestTree(controller, (item) => `[${item.id}] ${item.label}`), + ` +[speed1.ads] Tests for speed1.ads + [Speed 12:13] Tests for subprogram Speed + [speed1.ads:12] speed1.ads:12 + [Adjust_Speed 13:14] Tests for subprogram Adjust_Speed + [speed1.ads:13] speed1.ads:13 +[speed2.ads] Tests for speed2.ads + [Desired_Speed 10:13] Tests for subprogram Desired_Speed + [speed2.ads:10] speed2.ads:10 + [Set_Desired_Speed 12:14] Tests for subprogram Set_Desired_Speed + [speed2.ads:12] speed2.ads:12 + [Adjust_Speed 16:14] Tests for subprogram Adjust_Speed + [speed2.ads:16] speed2.ads:16 +`.trim() + ); + }); + + test('Getting leaf tests to run', async () => { + /** + * Resolve the entire tree + */ + await resolveAllTestTree(); + + /** + * Test on second item + */ + const speed2Item = controller.items.get('speed2.ads') as TestItem; + assert.equal( + testItemArrayToStr(collectLeafItems(speed2Item)), + ` +[speed2.ads:10] +[speed2.ads:12] +[speed2.ads:16] +`.trim() + ); + + /** + * Test on all items + */ + assert.equal( + testItemArrayToStr(collectLeafsFromCollection(controller.items)), + ` +[speed1.ads:12] +[speed1.ads:13] +[speed2.ads:10] +[speed2.ads:12] +[speed2.ads:16] +`.trim() + ); + }); + + test('Parsing test results', async () => { + /** + * Resolve the entire test tree + */ + await resolveAllTestTree(); + + /** + * Consider one of the existing tests + */ + const testItem = collectLeafsFromCollection(controller.items)[0]; + + /** + * Create dummy pass and fail test driver outputs + */ + const driverOutputSuccess = ` +foo +bar +${testItem.id}:4: info: corresponding test PASSED +foo +bar +`.trim(); + const driverOutputFail = ` +foo +bar +${testItem.id}:4: error: some test failure message +foo +bar +`.trim(); + + /** + * Create a mock of the TestRun object to test for specific methods + * being called. + */ + // The mock object keeps track of method calls. + const mockRun = mock(); + // The mock instance should be passed to the implementation. + const run: TestRun = instance(mockRun); + + /** + * Test that parsing a success message causes the passed() method to be + * called + */ + determineTestOutcome(testItem, driverOutputSuccess, run); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.passed(testItem, anything())).once(); + + /** + * Test that parsing a failure message causes the failed() method to be + * called + */ + resetCalls(mockRun); + determineTestOutcome(testItem, driverOutputFail, run); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.failed(testItem, anything(), anything())).once(); + /** + * Now capture the arguments of the call to failed and check that the + * test failure message was stored correctly. + */ + // eslint-disable-next-line max-len + // eslint-disable-next-line @typescript-eslint/unbound-method, @typescript-eslint/no-unused-vars + const msg = capture(mockRun.failed).last()[1]; + if (msg instanceof TestMessage) { + assert.equal(msg.message, `${testItem.id}:4: error: some test failure message`); + } else { + throw Error('Could not verify expected message'); + } + + /** + * Test that when no messages concerning the test are found, the test is + * marked as errored. + */ + resetCalls(mockRun); + determineTestOutcome(testItem, 'No output about the test', run); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.errored(testItem, anything(), anything())).once(); + + /** + * Multiple pass messages should result in an error + */ + resetCalls(mockRun); + determineTestOutcome(testItem, driverOutputSuccess + driverOutputSuccess, run); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.errored(testItem, anything(), anything())).once(); + + /** + * Multiple fail messages should result in an error + */ + resetCalls(mockRun); + determineTestOutcome(testItem, driverOutputFail + driverOutputFail + driverOutputFail, run); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.errored(testItem, anything(), anything())).once(); + + /** + * Both pass and fail messages should result in an error + */ + resetCalls(mockRun); + determineTestOutcome( + testItem, + driverOutputFail + driverOutputSuccess + driverOutputFail, + run + ); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + verify(mockRun.errored(testItem, anything(), anything())).once(); + }); + + test('Running tests', async () => { + /** + * Set up a spy on the test controller to stub some methods + */ + const spyCtrl = spy(controller); + try { + /** + * Create a mock TestRun + */ + const mockRun = mock(); + /** + * Capture the output by stubbing the appendOutput() method + */ + let outputs = ''; + when(mockRun.appendOutput(anything())).thenCall((output: string) => { + /** + * Remove '\\r's from the console outputs for easier comparison + */ + outputs += output.replace(/\r\n/g, '\n'); + }); + const run = instance(mockRun); + + /** + * Install a stub in the test controller spy to return the TestRun mock + */ + when(spyCtrl.createTestRun(anything(), anything(), anything())).thenReturn(run); + + /** + * Call the run handler with a request for running all tests. + */ + await runHandler( + { include: undefined, exclude: undefined, profile: undefined }, + undefined + ); + + /** + * Since the gprbuild output can change depending on whether a + * previous test run has already executed gprbuild, we don't check + * for it verbatim. Instead we check that the gprbuild command line + * was called, and that the test driver was called and gave the + * expected output. + */ + const buildOutput = ` +Building the test harness project +$ "gprbuild" "-P" "${await getGnatTestDriverProjectPath()}" +`.trimStart(); + const runOutput = ` +Running the test driver +$ "${await getGnatTestDriverExecPath()}" "--passed-tests=show" +speed1.ads:12:4: info: corresponding test PASSED +speed1.ads:13:4: info: corresponding test PASSED +speed2.ads:12:4: info: corresponding test PASSED +speed2.ads:16:4: info: corresponding test PASSED +speed1.ads:12:4: inherited at speed2.ads:20:4: info: corresponding test PASSED +speed2.ads:10:4: error: corresponding test FAILED: Test not implemented. (speed2-auto_controller_test_data-auto_controller_tests.adb:46) +6 tests run: 5 passed; 1 failed; 0 crashed. +`.trimStart(); + assert.ok(outputs.includes(buildOutput)); + assert.ok(outputs.includes(runOutput)); + + /** + * Check that calling the run handler with an empty include array + * also yields an execution of all tests. + */ + outputs = ''; + await runHandler({ include: [], exclude: undefined, profile: undefined }, undefined); + assert.ok(outputs.includes(buildOutput)); + assert.ok(outputs.includes(runOutput)); + } finally { + /** + * Reset the controller object on which we set a spy + */ + reset(spyCtrl); + } }); }); + +async function resolveAllTestTree() { + const promises: Promise[] = []; + controller.items.forEach((item) => promises.push(resolveHandler(item, true))); + await Promise.all(promises); +} + +function getTestTree( + ctrl: TestController, + testItemToStr: (item: TestItem) => string = defaultTestItemToStr +): string { + return testItemCollToStr(ctrl.items, testItemToStr); +} + +function testItemArrayToStr( + items: TestItem[], + testItemToStr: (items: TestItem) => string = defaultTestItemToStr +): string { + return items.map((item) => itemWithChildrenToStr(item, testItemToStr)).join('\n'); +} + +function testItemCollToStr( + col: TestItemCollection, + testItemToStr: (item: TestItem) => string = defaultTestItemToStr +) { + let res = ''; + col.forEach((item) => { + res += '\n' + itemWithChildrenToStr(item, testItemToStr); + }); + return res.trim(); +} + +function itemWithChildrenToStr(item: TestItem, testItemToStr: (item: TestItem) => string) { + let res = testItemToStr(item); + + if (item.children.size > 0) { + res += '\n' + indentString(testItemCollToStr(item.children, testItemToStr), 2); + } + + return res; +} + +function defaultTestItemToStr(item: TestItem) { + return `[${item.id}]`; +} + +const indentString = (str: string, count: number, indent = ' ') => + str.replace(/^/gm, indent.repeat(count)); From 9cb5edee93e23be6d384d1a010afa9c710f48bfa Mon Sep 17 00:00:00 2001 From: Elie Richa Date: Thu, 21 Mar 2024 17:53:33 +0000 Subject: [PATCH 5/6] Track test files in the gnattest integration testsuite --- ...-controller_test_data-controller_tests.adb | 126 ++++++++++++++++++ ...-controller_test_data-controller_tests.ads | 19 +++ .../tests/speed1-controller_test_data.adb | 19 +++ .../tests/speed1-controller_test_data.ads | 25 ++++ .../gnattest/tests/speed1-test_data-tests.ads | 2 + .../obj/gnattest/tests/speed1-test_data.ads | 2 + ...roller_test_data-auto_controller_tests.adb | 109 +++++++++++++++ ...roller_test_data-auto_controller_tests.ads | 22 +++ .../speed2-auto_controller_test_data.adb | 22 +++ .../speed2-auto_controller_test_data.ads | 21 +++ .../gnattest/tests/speed2-test_data-tests.ads | 2 + .../obj/gnattest/tests/speed2-test_data.ads | 2 + .../workspaces/gnattest/result.txt.expected | 7 - 13 files changed, 371 insertions(+), 7 deletions(-) create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.adb create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.adb create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data-tests.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.adb create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.adb create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data-tests.ads create mode 100644 integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data.ads delete mode 100644 integration/vscode/ada/test/workspaces/gnattest/result.txt.expected diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.adb b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.adb new file mode 100644 index 000000000..dd91887fc --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.adb @@ -0,0 +1,126 @@ +-- This package has been generated automatically by GNATtest. +-- You are allowed to add your code to the bodies of test routines. +-- Such changes will be kept during further regeneration of this file. +-- All code placed outside of test routine bodies will be lost. The +-- code intended to set up and tear down the test environment should be +-- placed into Speed1.Controller_Test_Data. + +with AUnit.Assertions; use AUnit.Assertions; +with System.Assertions; + +-- begin read only +-- id:2.2/00/ +-- +-- This section can be used to add with clauses if necessary. +-- +-- end read only + +-- begin read only +-- end read only +package body Speed1.Controller_Test_Data.Controller_Tests is + +-- begin read only +-- id:2.2/01/ +-- +-- This section can be used to add global variables and other elements. +-- +-- end read only + +-- begin read only +-- end read only + +-- begin read only + procedure Test_Speed (Gnattest_T : in out Test_Controller); + procedure Test_Speed_bdc804 (Gnattest_T : in out Test_Controller) renames Test_Speed; +-- id:2.2/bdc8045e732efa1b/Speed/1/0/ + procedure Test_Speed (Gnattest_T : in out Test_Controller) is + -- speed1.ads:12:4:Speed +-- end read only + + pragma Unreferenced (Gnattest_T); + + begin + + null; + -- AUnit.Assertions.Assert + -- (Gnattest_Generated.Default_Assert_Value, + -- "Test not implemented."); + +-- begin read only + end Test_Speed; +-- end read only + + +-- begin read only + procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller); + procedure Test_Adjust_Speed_6fd48f (Gnattest_T : in out Test_Controller) renames Test_Adjust_Speed; +-- id:2.2/6fd48ff933c1edff/Adjust_Speed/1/0/ + procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller) is + -- speed1.ads:13:4:Adjust_Speed +-- end read only + + pragma Unreferenced (Gnattest_T); + + begin + + null; + -- delay 5.0; + -- AUnit.Assertions.Assert + -- (Adjust_Speed (), + -- "Test not implemented."); + +-- begin read only + end Test_Adjust_Speed; +-- end read only + + +-- begin read only + -- procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller); + -- procedure Test_Adjust_Speed_cea401 (Gnattest_T : in out Test_Controller) renames Test_Adjust_Speed; +-- id:2.2/cea4013b78a4a615/Adjust_Speed/0/1/ + -- procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller) is +-- end read only +-- +-- pragma Unreferenced (Gnattest_T); +-- +-- begin +-- +-- AUnit.Assertions.Assert +-- (Gnattest_Generated.Default_Assert_Value, +-- "Test not implemented."); +-- +-- begin read only + -- end Test_Adjust_Speed; +-- end read only + + +-- begin read only + -- procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller); + -- procedure Test_Adjust_Speed_d4219e (Gnattest_T : in out Test_Controller) renames Test_Adjust_Speed; +-- id:2.2/d4219e26c5c99d2c/Adjust_Speed/0/1/ + -- procedure Test_Adjust_Speed (Gnattest_T : in out Test_Controller) is +-- end read only +-- +-- pragma Unreferenced (Gnattest_T); +-- +-- begin +-- +-- AUnit.Assertions.Assert +-- (Gnattest_Generated.Default_Assert_Value, +-- "Test not implemented."); +-- +-- begin read only + -- end Test_Adjust_Speed; +-- end read only + +-- begin read only +-- id:2.2/02/ +-- +-- This section can be used to add elaboration code for the global state. +-- +begin +-- end read only + null; +-- begin read only +-- end read only +end Speed1.Controller_Test_Data.Controller_Tests; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.ads new file mode 100644 index 000000000..c2bc6ade5 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data-controller_tests.ads @@ -0,0 +1,19 @@ +-- This package has been generated automatically by GNATtest. +-- Do not edit any part of it, see GNATtest documentation for more details. + +-- begin read only +with GNATtest_Generated; + +package Speed1.Controller_Test_Data.Controller_Tests is + + type Test_Controller is new + GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Test_Controller with null record; + + procedure Test_Speed_bdc804 (Gnattest_T : in out Test_Controller); + -- speed1.ads:12:4:Speed + + procedure Test_Adjust_Speed_6fd48f (Gnattest_T : in out Test_Controller); + -- speed1.ads:13:4:Adjust_Speed + +end Speed1.Controller_Test_Data.Controller_Tests; +-- end read only diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.adb b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.adb new file mode 100644 index 000000000..0b49e2ec5 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.adb @@ -0,0 +1,19 @@ +-- This package is intended to set up and tear down the test environment. +-- Once created by GNATtest, this package will never be overwritten +-- automatically. Contents of this package can be modified in any way +-- except for sections surrounded by a 'read only' marker. + +package body Speed1.Controller_Test_Data is + + Local_Controller : aliased GNATtest_Generated.GNATtest_Standard.Speed1.Controller; + procedure Set_Up (Gnattest_T : in out Test_Controller) is + begin + Gnattest_T.Fixture := Local_Controller'Access; + end Set_Up; + + procedure Tear_Down (Gnattest_T : in out Test_Controller) is + begin + null; + end Tear_Down; + +end Speed1.Controller_Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.ads new file mode 100644 index 000000000..4fe8f9161 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-controller_test_data.ads @@ -0,0 +1,25 @@ +-- This package is intended to set up and tear down the test environment. +-- Once created by GNATtest, this package will never be overwritten +-- automatically. Contents of this package can be modified in any way +-- except for sections surrounded by a 'read only' marker. + + +with AUnit.Test_Fixtures; + +with GNATtest_Generated; + +package Speed1.Controller_Test_Data is + + type Controller_Access is access all GNATtest_Generated.GNATtest_Standard.Speed1.Controller'Class; + +-- begin read only + type Test_Controller is new AUnit.Test_Fixtures.Test_Fixture +-- end read only + with record + Fixture : Controller_Access; + end record; + + procedure Set_Up (Gnattest_T : in out Test_Controller); + procedure Tear_Down (Gnattest_T : in out Test_Controller); + +end Speed1.Controller_Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data-tests.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data-tests.ads new file mode 100644 index 000000000..c0bfa5a9d --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data-tests.ads @@ -0,0 +1,2 @@ +package Speed1.Test_Data.Tests is +end Speed1.Test_Data.Tests; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data.ads new file mode 100644 index 000000000..15dbe63ad --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed1-test_data.ads @@ -0,0 +1,2 @@ +package Speed1.Test_Data is +end Speed1.Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.adb b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.adb new file mode 100644 index 000000000..59158f8cc --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.adb @@ -0,0 +1,109 @@ +-- This package has been generated automatically by GNATtest. +-- You are allowed to add your code to the bodies of test routines. +-- Such changes will be kept during further regeneration of this file. +-- All code placed outside of test routine bodies will be lost. The +-- code intended to set up and tear down the test environment should be +-- placed into Speed2.Auto_Controller_Test_Data. + +with AUnit.Assertions; use AUnit.Assertions; +with System.Assertions; + +-- begin read only +-- id:2.2/00/ +-- +-- This section can be used to add with clauses if necessary. +-- +-- end read only + +-- begin read only +-- end read only +package body Speed2.Auto_Controller_Test_Data.Auto_Controller_Tests is + +-- begin read only +-- id:2.2/01/ +-- +-- This section can be used to add global variables and other elements. +-- +-- end read only + +-- begin read only +-- end read only + +-- begin read only + procedure Test_Desired_Speed (Gnattest_T : in out Test_Auto_Controller); + procedure Test_Desired_Speed_3a9813 (Gnattest_T : in out Test_Auto_Controller) renames Test_Desired_Speed; +-- id:2.2/3a98136ae8d1ca89/Desired_Speed/1/0/ + procedure Test_Desired_Speed (Gnattest_T : in out Test_Auto_Controller) is + -- speed2.ads:10:4:Desired_Speed +-- end read only + + pragma Unreferenced (Gnattest_T); + + begin + + null; + -- delay 10.0; + AUnit.Assertions.Assert + (Gnattest_Generated.Default_Assert_Value, + "Test not implemented."); + +-- begin read only + end Test_Desired_Speed; +-- end read only + + +-- begin read only + procedure Test_Set_Desired_Speed (Gnattest_T : in out Test_Auto_Controller); + procedure Test_Set_Desired_Speed_42cd33 (Gnattest_T : in out Test_Auto_Controller) renames Test_Set_Desired_Speed; +-- id:2.2/42cd33c8ea29e2bf/Set_Desired_Speed/1/0/ + procedure Test_Set_Desired_Speed (Gnattest_T : in out Test_Auto_Controller) is + -- speed2.ads:12:4:Set_Desired_Speed +-- end read only + + pragma Unreferenced (Gnattest_T); + + begin + + null; + -- delay 4.0; + -- AUnit.Assertions.Assert + -- (Gnattest_Generated.Default_Assert_Value, + -- "Test not implemented."); + +-- begin read only + end Test_Set_Desired_Speed; +-- end read only + + +-- begin read only + procedure Test_Adjust_Speed (Gnattest_T : in out Test_Auto_Controller); + procedure Test_Adjust_Speed_6fd48f (Gnattest_T : in out Test_Auto_Controller) renames Test_Adjust_Speed; +-- id:2.2/6fd48ff933c1edff/Adjust_Speed/1/0/ + procedure Test_Adjust_Speed (Gnattest_T : in out Test_Auto_Controller) is + -- speed2.ads:16:4:Adjust_Speed +-- end read only + + pragma Unreferenced (Gnattest_T); + + begin + + null; + -- AUnit.Assertions.Assert + -- (Gnattest_Generated.Default_Assert_Value, + -- "Test not implemented."); + +-- begin read only + end Test_Adjust_Speed; +-- end read only + +-- begin read only +-- id:2.2/02/ +-- +-- This section can be used to add elaboration code for the global state. +-- +begin +-- end read only + null; +-- begin read only +-- end read only +end Speed2.Auto_Controller_Test_Data.Auto_Controller_Tests; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.ads new file mode 100644 index 000000000..b5ce17f1e --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data-auto_controller_tests.ads @@ -0,0 +1,22 @@ +-- This package has been generated automatically by GNATtest. +-- Do not edit any part of it, see GNATtest documentation for more details. + +-- begin read only +with GNATtest_Generated; + +package Speed2.Auto_Controller_Test_Data.Auto_Controller_Tests is + + type Test_Auto_Controller is new + GNATtest_Generated.GNATtest_Standard.Speed2.Auto_Controller_Test_Data.Test_Auto_Controller with null record; + + procedure Test_Desired_Speed_3a9813 (Gnattest_T : in out Test_Auto_Controller); + -- speed2.ads:10:4:Desired_Speed + + procedure Test_Set_Desired_Speed_42cd33 (Gnattest_T : in out Test_Auto_Controller); + -- speed2.ads:12:4:Set_Desired_Speed + + procedure Test_Adjust_Speed_6fd48f (Gnattest_T : in out Test_Auto_Controller); + -- speed2.ads:16:4:Adjust_Speed + +end Speed2.Auto_Controller_Test_Data.Auto_Controller_Tests; +-- end read only diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.adb b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.adb new file mode 100644 index 000000000..44bbc8de7 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.adb @@ -0,0 +1,22 @@ +-- This package is intended to set up and tear down the test environment. +-- Once created by GNATtest, this package will never be overwritten +-- automatically. Contents of this package can be modified in any way +-- except for sections surrounded by a 'read only' marker. + +package body Speed2.Auto_Controller_Test_Data is + + Local_Auto_Controller : aliased GNATtest_Generated.GNATtest_Standard.Speed2.Auto_Controller; + procedure Set_Up (Gnattest_T : in out Test_Auto_Controller) is + begin + GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Controller_Tests.Set_Up + (GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Controller_Tests.Test_Controller (Gnattest_T)); + Gnattest_T.Fixture := Local_Auto_Controller'Access; + end Set_Up; + + procedure Tear_Down (Gnattest_T : in out Test_Auto_Controller) is + begin + GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Controller_Tests.Tear_Down + (GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Controller_Tests.Test_Controller (Gnattest_T)); + end Tear_Down; + +end Speed2.Auto_Controller_Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.ads new file mode 100644 index 000000000..36e7ef615 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-auto_controller_test_data.ads @@ -0,0 +1,21 @@ +-- This package is intended to set up and tear down the test environment. +-- Once created by GNATtest, this package will never be overwritten +-- automatically. Contents of this package can be modified in any way +-- except for sections surrounded by a 'read only' marker. + +with Speed1.Controller_Test_Data.Controller_Tests; + +with GNATtest_Generated; + +package Speed2.Auto_Controller_Test_Data is + +-- begin read only + type Test_Auto_Controller is new + GNATtest_Generated.GNATtest_Standard.Speed1.Controller_Test_Data.Controller_Tests.Test_Controller +-- end read only + with null record; + + procedure Set_Up (Gnattest_T : in out Test_Auto_Controller); + procedure Tear_Down (Gnattest_T : in out Test_Auto_Controller); + +end Speed2.Auto_Controller_Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data-tests.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data-tests.ads new file mode 100644 index 000000000..309580fbe --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data-tests.ads @@ -0,0 +1,2 @@ +package Speed2.Test_Data.Tests is +end Speed2.Test_Data.Tests; diff --git a/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data.ads b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data.ads new file mode 100644 index 000000000..ac09bb4ef --- /dev/null +++ b/integration/vscode/ada/test/workspaces/gnattest/obj/gnattest/tests/speed2-test_data.ads @@ -0,0 +1,2 @@ +package Speed2.Test_Data is +end Speed2.Test_Data; diff --git a/integration/vscode/ada/test/workspaces/gnattest/result.txt.expected b/integration/vscode/ada/test/workspaces/gnattest/result.txt.expected deleted file mode 100644 index 10bc779f5..000000000 --- a/integration/vscode/ada/test/workspaces/gnattest/result.txt.expected +++ /dev/null @@ -1,7 +0,0 @@ -speed1.ads:12:4: error: corresponding test FAILED: Test not implemented. (speed1-controller_test_data-controller_tests.adb:44) -speed1.ads:13:4: error: corresponding test FAILED: Test not implemented. (speed1-controller_test_data-controller_tests.adb:65) -speed2.ads:10:4: error: corresponding test FAILED: Test not implemented. (speed2-auto_controller_test_data-auto_controller_tests.adb:44) -speed2.ads:12:4: error: corresponding test FAILED: Test not implemented. (speed2-auto_controller_test_data-auto_controller_tests.adb:65) -speed2.ads:16:4: error: corresponding test FAILED: Test not implemented. (speed2-auto_controller_test_data-auto_controller_tests.adb:86) -speed1.ads:12:4: inherited at speed2.ads:20:4: error: corresponding test FAILED: Test not implemented. (speed1-controller_test_data-controller_tests.adb:44) -6 tests run: 0 passed; 6 failed; 0 crashed. From 15ec6a0c85d91d3c38e7178a17de3cdcc6e8f001 Mon Sep 17 00:00:00 2001 From: Anthony Leonardo Gracio Date: Fri, 15 Mar 2024 14:42:38 +0000 Subject: [PATCH 6/6] Prepend './' to the executable's relative path when needed This is needed when we want to run the executable from a shell, in case there is no path separator in its relative path (e.g: when there is no custom object directory). For eng/ide/ada_language_server#1305 --- integration/vscode/ada/src/taskProviders.ts | 12 ++++++-- .../ada/test/suite/general/tasks.test.ts | 29 +++++++++++++++++++ .../default_without_obj_dir.gpr | 18 ++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 integration/vscode/ada/test/workspaces/general/default_without_obj_dir/default_without_obj_dir.gpr diff --git a/integration/vscode/ada/src/taskProviders.ts b/integration/vscode/ada/src/taskProviders.ts index 4154f2b03..68edd44b9 100644 --- a/integration/vscode/ada/src/taskProviders.ts +++ b/integration/vscode/ada/src/taskProviders.ts @@ -21,6 +21,7 @@ import * as vscode from 'vscode'; import { SymbolKind } from 'vscode'; import { adaExtState } from './extension'; import { AdaMain, getAdaMains, getProjectFile, getSymbols } from './helpers'; +import path from 'path'; export const ADA_TASK_TYPE = 'ada'; @@ -691,8 +692,15 @@ async function buildFullCommandLine( if (taskDef.configuration.kind == 'runMain') { if (adaMain) { - // Append the run of the main executable - cmd.push(adaMain.execRelPath()); + // Append the main executable's relative path, prepending './' + // (or '.\\' on Windows) when needed, to make sure it's executable from + // a shell. + let execRelPath = adaMain.execRelPath(); + if (!execRelPath.includes(path.sep)) { + execRelPath = '.' + path.sep + execRelPath; + } + + cmd.push(execRelPath); if (taskDef.configuration.mainArgs) { cmd = cmd.concat(taskDef.configuration.mainArgs); } diff --git a/integration/vscode/ada/test/suite/general/tasks.test.ts b/integration/vscode/ada/test/suite/general/tasks.test.ts index eb02c1976..8206f608a 100644 --- a/integration/vscode/ada/test/suite/general/tasks.test.ts +++ b/integration/vscode/ada/test/suite/general/tasks.test.ts @@ -11,6 +11,7 @@ import { getSelectedRegion, } from '../../../src/taskProviders'; import { activate } from '../utils'; +import path from 'path'; suite('GPR Tasks Provider', function () { let projectPath: string; @@ -244,6 +245,34 @@ ada: Build and run main - src/test.adb - kind: buildAndRunMain`.trim(); assert.equal(execStatus, 0); }); + /** + * Check that the 'buildAndRunMain' task works fine with projects that + * do not explicitly define an object directory. + */ + test('buildAndRunMain task without object directory', async () => { + // Load a custom project that does not define any object dir by + // changing the 'ada.projectFile' setting. + const initialProjectFile = vscode.workspace.getConfiguration().get('ada.projectFile'); + try { + await vscode.workspace + .getConfiguration() + .update( + 'ada.projectFile', + 'default_without_obj_dir' + path.sep + 'default_without_obj_dir.gpr' + ); + const adaTasks = await vscode.tasks.fetchTasks({ type: 'ada' }); + const task = adaTasks.find((v) => v.name == 'Build and run main - src/main1.adb'); + assert(task); + + // Check that the executable has been ran correctly + const execStatus: number | undefined = await runTaskAndGetResult(task); + assert.equal(execStatus, 0); + } finally { + // Reset the 'ada.projectFile' setting. + await vscode.workspace.getConfiguration().update('ada.projectFile', initialProjectFile); + } + }); + /** * Test that buildAndRunMain fails when configured with non-existing tasks */ diff --git a/integration/vscode/ada/test/workspaces/general/default_without_obj_dir/default_without_obj_dir.gpr b/integration/vscode/ada/test/workspaces/general/default_without_obj_dir/default_without_obj_dir.gpr new file mode 100644 index 000000000..607f6e091 --- /dev/null +++ b/integration/vscode/ada/test/workspaces/general/default_without_obj_dir/default_without_obj_dir.gpr @@ -0,0 +1,18 @@ +project Default_Without_Obj_Dir is + + Tools_Mains := + ("main1.adb", + "test.adb"); + + for Source_Dirs use ("../src/**"); + for Main use Tools_Mains; + + package Builder is + for Executable ("main1.adb") use "main1exec"; + end Builder; + + package Compiler is + for Default_Switches ("Ada") use ("-g", "-O0"); + end Compiler; + +end Default_Without_Obj_Dir;