Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Argbuilder #88

Merged
merged 2 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/CodeLens/PhpCodeLensProvider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CodeLensProvider, CodeLens, CancellationToken, TextDocument, Range } from 'vscode';
import { Class, CommentBlock, Engine, Identifier, Method, Namespace } from 'php-parser';
import { PhpunitArgBuilder } from '../PhpunitCommand/PhpunitArgBuilder';

let lastDocumentText: string;
let lastCodeLenses: Array<CodeLens> = [];
Expand Down Expand Up @@ -40,6 +41,10 @@ export class PhpCodeLensProvider implements CodeLensProvider {
}
}

for (const codeLens of codeLenses) {
(codeLens.command!.arguments![0] as PhpunitArgBuilder).addDirectoryOrFile(document.fileName);
}

lastDocumentText = document.getText();
lastCodeLenses = codeLenses;

Expand Down Expand Up @@ -79,11 +84,15 @@ export class PhpCodeLensProvider implements CodeLensProvider {

if (codeLenses.length > 0) {
const classCodeLensRange = new Range(node.loc!.start.line - 1, 0, node.loc!.start.line - 1, 0);
const className = typeof node.name === 'string' ? node.name : (node.name as Identifier).name;

codeLenses.push(new CodeLens(classCodeLensRange, {
command: 'phpunit.Test',
title: "Run tests",
arguments: ["AdditionTest"],
arguments: [
new PhpunitArgBuilder()
.addFilter(className)
],
}));
}

Expand All @@ -107,7 +116,10 @@ export class PhpCodeLensProvider implements CodeLensProvider {
return new CodeLens(codeLensRange, {
command: 'phpunit.Test',
title: 'Run test',
arguments: [methodName],
arguments: [
new PhpunitArgBuilder()
.addFilter(methodName)
],
});
}
}
21 changes: 15 additions & 6 deletions src/CodeLens/PhpunitXmlCodeLensProvider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CodeLensProvider, CodeLens, CancellationToken, TextDocument, Range } from 'vscode';
import { parse, DocumentCstNode } from '@xml-tools/parser';
import { buildAst, XMLElement, } from '@xml-tools/ast';
import { PhpunitArgBuilder } from '../PhpunitCommand/PhpunitArgBuilder';

let lastDocumentText: string;
let lastCodeLenses: Array<CodeLens> = [];
Expand All @@ -22,7 +23,7 @@ export class PhpunitXmlCodeLensProvider implements CodeLensProvider {

for (const node of ast.rootElement!.subElements) {
if (node.name === 'testsuites') {
codeLenses.push(...this.parseTestSuites(node));
codeLenses.push(...this.parseTestSuites(node, document.fileName));
}
}

Expand All @@ -37,35 +38,43 @@ export class PhpunitXmlCodeLensProvider implements CodeLensProvider {
// return codeLens;
// }

private parseTestSuites(node: XMLElement): CodeLens[] {
private parseTestSuites(node: XMLElement, fileName: string): CodeLens[] {
const codeLenses: Array<CodeLens> = [];

for (const child of node.subElements) {
if (child.name === 'testsuite') {
codeLenses.push(this.parseTestSuite(child));
codeLenses.push(this.parseTestSuite(child, fileName));
}
}

if (codeLenses.length > 0) {
const codeLensRange = new Range(node.position.startLine - 1, 0, node.position.startLine - 1, 0);

codeLenses.push(new CodeLens(codeLensRange, {
command: 'phpunit.Test',
title: 'Run tests',
arguments: ['All Test Suites'],
arguments: [
new PhpunitArgBuilder()
.withConfig(fileName)
]
}));
}

return codeLenses;
}

private parseTestSuite(node: XMLElement): CodeLens {
private parseTestSuite(node: XMLElement, fileName: string): CodeLens {
const codeLensRange = new Range(node.position.startLine - 1, 0, node.position.startLine - 1, 0);
const name = node.attributes.find((attribute) => attribute.key === 'name')!.value!;

return new CodeLens(codeLensRange, {
command: 'phpunit.Test',
title: 'Run test',
arguments: [name],
arguments: [
new PhpunitArgBuilder()
.withConfig(fileName)
.addSuite(name)
]
});
}
}
104 changes: 104 additions & 0 deletions src/PhpunitCommand/PhpunitArgBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import escapeStringRegexp from "../Utils/escape-string-regexp";

export class PhpunitArgBuilder {
private directoryOrFiles: Array<string> = [];
private suites: Array<string> = [];
private filters: Array<string> = [];
private groups: Array<string> = [];
private configFile?: string;
private color?: string;
private args: Array<string> = [];
private pathMappings?: { [key: string]: string };
private workspaceFolder?: string;

public addDirectoryOrFile(directoryOrFile: string): PhpunitArgBuilder {
this.directoryOrFiles.push(directoryOrFile.replace(/\\/gi, "/"));

return this;
}

public addSuite(suiteName: string): PhpunitArgBuilder {
this.suites.push(suiteName);

return this;
}

public addSuites(suiteNames: Array<string>): PhpunitArgBuilder {
this.suites.push(...suiteNames);

return this;
}

public addFilter(filter: string): PhpunitArgBuilder {
this.filters.push(filter);

return this;
}

public addGroup(group: string): PhpunitArgBuilder {
this.groups.push(group);

return this;
}

public addGroups(groups: Array<string>): PhpunitArgBuilder {
this.groups.push(...groups);

return this;
}

public withConfig(configFile: string): PhpunitArgBuilder {
this.configFile = configFile.replace(/\\/gi, "/");

return this;
}

public withColors(color: 'never' | 'auto' | 'always'): PhpunitArgBuilder {
this.color = color;

return this;
}

public addArgs(args: string[]): PhpunitArgBuilder {
this.args.push(...args);

return this;
}

public withPathMappings(pathMappings: { [key: string]: string }, workspaceFolder: string): PhpunitArgBuilder {
this.pathMappings = pathMappings;
this.workspaceFolder = workspaceFolder;

return this;
}

public buildArgs(): Array<string> {
let args = [
this.configFile ? `--configuration ${this.configFile}` : '',
this.color ? `--colors=${this.color}` : '',
this.suites.length > 0 ? `--testsuite ${this.suites.join(',')}` : '',
this.filters.map(filter => `--filter ${filter}`).join(' '),
this.groups.length > 0 ? `--group ${this.groups.join(',')}` : '',
this.args.join(' '),
this.directoryOrFiles.join(' '),
]
.filter(part => part);

if (this.pathMappings) {
for (const key of Object.keys(this.pathMappings)) {
const localPath = key
.replace(/\$\{workspaceFolder\}/gi, this.workspaceFolder!)
.replace(/\\/gi, "/");
const remotePath = this.pathMappings[key];

args = args.map(arg => arg.replace(new RegExp(escapeStringRegexp(localPath), "ig"), remotePath));
}
}

return args.filter(part => part);
}

public build(): string {
return this.buildArgs().join(' ');
}
}
33 changes: 19 additions & 14 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import * as vscode from "vscode";
import { TestRunner } from "./phpunittest";
import { IMyExtensionApi } from "./MyExtensionApi";
import path = require("path");
// import { PhpCodeLensProvider } from "./CodeLens/PhpCodeLensProvider";
// import { PhpunitXmlCodeLensProvider } from "./CodeLens/PhpunitXmlCodeLensProvider";
import { PhpunitArgBuilder } from "./PhpunitCommand/PhpunitArgBuilder";
import { PhpCodeLensProvider } from "./CodeLens/PhpCodeLensProvider";
import { PhpunitXmlCodeLensProvider } from "./CodeLens/PhpunitXmlCodeLensProvider";

export function activate(context: vscode.ExtensionContext): IMyExtensionApi {
const testOutputFile = path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'test-output.txt');
Expand All @@ -30,8 +31,12 @@ export function activate(context: vscode.ExtensionContext): IMyExtensionApi {
});

context.subscriptions.push(
vscode.commands.registerCommand("phpunit.Test", async () => {
return await PHPUnitTestRunner.run("test");
vscode.commands.registerCommand("phpunit.Test", async (argBuilder: PhpunitArgBuilder) => {
if (argBuilder) {
return await PHPUnitTestRunner.runArgs(argBuilder);
} else {
return await PHPUnitTestRunner.run("test");
}
})
);

Expand Down Expand Up @@ -91,16 +96,16 @@ export function activate(context: vscode.ExtensionContext): IMyExtensionApi {
})
);

// context.subscriptions.push(vscode.languages.registerCodeLensProvider({
// language: 'php',
// scheme: 'file',
// pattern: '**/test*/**/*.php'
// }, new PhpCodeLensProvider()));
// context.subscriptions.push(vscode.languages.registerCodeLensProvider({
// language: 'xml',
// scheme: 'file',
// pattern: '**/phpunit.xml*'
// }, new PhpunitXmlCodeLensProvider()));
context.subscriptions.push(vscode.languages.registerCodeLensProvider({
language: 'php',
scheme: 'file',
pattern: '**/test*/**/*.php'
}, new PhpCodeLensProvider()));
context.subscriptions.push(vscode.languages.registerCodeLensProvider({
language: 'xml',
scheme: 'file',
pattern: '**/phpunit.xml*'
}, new PhpunitXmlCodeLensProvider()));

return myExtensionApi;
}
Expand Down
50 changes: 50 additions & 0 deletions src/phpunittest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import IPhpUnitDriver from "./Drivers/IPhpUnitDriver";
import PhpUnitDrivers from "./Drivers/PhpUnitDrivers";
import { IExtensionBootstrapBridge } from "./ExtensionBootstrapBridge";
import parsePhpToObject from "./PhpParser/PhpParser";
import { PhpunitArgBuilder } from "./PhpunitCommand/PhpunitArgBuilder";

type RunType =
| "test"
Expand Down Expand Up @@ -281,6 +282,55 @@ export class TestRunner {
return undefined;
}

public async runArgs(argBuilder: PhpunitArgBuilder) {
const config = vscode.workspace.getConfiguration("phpunit");
const order = config.get<string[]>("driverPriority");

const driver = await this.getDriver(order);
if (!driver) {
console.error(`Wasn't able to start phpunit.`);
return;
}

const configArgs = config.get<string[]>("args", []);
argBuilder.addArgs(configArgs);

const colors = config.get<string>("colors");
if (colors && (configArgs.indexOf(colors) === -1)) {
argBuilder.withColors(colors.replace(/--colors=?/i, '') as 'never' | 'auto' | 'always');
}

const pathMappings = config.get<{ [key: string]: string }>("paths");
if (pathMappings) {
argBuilder.withPathMappings(pathMappings, vscode.workspace.workspaceFolders![0].uri.fsPath);
}

const runConfig = await driver.run(argBuilder.buildArgs());

if (config.get<string>("clearOutputOnRun")) {
this.channel.clear();
}
this.channel.appendLine(`Running phpunit with driver: ${driver.name}`);
this.channel.appendLine(runConfig.command);

this.bootstrapBridge.setTaskCommand(
runConfig.command,
runConfig.problemMatcher
);

if (process.env.VSCODE_PHPUNIT_TEST === 'true') {
console.debug(runConfig.command);
}

await vscode.commands.executeCommand("workbench.action.terminal.clear");
await vscode.commands.executeCommand(
"workbench.action.tasks.runTask",
"phpunit: run"
);

this.channel.show(true);
}

public async run(type: RunType) {
const config = vscode.workspace.getConfiguration("phpunit");
const order = config.get<string[]>("driverPriority");
Expand Down
50 changes: 24 additions & 26 deletions src/test/php-project/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
cacheDirectory=".phpunit.cache">
<coverage>
<!-- <report>
<html outputDirectory="coverage" lowUpperBound="35" highLowerBound="70"/>
<text outputFile="php://stdout" showUncoveredFiles="true"/>
</report> -->
</coverage>
<testsuites>
<testsuite name="Test All">
<directory>./tests</directory>
</testsuite>
<testsuite name="Science">
<directory>./tests/Science</directory>
</testsuite>
</testsuites>
<logging/>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.4/phpunit.xsd"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
executionOrder="depends,defects"
requireCoverageMetadata="true"
beStrictAboutCoverageMetadata="true"
beStrictAboutOutputDuringTests="true"
failOnRisky="false"
failOnWarning="true"
colors="true">
<testsuites>
<testsuite name="Math">
<directory>tests/Math</directory>
</testsuite>
<testsuite name="Science">
<directory>tests/Science</directory>
</testsuite>
</testsuites>

<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
Loading
Loading