@@ -9,11 +9,10 @@ import { CancellationToken } from 'vscode-languageclient';
99import { adaExtState } from './extension' ;
1010import { addCoverageData , GnatcovFileCoverage } from './gnatcov' ;
1111import { getScenarioArgs } from './gnatTaskProvider' ;
12- import { escapeRegExp , exe , getObjectDir , setTerminalEnvironment , slugify } from './helpers' ;
12+ import { escapeRegExp , exe , setTerminalEnvironment , slugify } from './helpers' ;
1313import {
1414 DEFAULT_PROBLEM_MATCHER ,
1515 findTaskByName ,
16- runTaskAndGetResult ,
1716 runTaskSequence ,
1817 SimpleTaskDef ,
1918 TASK_BUILD_TEST_DRIVER ,
@@ -160,19 +159,29 @@ export async function refreshTestItemTree() {
160159/**
161160 * @returns the full path to the GNATtest XML file.
162161 */
163- async function getGnatTestXmlPath ( ) : Promise < string > {
164- const objDir = await getObjectDir ( ) ;
165- const gnatTestXmlPath = path . join ( objDir , 'gnattest' , 'harness' , 'gnattest.xml' ) ;
162+ export async function getGnatTestXmlPath ( ) : Promise < string > {
163+ const gnatTestXmlPath = path . join ( await getHarnessDir ( ) , 'gnattest.xml' ) ;
166164 return gnatTestXmlPath ;
167165}
168166
167+ export async function getHarnessDir ( ) {
168+ return await adaExtState
169+ . getProjectAttributeValue ( 'Harness_Dir' , 'Gnattest' )
170+ . catch (
171+ /**
172+ * default to gnattest/harness if Harness_Dir is unspecified
173+ */
174+ ( ) => path . join ( 'gnattest' , 'harness' ) ,
175+ )
176+ . then ( async ( value ) => path . join ( await adaExtState . getObjectDir ( ) , value as string ) ) ;
177+ }
178+
169179/**
170180 *
171181 * @returns the full path to the GNATtest test driver GPR project.
172182 */
173183export async function getGnatTestDriverProjectPath ( ) : Promise < string > {
174- const objDir = await getObjectDir ( ) ;
175- const testDriverPath = path . join ( objDir , 'gnattest' , 'harness' , 'test_driver.gpr' ) ;
184+ const testDriverPath = path . join ( await getHarnessDir ( ) , 'test_driver.gpr' ) ;
176185 return testDriverPath ;
177186}
178187
@@ -181,11 +190,26 @@ export async function getGnatTestDriverProjectPath(): Promise<string> {
181190 * @returns the full path to the GNATtest test driver executable.
182191 */
183192export async function getGnatTestDriverExecPath ( ) : Promise < string > {
184- const objDir = await getObjectDir ( ) ;
185- const testDriverPath = path . join ( objDir , 'gnattest' , 'harness' , 'test_runner' + exe ) ;
193+ const testDriverPath = path . join ( await getHarnessDir ( ) , 'test_runner' + exe ) ;
186194 return testDriverPath ;
187195}
188196
197+ /**
198+ *
199+ * @returns path where GNATcoverage execution traces will be created during a test run
200+ */
201+ async function getTracesDir ( ) {
202+ return path . join ( await adaExtState . getVSCodeObjectSubdir ( ) , 'test-traces' ) ;
203+ }
204+
205+ /**
206+ *
207+ * @returns path where GNATcoverage report will be created after a test run
208+ */
209+ async function getGnatCovXMLReportDir ( ) {
210+ return path . join ( await adaExtState . getVSCodeObjectSubdir ( ) , 'cov-xml' ) ;
211+ }
212+
189213/**
190214 * Parse the GNATtest XML file and create the top-level TestItems in the test
191215 * controller for later lazy resolution.
@@ -330,6 +354,7 @@ async function addTestCaseItem(parentItem: vscode.TestItem, testCase: TestCase)
330354 const testFileBasename = test [ '@_file' ] ;
331355 const pos = new vscode . Position ( parseInt ( test [ '@_line' ] ) , parseInt ( test [ '@_column' ] ) - 1 ) ;
332356 const range = new vscode . Range ( pos , pos ) ;
357+
333358 const testUri = await findFileInWorkspace ( testFileBasename ) ;
334359
335360 // The name of the source file of the tested subprogram is not part of the
@@ -557,7 +582,16 @@ async function handleRunRequestedTests(
557582 requestedRootTests . push ( ...request . include ) ;
558583 } else {
559584 /**
560- * Consider all tests as included
585+ * If the Testing view hasn't been opened yet, the tests may not
586+ * have been loaded yet. Check for that and load the tests in that
587+ * case.
588+ */
589+ if ( controller . items . size == 0 ) {
590+ await refreshTestItemTree ( ) ;
591+ }
592+
593+ /**
594+ * Consider all tests as included.
561595 */
562596 controller . items . forEach ( ( i ) => requestedRootTests . push ( i ) ) ;
563597 }
@@ -606,7 +640,11 @@ async function handleRunRequestedTests(
606640 * Invoke the test driver for each test
607641 */
608642 const execPath = await getGnatTestDriverExecPath ( ) ;
609- const tracesDir = path . dirname ( execPath ) ;
643+ const tracesDir = await getTracesDir ( ) ;
644+
645+ if ( coverage ) {
646+ fs . mkdirSync ( tracesDir , { recursive : true } ) ;
647+ }
610648
611649 function getTracePath ( test : TestItem ) : string {
612650 return path . join ( tracesDir , slugify ( test . id ) + '.srctrace' ) ;
@@ -684,7 +722,7 @@ async function handleRunRequestedTests(
684722 /**
685723 * Produce a GNATcov XML report
686724 */
687- const outputDir = path . join ( await adaExtState . getObjectDir ( ) , 'cov-xml' ) ;
725+ const outputDir = await getGnatCovXMLReportDir ( ) ;
688726 const adaTP = adaExtState . getAdaTaskProvider ( ) ! ;
689727 const gnatcovReportTask = ( await adaTP . resolveTask (
690728 new vscode . Task (
@@ -708,7 +746,7 @@ async function handleRunRequestedTests(
708746 ) ,
709747 ) ) ! ;
710748 gnatcovReportTask . presentationOptions . reveal = vscode . TaskRevealKind . Never ;
711- const result = await runTaskAndGetResult ( gnatcovReportTask ) ;
749+ const result = await runTaskSequence ( [ gnatcovReportTask ] , new WriteEmitter ( run ) ) ;
712750 if ( result != 0 ) {
713751 const msg =
714752 `Error while running coverage analysis.` +
@@ -726,6 +764,20 @@ async function handleRunRequestedTests(
726764 }
727765}
728766
767+ /**
768+ * An EventEmitter that forwards data to a a TestRun given at construction
769+ * time.
770+ */
771+ class WriteEmitter extends vscode . EventEmitter < string > {
772+ constructor ( private run : vscode . TestRun ) {
773+ super ( ) ;
774+ }
775+
776+ override fire ( data : string ) : void {
777+ this . run . appendOutput ( data ) ;
778+ }
779+ }
780+
729781/**
730782 * Build the test driver and report build failure as errors on the tests
731783 * requested for execution.
@@ -739,12 +791,6 @@ async function buildTestDriverAndReportErrors(
739791 testsToRun : vscode . TestItem [ ] ,
740792 coverage : boolean ,
741793) {
742- class WriteEmitter extends vscode . EventEmitter < string > {
743- override fire ( data : string ) : void {
744- run . appendOutput ( data ) ;
745- }
746- }
747-
748794 const buildTasks = [ ] ;
749795 if ( coverage ) {
750796 const adaTP = adaExtState . getAdaTaskProvider ( ) ;
@@ -836,7 +882,7 @@ async function buildTestDriverAndReportErrors(
836882 buildTasks . push ( task ) ;
837883 }
838884
839- const result = await runTaskSequence ( buildTasks , new WriteEmitter ( ) ) ;
885+ const result = await runTaskSequence ( buildTasks , new WriteEmitter ( run ) ) ;
840886
841887 if ( result != 0 ) {
842888 let msg =
0 commit comments