forked from recca0120/vscode-phpunit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHandler.ts
More file actions
118 lines (95 loc) · 4.52 KB
/
Handler.ts
File metadata and controls
118 lines (95 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { rm } from 'node:fs/promises';
import { dirname } from 'node:path';
import {
CancellationToken, debug, OutputChannel, TestController, TestItem, TestItemCollection, TestRun, TestRunRequest,
workspace,
} from 'vscode';
import { CloverParser } from './CloverParser';
import { Configuration } from './Configuration';
import { OutputChannelObserver, Printer, TestResultObserver } from './Observers';
import { MessageObserver } from './Observers/MessageObserver';
import { Builder, PHPUnitXML, TestRunner, TestRunnerEvent, TestType } from './PHPUnit';
import { Mode, Xdebug } from './PHPUnit/CommandBuilder/Xdebug';
import { TestCase, TestCollection } from './TestCollection';
export class Handler {
private previousRequest: TestRunRequest | undefined;
constructor(
private ctrl: TestController,
private phpUnitXML: PHPUnitXML,
private configuration: Configuration,
private testCollection: TestCollection,
private outputChannel: OutputChannel,
private printer: Printer,
) { }
getPreviousRequest() {
return this.previousRequest;
}
async startTestRun(request: TestRunRequest, cancellation?: CancellationToken) {
const wsf = workspace.getWorkspaceFolder(this.testCollection.getWorkspace());
const builder = new Builder(this.configuration, { cwd: this.phpUnitXML.root() });
const xdebug = new Xdebug(this.configuration);
builder.setXdebug(xdebug);
await xdebug.setMode(request.profile?.kind);
if (xdebug.mode === Mode.debug) {
// TODO: perhaps wait for the debug session
await debug.startDebugging(wsf, xdebug.name ?? await xdebug.getDebugConfiguration());
}
const testRun = this.ctrl.createTestRun(request);
await this.runTestQueue(builder, testRun, request, cancellation);
if (xdebug.mode === Mode.debug && debug.activeDebugSession?.type === 'php') {
debug.stopDebugging(debug.activeDebugSession);
}
this.previousRequest = request;
}
private async runTestQueue(builder: Builder, testRun: TestRun, request: TestRunRequest, cancellation?: CancellationToken) {
const queue = await this.discoverTests(request.include ?? this.gatherTestItems(this.ctrl.items), request);
queue.forEach((testItem) => testRun.enqueued(testItem));
const runner = new TestRunner();
runner.observe(new TestResultObserver(queue, testRun));
runner.observe(new OutputChannelObserver(this.outputChannel, this.configuration, this.printer, request));
runner.observe(new MessageObserver(this.configuration));
runner.emit(TestRunnerEvent.start, undefined);
const processes = !request.include
? [runner.run(builder)]
: request.include
.map((testItem) => this.testCollection.getTestCase(testItem)!)
.map((testCase, index) => testCase.update(builder, index))
.map((builder) => runner.run(builder));
cancellation?.onCancellationRequested(() => processes.forEach((process) => process.abort()));
await Promise.all(processes.map((process) => process.run()));
await Promise.all(
processes
.map((process) => process.getCloverFile())
.filter((file) => !!file)
.map(async (file) => {
return (await CloverParser.parseClover(file!)).map(coverage => {
testRun.addCoverage(coverage);
});
}),
);
const cloverFile = processes[0].getCloverFile();
if (cloverFile) {
await rm(dirname(cloverFile), { recursive: true, force: true });
}
runner.emit(TestRunnerEvent.done, undefined);
};
private async discoverTests(tests: Iterable<TestItem>, request: TestRunRequest, queue = new Map<TestCase, TestItem>()) {
for (const testItem of tests) {
if (request.exclude?.includes(testItem)) {
continue;
}
const testCase = this.testCollection.getTestCase(testItem);
if (testCase?.type === TestType.method) {
queue.set(testCase, testItem);
} else {
await this.discoverTests(this.gatherTestItems(testItem.children), request, queue);
}
}
return queue;
};
private gatherTestItems(collection: TestItemCollection) {
const items: TestItem[] = [];
collection.forEach((item) => items.push(item));
return items;
}
}