Skip to content

Commit

Permalink
Merge pull request #25 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 41c20af + d141a38 commit fad7421
Show file tree
Hide file tree
Showing 11 changed files with 232 additions and 183 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ before_install:

install:
- npm install
- npm audit
- npm run compile

script:
- npm test --silent

before_deploy:
- npm install
- npm audit
- npm run compile

deploy:
Expand Down
20 changes: 17 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.1.0]

### Added

- `catch2TestExplorer.debugBreakOnFailure` option. It is true by default.
- 🤩 Change of test file (ex.:recompilation) triggers "**autorun**" feature.
(Right click on test/suite in text explorer -> Enable to enable autorun for the selected test/suite.)
This basically means that the selected test/suite will run in case of any filesystem event related to the `executables` variable.
It can be really useful if one would like to run a test (or suite) automatically after recompiliation. 💙

### Fixed

Performance and stability improvements.

## [2.0.3] - 2018-11-20

## Fixed
### Fixed

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

## [2.0.2] - 2018-11-19

Expand Down
11 changes: 3 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
## **Warning**: Version 2 has been released: **API has been changed**.

Update your settings! ([See changelog](CHANGELOG.md) or [configuration below](#Configuration).)

---

## Catch2 Test Explorer for Visual Studio Code
# Catch2 Test Explorer for Visual Studio Code

[![Build Status](https://travis-ci.org/matepek/vscode-catch2-test-adapter.svg?branch=master)](https://travis-ci.org/matepek/vscode-catch2-test-adapter)
[![Build status](https://ci.appveyor.com/api/projects/status/p6uuyg21cwxcnlv9/branch/master?svg=true)](https://ci.appveyor.com/project/matepek/vscode-catch2-test-adapter/branch/master)
Expand All @@ -28,6 +22,7 @@ This extension allows you to run your [Catch2 tests](https://github.com/catchorg
| `catch2TestExplorer.workerMaxNumber` | The variable maximize the number of the parallel test execution. |
| `catch2TestExplorer.enableSourceDecoration` | Sets the source code decorations: Errored lines will be highlited. |
| `catch2TestExplorer.debugConfigTemplate` | Set the necessary debug configuraitons and the debug button will work. Details: [below](#catch2TestExplorer.debugConfigTemplate) |
| `catch2TestExplorer.debugBreakOnFailure` | Debugger breaks on failure while debugging the test. This is a Catch2 parameter: --break |
| `testExplorer.onStart` | (This is part of the [dependency extension](https://github.com/hbenl/vscode-test-explorer#configuration)'s settings.) |
| `testExplorer.onReload` | (This is part of the [dependency extension](https://github.com/hbenl/vscode-test-explorer#configuration)'s settings.) |

Expand Down Expand Up @@ -60,7 +55,7 @@ Variables which can be used in `name`, `cwd` and `env` of `executables`:
| `${ext2Filename}` | Filename's second level extension. ("d/a.b.c" => ".b") |
| `${base3Filename}` | Filename without extension ("d/a.b.c" => "a") |
| `${ext3Filename}` | Filename's second level extension. ("d/a.b.c" => "") |
| `${workspaceDirectory}` | (You can only guess one.) |
| `${workspaceDirectory}` | (You can only guess once.) |
| `${workspaceFolder}` | Alias of `${workspaceDirectory}` |

Examples:
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@
"@types/fs-extra": "^5.0.4",
"@types/mocha": "^5.2.5",
"@types/request-promise": "4.1.42",
"@types/sinon": "5.0.5",
"@types/sinon": "^5.0.7",
"@types/node": "^10.12.9",
"@types/xml2js": "^0.4.3",
"deep-equal": "^1.0.1",
"fs-extra": "^7.0.1",
Expand Down Expand Up @@ -148,6 +149,12 @@
"default": null,
"scope": "resource"
},
"catch2TestExplorer.debugBreakOnFailure": {
"description": "Debugger breaks on failure while debugging the test. This is a Catch2 parameter: --break",
"type": "boolean",
"default": true,
"scope": "resource"
},
"catch2TestExplorer.logpanel": {
"description": "Create a new output channel and write the log messages there.",
"type": "boolean",
Expand Down
24 changes: 15 additions & 9 deletions src/C2AllTestSuiteInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
private _isDisposed = false;

constructor(
private readonly _allTasks: QueueGraphNode,
public readonly allTasks: QueueGraphNode,
public readonly log: util.Log,
public readonly workspaceFolder: vscode.WorkspaceFolder,
public readonly testsEmitter:
private readonly _loadFinishedEmitter: vscode.EventEmitter<void>,
private readonly _testsEmitter:
vscode.EventEmitter<TestLoadStartedEvent|TestLoadFinishedEvent>,
public readonly testStatesEmitter:
private readonly _testStatesEmitter:
vscode.EventEmitter<TestRunStartedEvent|TestRunFinishedEvent|
TestSuiteEvent|TestEvent>,
public readonly autorunEmitter: vscode.EventEmitter<void>,
public readonly variableToValue: [string, string][],
public isEnabledSourceDecoration: boolean,
public rngSeed: string|number|null,
Expand All @@ -46,24 +48,28 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
}

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

sendTestStateEvent(ev: TestSuiteEvent|TestEvent) {
this._testStatesEmitter.fire(ev);
}

removeChild(child: C2TestSuiteInfo): boolean {
const i = this.children.findIndex(val => val.id == child.id);
if (i != -1) {
Expand Down Expand Up @@ -129,7 +135,7 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
}

run(tests: string[], workerMaxNumber: number): Promise<void> {
this.testStatesEmitter.fire(
this._testStatesEmitter.fire(
<TestRunStartedEvent>{type: 'started', tests: tests});

const taskPool = new TaskPool(workerMaxNumber);
Expand All @@ -155,7 +161,7 @@ export class C2AllTestSuiteInfo implements TestSuiteInfo, vscode.Disposable {
}

const always = () => {
this.testStatesEmitter.fire(<TestRunFinishedEvent>{type: 'finished'});
this._testStatesEmitter.fire(<TestRunFinishedEvent>{type: 'finished'});
};

return Promise.all(ps).then(always, always);
Expand Down
87 changes: 45 additions & 42 deletions src/C2ExecutableInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {resolveVariables} from './Helpers';

export class C2ExecutableInfo implements vscode.Disposable {
constructor(
private _allTest: C2AllTestSuiteInfo, public readonly name: string,
private _allTests: C2AllTestSuiteInfo, public readonly name: string,
public readonly pattern: string, public readonly cwd: string,
public readonly env: {[prop: string]: any}) {}

Expand All @@ -33,7 +33,7 @@ export class C2ExecutableInfo implements vscode.Disposable {
}

async load(): Promise<void> {
const wsUri = this._allTest.workspaceFolder.uri;
const wsUri = this._allTests.workspaceFolder.uri;
const pattern =
this.pattern.startsWith('./') ? this.pattern.substr(2) : this.pattern;
const isAbsolute = path.isAbsolute(pattern);
Expand All @@ -44,10 +44,10 @@ export class C2ExecutableInfo implements vscode.Disposable {
const isPartOfWs = !relativeToWs.startsWith('..');

if (isAbsolute && isPartOfWs)
this._allTest.log.info(
this._allTests.log.info(
'Absolute path is used for workspace directory: ' + inspect([this]));
if (this.pattern.indexOf('\\') != -1)
this._allTest.log.warn(
this._allTests.log.warn(
'Pattern contains backslash character: ' + this.pattern);

let fileUris: vscode.Uri[] = [];
Expand All @@ -56,10 +56,10 @@ export class C2ExecutableInfo implements vscode.Disposable {
let relativePattern: vscode.RelativePattern;
if (isAbsolute)
relativePattern = new vscode.RelativePattern(
this._allTest.workspaceFolder, relativeToWs);
this._allTests.workspaceFolder, relativeToWs);
else
relativePattern =
new vscode.RelativePattern(this._allTest.workspaceFolder, pattern);
new vscode.RelativePattern(this._allTests.workspaceFolder, pattern);
try {
fileUris =
await vscode.workspace.findFiles(relativePattern, undefined, 1000);
Expand All @@ -75,7 +75,7 @@ export class C2ExecutableInfo implements vscode.Disposable {
this._disposables.push(
this._watcher.onDidDelete(this._handleDelete, this));
} catch (e) {
this._allTest.log.error(inspect([e, this]));
this._allTests.log.error(inspect([e, this]));
}
} else {
fileUris.push(absPatternAsUri);
Expand All @@ -93,15 +93,15 @@ export class C2ExecutableInfo implements vscode.Disposable {

for (const suite of this._executables.values()) {
await suite.reloadChildren().catch((err: any) => {
this._allTest.log.error(
this._allTests.log.error(
'Couldn\'t load suite: ' + inspect([err, suite]));
// we could remove it, but now the user still sees the dead leaf
});
}
}

private _addFile(file: vscode.Uri) {
const wsUri = this._allTest.workspaceFolder.uri;
const wsUri = this._allTests.workspaceFolder.uri;

let resolvedName = this.name;
let resolvedCwd = this.cwd;
Expand All @@ -118,7 +118,7 @@ export class C2ExecutableInfo implements vscode.Disposable {
const base3Filename = path.basename(base2Filename, ext3Filename);

const varToValue: [string, string][] = [
...this._allTest.variableToValue,
...this._allTests.variableToValue,
['${absPath}', file.fsPath],
['${relPath}', relPath],
['${absDirpath}', path.dirname(file.fsPath)],
Expand All @@ -133,16 +133,17 @@ export class C2ExecutableInfo implements vscode.Disposable {
];
resolvedName = resolveVariables(this.name, varToValue);
if (resolvedName.match(/\$\{.*\}/))
this._allTest.log.warn('Possibly unresolved variable: ' + resolvedName);
this._allTests.log.warn(
'Possibly unresolved variable: ' + resolvedName);
resolvedCwd = path.normalize(resolveVariables(this.cwd, varToValue));
if (resolvedCwd.match(/\$\{.*\}/))
this._allTest.log.warn('Possibly unresolved variable: ' + resolvedCwd);
this._allTests.log.warn('Possibly unresolved variable: ' + resolvedCwd);
resolvedEnv = resolveVariables(this.env, varToValue);
} catch (e) {
this._allTest.log.error(inspect([e, this]));
this._allTests.log.error(inspect([e, this]));
}

const suite = this._allTest.createChildSuite(
const suite = this._allTests.createChildSuite(
resolvedName, file.fsPath, {cwd: resolvedCwd, env: resolvedEnv});

return suite;
Expand All @@ -163,38 +164,40 @@ export class C2ExecutableInfo implements vscode.Disposable {

if (isRunning) return;

const x =
(exists: boolean, timeout: number, delay: number): Promise<void> => {
let lastEventArrivedAt = this._lastEventArrivedAt.get(uri.fsPath);
if (lastEventArrivedAt === undefined) {
this._allTest.log.error('assert in ' + __filename);
debugger;
return Promise.resolve();
}
if (Date.now() - lastEventArrivedAt! > timeout) {
this._lastEventArrivedAt.delete(uri.fsPath);
this._executables.delete(uri.fsPath);
this._allTest.testsEmitter.fire({type: 'started'});
this._allTest.removeChild(suite!);
this._allTest.testsEmitter.fire(
{type: 'finished', suite: this._allTest});
return Promise.resolve();
} else if (exists) {
return this._allTest.sendLoadEvents(() => {
const x = (exists: boolean, delay: number): Promise<void> => {
let lastEventArrivedAt = this._lastEventArrivedAt.get(uri.fsPath);
if (lastEventArrivedAt === undefined) {
this._allTests.log.error('assert in ' + __filename);
debugger;
return Promise.resolve();
}
if (Date.now() - lastEventArrivedAt! > this._allTests.execWatchTimeout) {
return this._allTests.sendLoadEvents(() => {
this._lastEventArrivedAt.delete(uri.fsPath);
this._executables.delete(uri.fsPath);
this._allTests.removeChild(suite!);
return Promise.resolve();
});
} else if (exists) {
return this._allTests
.sendLoadEvents(() => {
this._lastEventArrivedAt.delete(uri.fsPath);
return suite!.reloadChildren().catch(() => {
return x(false, timeout, Math.min(delay * 2, 2000));
return x(false, Math.min(delay * 2, 2000));
});
})
.then(() => {
this._allTests.autorunEmitter.fire();
});
}
return promisify(setTimeout)(Math.min(delay * 2, 2000)).then(() => {
return c2fs.existsAsync(uri.fsPath).then((exists: boolean) => {
return x(exists, timeout, Math.min(delay * 2, 2000));
});
});
};
}
return promisify(setTimeout)(Math.min(delay * 2, 2000)).then(() => {
return c2fs.existsAsync(uri.fsPath).then((exists: boolean) => {
return x(exists, Math.min(delay * 2, 2000));
});
});
};
// change event can arrive during debug session on osx (why?)
x(false, this._allTest.execWatchTimeout, 64);
x(false, 64);
}

private _handleCreate(uri: vscode.Uri) {
Expand Down Expand Up @@ -237,7 +240,7 @@ export class C2ExecutableInfo implements vscode.Disposable {
return res.stdout.indexOf('Catch v2.') != -1;
})
.catch(e => {
this._allTest.log.error(inspect(e));
this._allTests.log.error(inspect(e));
return false;
});
}
Expand Down
Loading

0 comments on commit fad7421

Please sign in to comment.