Skip to content

Commit

Permalink
Merge pull request #24 from matepek/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
matepek authored Nov 20, 2018
2 parents e8070ff + 05b8565 commit 389952f
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 102 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"files.associations": {
"*.txt": "cpp"
},
"editor.formatOnSaveTimeout": 1750
"editor.formatOnSaveTimeout": 3000
}
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.0.3]

## Fixed

- It reload suite if it finds any new tests.
- A bug in package.json. It couldn't load the tests.

## [2.0.2] - 2018-11-19

### Fixed
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Update your settings! ([See changelog](CHANGELOG.md) or [configuration below](#C
[![GitHub license](https://img.shields.io/github/license/matepek/vscode-catch2-test-adapter.svg)](https://github.com/matepek/vscode-catch2-test-adapter/blob/master/LICENSE)
[![Visual Studio Marketplace](https://img.shields.io/vscode-marketplace/d/matepek.vscode-catch2-test-adapter.svg)](https://marketplace.visualstudio.com/items?itemName=matepek.vscode-catch2-test-adapter)
[![Visual Studio Marketplace](https://img.shields.io/vscode-marketplace/v/matepek.vscode-catch2-test-adapter.svg)](https://marketplace.visualstudio.com/items?itemName=matepek.vscode-catch2-test-adapter)
[![GitHub stars](https://img.shields.io/github/stars/badges/shields.svg?style=social&label=Stars)](https://github.com/matepek/vscode-catch2-test-adapter)

This extension allows you to run your [Catch2 tests](https://github.com/catchorg/Catch2) using the
[Test Explorer for VS Code](https://marketplace.visualstudio.com/items?itemName=hbenl.vscode-test-explorer).
Expand Down Expand Up @@ -78,7 +77,7 @@ Examples:
"catch2TestExplorer.executables": {
"name": "${relName} (${relDirname}/)",
"pattern": "{build,Build,BUILD,out,Out,OUT}/**/*{test,Test,TEST}*",
"cwd": "${absDirname}",
"cwd": "${absDirpath}",
"env": {
"ExampleENV1": "You can use variables here too, like ${absName}"
}
Expand All @@ -102,7 +101,13 @@ Examples:

### catch2TestExplorer.debugConfigTemplate

For help, see: [here](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations)
If `catch2TestExplorer.debugConfigTemplate` value is `null` (default),
it will look after `vadimcn.vscode-lldb` and `ms-vscode.cpptools` extensions.
If it founds one of it, it will use it automatically.

#### Or user can manually fill it

See [here](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) for details.

Usable variables:

Expand All @@ -116,7 +121,7 @@ Usable variables:

These variables will be substituted when a DebugConfiguration is created.

`name` and `request` are prefilled, so it is not necessary to set them.
Note that `name` and `request` are prefilled, so it is not necessary to set them.

Example:

Expand Down
17 changes: 16 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
{
"name": "${relPath} (${relDirpath}/)",
"path": "{build,Build,BUILD,out,Out,OUT}/**/*{test,Test,TEST}*",
"cwd": "${absDirname}",
"cwd": "${absDirpath}",
"env": {
"C2TESTEXECUTABLEPATH": "${absPath}"
}
Expand Down Expand Up @@ -147,6 +147,21 @@
],
"default": null,
"scope": "resource"
},
"catch2TestExplorer.logpanel": {
"description": "Create a new output channel and write the log messages there.",
"type": "boolean",
"default": false,
"scope": "resource"
},
"catch2TestExplorer.logfile": {
"description": "Write the log message into the given file.",
"type": [
"string",
"null"
],
"default": null,
"scope": "resource"
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions src/C2AllTestSuiteInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {C2ExecutableInfo} from './C2ExecutableInfo'
import {C2TestInfo} from './C2TestInfo';
import {C2TestSuiteInfo} from './C2TestSuiteInfo';
import {generateUniqueId} from './IdGenerator';
import {QueueGraphNode} from './QueueGraph';
import {TaskPool} from './TaskPool';

export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
Expand All @@ -20,8 +21,10 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
readonly label: string = 'AllTests';
readonly children: C2TestSuiteInfo[] = [];
private readonly _executables: C2ExecutableInfo[] = [];
private _isDisposed = false;

constructor(
private readonly _allTasks: QueueGraphNode,
public readonly log: util.Log,
public readonly workspaceFolder: vscode.WorkspaceFolder,
public readonly testsEmitter:
Expand All @@ -38,9 +41,29 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
}

dispose() {
this._isDisposed = true;
while (this._executables.length) this._executables.pop()!.dispose();
}

sendLoadEvents(task: (() => Promise<void>)) {
return this._allTasks.then(() => {
if (this._isDisposed) {
return task();
} else {
this.testsEmitter.fire({type: 'started'});
return task().then(
() => {
this.testsEmitter.fire({type: 'finished', suite: this});
},
(reason: any) => {
this.testsEmitter.fire({type: 'finished', suite: this});
this.log.warn(inspect(reason));
throw reason;
});
}
});
}

removeChild(child: C2TestSuiteInfo): boolean {
const i = this.children.findIndex(val => val.id == child.id);
if (i != -1) {
Expand Down
42 changes: 19 additions & 23 deletions src/C2ExecutableInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@ export class C2ExecutableInfo implements vscode.Disposable {

let fileUris: vscode.Uri[] = [];

if (!isAbsolute) {
const relativePattern =
new vscode.RelativePattern(this._allTest.workspaceFolder, pattern);

if (!isAbsolute || isPartOfWs) {
let relativePattern: vscode.RelativePattern;
if (isAbsolute)
relativePattern = new vscode.RelativePattern(
this._allTest.workspaceFolder, relativeToWs);
else
relativePattern =
new vscode.RelativePattern(this._allTest.workspaceFolder, pattern);
try {
fileUris =
await vscode.workspace.findFiles(relativePattern, undefined, 1000);
Expand Down Expand Up @@ -128,7 +132,11 @@ export class C2ExecutableInfo implements vscode.Disposable {
['${base3Filename}', base3Filename],
];
resolvedName = resolveVariables(this.name, varToValue);
if (resolvedName.match(/\$\{.*\}/))
this._allTest.log.warn('Possibly unresolved variable: ' + resolvedName);
resolvedCwd = path.normalize(resolveVariables(this.cwd, varToValue));
if (resolvedCwd.match(/\$\{.*\}/))
this._allTest.log.warn('Possibly unresolved variable: ' + resolvedCwd);
resolvedEnv = resolveVariables(this.env, varToValue);
} catch (e) {
this._allTest.log.error(inspect([e, this]));
Expand All @@ -150,13 +158,11 @@ export class C2ExecutableInfo implements vscode.Disposable {
}

const isRunning = this._lastEventArrivedAt.get(uri.fsPath) !== undefined;
if (isRunning) {
this._lastEventArrivedAt.set(uri.fsPath, Date.now());
return;
}

this._lastEventArrivedAt.set(uri.fsPath, Date.now());

if (isRunning) return;

const x =
(exists: boolean, timeout: number, delay: number): Promise<void> => {
let lastEventArrivedAt = this._lastEventArrivedAt.get(uri.fsPath);
Expand All @@ -174,20 +180,11 @@ export class C2ExecutableInfo implements vscode.Disposable {
{type: 'finished', suite: this._allTest});
return Promise.resolve();
} else if (exists) {
return Promise.resolve().then(() => {
this._allTest.testsEmitter.fire({type: 'started'});
return suite!.reloadChildren().then(
() => {
this._allTest.testsEmitter.fire(
{type: 'finished', suite: this._allTest});
this._lastEventArrivedAt.delete(uri.fsPath);
},
(err: any) => {
this._allTest.testsEmitter.fire(
{type: 'finished', suite: this._allTest});
this._allTest.log.warn(inspect(err));
return x(false, timeout, Math.min(delay * 2, 2000));
});
return this._allTest.sendLoadEvents(() => {
this._lastEventArrivedAt.delete(uri.fsPath);
return suite!.reloadChildren().catch(() => {
return x(false, timeout, Math.min(delay * 2, 2000));
});
});
}
return promisify(setTimeout)(Math.min(delay * 2, 2000)).then(() => {
Expand All @@ -197,7 +194,6 @@ export class C2ExecutableInfo implements vscode.Disposable {
});
};
// change event can arrive during debug session on osx (why?)
// if (!this.isDebugging) {
x(false, this._allTest.execWatchTimeout, 64);
}

Expand Down
80 changes: 47 additions & 33 deletions src/C2TestAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {C2AllTestSuiteInfo} from './C2AllTestSuiteInfo';
import {C2ExecutableInfo} from './C2ExecutableInfo';
import {C2TestInfo} from './C2TestInfo';
import {resolveVariables} from './Helpers';
import {QueueGraphNode} from './QueueGraph';

export class C2TestAdapter implements TestAdapter, vscode.Disposable {
private readonly _testsEmitter =
Expand All @@ -29,6 +30,7 @@ export class C2TestAdapter implements TestAdapter, vscode.Disposable {
private _isDebugging: boolean = false;
private _isRunning: number = 0;

private _allTasks = new QueueGraphNode();
private _allTests: C2AllTestSuiteInfo;
private readonly _disposables: vscode.Disposable[] = [];

Expand Down Expand Up @@ -78,7 +80,7 @@ export class C2TestAdapter implements TestAdapter, vscode.Disposable {

const config = this._getConfiguration();
this._allTests = new C2AllTestSuiteInfo(
this._log, this._workspaceFolder, this._testsEmitter,
this._allTasks, this._log, this._workspaceFolder, this._testsEmitter,
this._testStatesEmitter, this._variableToValue,
this._getEnableSourceDecoration(config),
this._getDefaultRngSeed(config),
Expand Down Expand Up @@ -106,29 +108,37 @@ export class C2TestAdapter implements TestAdapter, vscode.Disposable {
return this._autorunEmitter.event;
}

async load(): Promise<void> {
try {
this.cancel();
const config = this._getConfiguration();

this._allTests.dispose();

this._allTests = new C2AllTestSuiteInfo(
this._log, this._workspaceFolder, this._testsEmitter,
this._testStatesEmitter, this._variableToValue,
this._getEnableSourceDecoration(config),
this._getDefaultRngSeed(config),
this._getDefaultExecWatchTimeout(config));
load(): Promise<void> {
this.cancel();
const config = this._getConfiguration();

this._testsEmitter.fire(<TestLoadStartedEvent>{type: 'started'});
this._allTests.dispose();
this._allTasks = new QueueGraphNode();

await this._allTests.load(this._getExecutables(config, this._allTests));
this._allTests = new C2AllTestSuiteInfo(
this._allTasks, this._log, this._workspaceFolder, this._testsEmitter,
this._testStatesEmitter, this._variableToValue,
this._getEnableSourceDecoration(config),
this._getDefaultRngSeed(config),
this._getDefaultExecWatchTimeout(config));

this._testsEmitter.fire({type: 'finished', suite: this._allTests});
} catch (e) {
this._testsEmitter.fire(
{type: 'finished', suite: undefined, errorMessage: e.message});
}
this._testsEmitter.fire(<TestLoadStartedEvent>{type: 'started'});

return this._allTasks.then(() => {
return this._allTests.load(this._getExecutables(config, this._allTests))
.then(
() => {
this._testsEmitter.fire(
{type: 'finished', suite: this._allTests});
},
(e: any) => {
this._testsEmitter.fire({
type: 'finished',
suite: undefined,
errorMessage: e.toString()
});
});
});
}

cancel(): void {
Expand All @@ -145,12 +155,14 @@ export class C2TestAdapter implements TestAdapter, vscode.Disposable {
const always = () => {
this._isRunning -= 1;
};
return this._allTests
.run(tests, this._getWorkerMaxNumber(this._getConfiguration()))
.then(always, always);
return this._allTasks.then(() => {
return this._allTests
.run(tests, this._getWorkerMaxNumber(this._getConfiguration()))
.then(always, always);
});
}

throw Error('Catch2 Test Adapter: Test(s) are currently being run.');
throw Error('Catch2 Test Adapter: Test(s) are currently doing something.');
}

async debug(tests: string[]): Promise<void> {
Expand Down Expand Up @@ -244,14 +256,16 @@ export class C2TestAdapter implements TestAdapter, vscode.Disposable {
this._isDebugging = false;
};

await new Promise<void>((resolve, reject) => {
const subscription = vscode.debug.onDidTerminateDebugSession(session => {
if (currentSession != session) return;
console.info('Debug session ended');
resolve();
subscription.dispose();
});
}).then(always, always);
return new Promise<void>((resolve) => {
const subscription =
vscode.debug.onDidTerminateDebugSession(session => {
if (currentSession != session) return;
console.info('Debug session ended');
resolve();
subscription.dispose();
});
})
.then(always, always);
}

private _getConfiguration(): vscode.WorkspaceConfiguration {
Expand Down
21 changes: 20 additions & 1 deletion src/C2TestSuiteInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,15 @@ export class C2TestSuiteInfo implements TestSuiteInfo {
this.line = undefined;
}

this.children.push(test);
let i = this.children.findIndex((v: C2TestInfo) => {
const f = test.file.trim().localeCompare(v.file.trim());
if (f != 0)
return f < 0;
else
return test.line < v.line;
});
if (i == -1) i = this.children.length;
this.children.splice(i, 0, test);

return test;
}
Expand Down Expand Up @@ -210,6 +218,17 @@ export class C2TestSuiteInfo implements TestSuiteInfo {
this.allTests.log.error(
'Parsing and processing test: ' + data.currentChild.label);
}
} else {
this.allTests
.sendLoadEvents(() => {
return this.reloadChildren();
})
.then(
() => {
// TODO send event states: find newChild and parseXml
});

this.allTests.log.info('<TestCase> found without TestInfo.');
}

data.inTestCase = false;
Expand Down
Loading

0 comments on commit 389952f

Please sign in to comment.