diff --git a/CHANGELOG.md b/CHANGELOG.md index e1e9512a..04edf3d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] +## [4.0.4] + +### Fixed + +- navigation to source file related issue (again) + ## [4.0.3] - 2021-11-23 - Improved Output formatting and colorization diff --git a/README.md b/README.md index 2d5c30da..3ced5891 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ Plenty of more **fine-tuning options** are available under [test.advancedExecuta | ID | Command | | -------------------------------- | --------------------------------------------- | | `testMate.cmd.reload-tests` | Reload tests | -| `testMate.cmd.reload-workspaces` | Force reload workspaces (in case of na issue) | +| `testMate.cmd.reload-workspaces` | Force reload workspaces (in case of an issue) | ## About [Sentry.io](https://github.com/matepek/vscode-catch2-test-adapter/blob/master/documents/configuration/log.logSentry.md) integration diff --git a/src/AbstractExecutable.ts b/src/AbstractExecutable.ts index 7729ee4d..9f9eb02e 100644 --- a/src/AbstractExecutable.ts +++ b/src/AbstractExecutable.ts @@ -774,7 +774,7 @@ export abstract class AbstractExecutable implements Disposable { } } - protected async _resolveAndFindSourceFilePath(file: string | undefined): Promise { + public async resolveAndFindSourceFilePath(file: string | undefined): Promise { if (typeof file != 'string') return undefined; let resolved = file; diff --git a/src/AbstractTest.ts b/src/AbstractTest.ts index e6810492..0894a1a0 100644 --- a/src/AbstractTest.ts +++ b/src/AbstractTest.ts @@ -192,24 +192,35 @@ export abstract class AbstractTest { private _subTests: Map | undefined = undefined; - public getOrCreateSubTest( + public async getOrCreateSubTest( id: string, label: string | undefined, file: string | undefined, line: string | undefined, - ): SubTest { + ): Promise { + const resolvedFile = await this.executable.resolveAndFindSourceFilePath(file); + if (this._subTests) { const found = this._subTests.get(id); if (found) { - found.updateSub(label, file, line); + found.updateSub(label, resolvedFile, line); return found; } } else { this._subTests = new Map(); } - const subTest = new SubTest(this.shared, this.executable, this._item, id, label, file, line, this._frameworkTag); + const subTest = new SubTest( + this.shared, + this.executable, + this._item, + id, + label, + resolvedFile, + line, + this._frameworkTag, + ); this._subTests.set(id, subTest); return subTest; diff --git a/src/framework/Catch2Executable.ts b/src/framework/Catch2Executable.ts index f15a2d3f..4c2c17be 100644 --- a/src/framework/Catch2Executable.ts +++ b/src/framework/Catch2Executable.ts @@ -123,8 +123,6 @@ export class Catch2Executable extends AbstractExecutable { this.shared.log.error('Could not find catch2 file info1', lines); } } - - filePath = await this._resolveAndFindSourceFilePath(filePath); } let description: string | undefined = lines[i++].substr(4); @@ -181,7 +179,7 @@ export class Catch2Executable extends AbstractExecutable { if (matches) matches.forEach((t: string) => tags.push(t.substring(1, t.length - 1))); } - const resolvedFile = await this._resolveAndFindSourceFilePath(file); + const resolvedFile = await this.resolveAndFindSourceFilePath(file); return this._createTreeAndAddTest( this.getTestGrouping(), @@ -447,7 +445,7 @@ class TestCaseListingProcessor implements XmlTagProcessor { abstract class TagProcessorBase implements XmlTagProcessor { constructor(public readonly builder: TestResultBuilder, protected readonly shared: WorkspaceShared) {} - public onopentag(tag: XmlTag): XmlTagProcessor | void { + public onopentag(tag: XmlTag): void | XmlTagProcessor | Promise { const procCreator = TagProcessorBase.openTagProcessorMap.get(tag.name); if (procCreator) { return procCreator(tag, this.builder, this.shared); @@ -498,7 +496,12 @@ abstract class TagProcessorBase implements XmlTagProcessor { private static readonly openTagProcessorMap: Map< string, - null | ((tag: XmlTag, builder: TestResultBuilder, shared: WorkspaceShared) => void | XmlTagProcessor) + | null + | (( + tag: XmlTag, + builder: TestResultBuilder, + shared: WorkspaceShared, + ) => void | XmlTagProcessor | Promise) > = new Map([ [ 'OverallResult', @@ -532,14 +535,14 @@ abstract class TagProcessorBase implements XmlTagProcessor { ], [ 'Section', - (tag: XmlTag, builder: TestResultBuilder, shared: WorkspaceShared): XmlTagProcessor => - new SectionProcessor(shared, builder, tag.attribs), + (tag: XmlTag, builder: TestResultBuilder, shared: WorkspaceShared): Promise => + SectionProcessor.create(shared, builder, tag.attribs), ], [ 'BenchmarkResults', - (tag: XmlTag, builder: TestResultBuilder, shared: WorkspaceShared): XmlTagProcessor => { + async (tag: XmlTag, builder: TestResultBuilder, shared: WorkspaceShared): Promise => { assert(tag.attribs.name); - const subTest = builder.test.getOrCreateSubTest(tag.attribs.name, undefined, undefined, undefined); + const subTest = await builder.test.getOrCreateSubTest(tag.attribs.name, undefined, undefined, undefined); const subBuilder = builder.createSubTestBuilder(subTest); return new BenchmarkResultsProcessor(shared, subBuilder, tag.attribs); }, @@ -638,14 +641,17 @@ class TestCaseTagProcessor extends TagProcessorBase { /// class SectionProcessor extends TagProcessorBase { - public constructor(shared: WorkspaceShared, testBuilder: TestResultBuilder, attribs: Record) { + public static async create(shared: WorkspaceShared, testBuilder: TestResultBuilder, attribs: Record) { if (typeof attribs.name !== 'string' || !attribs.name) throw Error('Section must have name attribute'); - const subTest = testBuilder.test.getOrCreateSubTest(attribs.name, undefined, attribs.filename, attribs.line); + const subTest = await testBuilder.test.getOrCreateSubTest(attribs.name, undefined, attribs.filename, attribs.line); const subTestBuilder = testBuilder.createSubTestBuilder(subTest); - subTestBuilder.started(); + return new SectionProcessor(shared, subTestBuilder); + } - super(subTestBuilder, shared); + private constructor(shared: WorkspaceShared, testBuilder: TestResultBuilder) { + testBuilder.started(); + super(testBuilder, shared); } public end(): void { diff --git a/src/framework/DOCExecutable.ts b/src/framework/DOCExecutable.ts index 002ecd6a..bb53423f 100644 --- a/src/framework/DOCExecutable.ts +++ b/src/framework/DOCExecutable.ts @@ -77,7 +77,7 @@ export class DOCExecutable extends AbstractExecutable { ): Promise => { const tags: string[] = suiteName ? [suiteName] : []; const skippedB = skipped === 'true'; - const resolvedFile = await this._resolveAndFindSourceFilePath(file); + const resolvedFile = await this.resolveAndFindSourceFilePath(file); return this._createTreeAndAddTest( this.getTestGrouping(), testName, @@ -319,7 +319,7 @@ abstract class TagProcessorBase implements XmlTagProcessor { protected readonly caseData: CaseData, ) {} - public onopentag(tag: XmlTag): XmlTagProcessor | void { + public onopentag(tag: XmlTag): void | XmlTagProcessor | Promise { const procCreator = TagProcessorBase.openTagProcessorMap.get(tag.name); if (procCreator) { return procCreator(tag, this.builder, this.caseData, this.shared); @@ -365,7 +365,12 @@ abstract class TagProcessorBase implements XmlTagProcessor { private static readonly openTagProcessorMap: Map< string, | null - | ((tag: XmlTag, builder: TestResultBuilder, caseData: CaseData, shared: WorkspaceShared) => void | XmlTagProcessor) + | (( + tag: XmlTag, + builder: TestResultBuilder, + caseData: CaseData, + shared: WorkspaceShared, + ) => void | XmlTagProcessor | Promise) > = new Map([ [ 'SubCase', @@ -374,9 +379,9 @@ abstract class TagProcessorBase implements XmlTagProcessor { builder: TestResultBuilder, caseData: CaseData, shared: WorkspaceShared, - ): void | XmlTagProcessor => { + ): void | XmlTagProcessor | Promise => { // if name is missing we don't create subcase for it - if (tag.attribs.name) return new SubCaseProcessor(shared, builder, tag.attribs, caseData); + if (tag.attribs.name) return SubCaseProcessor.create(shared, builder, tag.attribs, caseData); }, ], [ @@ -449,7 +454,7 @@ class TestCaseTagProcessor extends TagProcessorBase { test.line = attribs.line; } - public override onopentag(tag: XmlTag): XmlTagProcessor | void { + public override onopentag(tag: XmlTag): void | XmlTagProcessor | Promise { if (tag.name === 'OverallResultsAsserts') { const durationSec = parseFloat(tag.attribs.duration) || undefined; if (durationSec === undefined) this.shared.log.errorS('doctest: duration is NaN: ' + tag.attribs.duration); @@ -487,12 +492,12 @@ class TestCaseTagProcessor extends TagProcessorBase { /// class SubCaseProcessor extends TagProcessorBase { - public constructor( + public static async create( shared: WorkspaceShared, testBuilder: TestResultBuilder, attribs: Record, parentCaseData: CaseData, - ) { + ): Promise { if (typeof attribs.name !== 'string' || !attribs.name) throw Error('Section must have name attribute'); let label: string | undefined = undefined; @@ -501,11 +506,16 @@ class SubCaseProcessor extends TagProcessorBase { if (m) label = m[1]; } - const subTest = testBuilder.test.getOrCreateSubTest(attribs.name, label, attribs.filename, attribs.line); + const subTest = await testBuilder.test.getOrCreateSubTest(attribs.name, label, attribs.filename, attribs.line); const subTestBuilder = testBuilder.createSubTestBuilder(subTest); - subTestBuilder.started(); - super(subTestBuilder, shared, parentCaseData); + return new SubCaseProcessor(shared, subTestBuilder, parentCaseData); + } + + private constructor(shared: WorkspaceShared, testBuilder: TestResultBuilder, parentCaseData: CaseData) { + testBuilder.started(); + + super(testBuilder, shared, parentCaseData); } //doctest does not provide result for sub-cases, no point to build diff --git a/src/framework/GoogleTestExecutable.ts b/src/framework/GoogleTestExecutable.ts index 9bab8241..9cd74512 100644 --- a/src/framework/GoogleTestExecutable.ts +++ b/src/framework/GoogleTestExecutable.ts @@ -109,7 +109,7 @@ export class GoogleTestExecutable extends AbstractExecutable { typeParam: string | undefined, valueParam: string | undefined, ): Promise => { - const resolvedFile = await this._resolveAndFindSourceFilePath(file); + const resolvedFile = await this.resolveAndFindSourceFilePath(file); return this._createTreeAndAddTest( this.getTestGrouping(), testName,