Skip to content

Commit 3bbe056

Browse files
authored
Merge pull request #34 from phpactor/test
Add test runner
2 parents c3d926c + eb93a1c commit 3bbe056

File tree

9 files changed

+9135
-4311
lines changed

9 files changed

+9135
-4311
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,20 @@
1-
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
2-
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3-
4-
name: Node.js CI
5-
1+
name: Test Extension
62
on:
73
push:
8-
branches: [ master ]
4+
branches:
5+
- master
96
pull_request:
107
branches: [ master ]
118

129
jobs:
1310
build:
14-
1511
runs-on: ubuntu-latest
16-
17-
strategy:
18-
matrix:
19-
node-version: [17.x]
20-
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21-
2212
steps:
23-
- uses: actions/checkout@v3
24-
- name: Use Node.js ${{ matrix.node-version }}
25-
uses: actions/setup-node@v3
13+
- name: Checkout
14+
uses: actions/checkout@v2
15+
- name: Install Node.js
16+
uses: actions/setup-node@v2
2617
with:
27-
node-version: ${{ matrix.node-version }}
28-
cache: 'npm'
29-
- run: npm ci
30-
- run: npm run build --if-present
31-
- run: npm test
18+
node-version: 14
19+
- run: npm install
20+
- run: xvfb-run -a npm test

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
lib
22
.vscode
33
node_modules
4+
.vscode-test

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Phpactor VSCode Extension
2-
======================
2+
=========================
33

44
![phpactor2sm](https://user-images.githubusercontent.com/530801/27995098-82e72c4c-64c0-11e7-96d2-f549c711ca8b.png)
55

@@ -9,8 +9,6 @@ with [VSCode](https://github.com/neoclide/coc.nvim).
99
Installation
1010
------------
1111

12-
First, install [Phpactor](https://phpactor.readthedocs.io/en/develop/usage/standalone.html).
13-
1412
The package isn't published yet on the "marketplace" so:
1513

1614
1. Install [yarn](https://classic.yarnpkg.com/en/docs/install) and [npm](https://www.npmjs.com/get-npm).
@@ -26,6 +24,7 @@ Phpactor should then be enabled the next time you start VS code.
2624
Commands
2725
--------
2826

27+
- `phpactor.update`: Update Phpactor to the latest version
2928
- `phpactor.status`: Show Phpactor's status
3029
- `phpactor.reindex`: Reindex the project.
3130
- `phpactor.services.list`: List Phpactor's currently running services.

package-lock.json

Lines changed: 8953 additions & 4272 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@
1515
"scripts": {
1616
"clean": "rimraf lib",
1717
"build": "tsc -p tsconfig.json",
18-
"prepare": "yarn clean && yarn build"
18+
"prepare": "yarn clean && yarn build",
19+
"watch": "tsc -watch -p ./",
20+
"pretest": "npm run compile",
21+
"compile": "tsc -p ./",
22+
"test": "node ./lib/test/runTests.js"
1923
},
2024
"activationEvents": [
2125
"onLanguage:php"
2226
],
2327
"contributes": {
2428
"commands": [
29+
{
30+
"command": "phpactor.update",
31+
"title": "Update Phpactor to the latest version"
32+
},
2533
{
2634
"command": "phpactor.reindex",
2735
"title": "Phpactor: Reindex the project."
@@ -43,8 +51,8 @@
4351
"title": "phpactor config",
4452
"properties": {
4553
"phpactor.path": {
46-
"type": "string",
47-
"default": "phpactor",
54+
"type": "string|null",
55+
"default": null,
4856
"description": "phpactor bin path"
4957
},
5058
"phpactor.enable": {
@@ -66,15 +74,24 @@
6674
"devDependencies": {
6775
"@chemzqm/tsconfig": "^0.0.3",
6876
"@chemzqm/tslint-config": "^1.0.18",
77+
"@types/glob": "^7.1.1",
78+
"@types/mocha": "^9.1.0",
6979
"@types/node": "^11.13.10",
7080
"@types/vscode": "1.43.0",
81+
"@typescript-eslint/eslint-plugin": "^5.19.0",
82+
"@typescript-eslint/parser": "^5.19.0",
83+
"@vscode/test-electron": "^2.1.3",
84+
"eslint": "^8.13.0",
85+
"glob": "^7.1.4",
86+
"mocha": "^9.2.2",
7187
"rimraf": "~3.0.2",
88+
"source-map-support": "^0.5.12",
7289
"ts-loader": "~8.0.2",
7390
"tslib": "^2.1.0",
7491
"tslint": "^5.16.0",
75-
"typescript": "~3.9.7",
76-
"webpack": "^4.34.0",
92+
"typescript": "^4.6.3",
7793
"vscode-test": "~1.4.0",
94+
"webpack": "^4.34.0",
7895
"webpack-cli": "^3.3.4"
7996
},
8097
"dependencies": {

src/extension.ts

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import {
55
} from "vscode-languageclient";
66

77
import * as vscode from "vscode";
8+
import { spawn } from "child_process";
9+
import { existsSync, mkdir, mkdirSync } from "fs";
10+
import { basename, dirname } from "path";
811

912
const LanguageID = 'php';
1013

@@ -15,10 +18,13 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
1518
const config = workspaceConfig.get("phpactor") as any;
1619
const enable = config.enable;
1720

21+
if (!config.path) {
22+
config.path = await installPhpactor(context.globalStoragePath)
23+
}
24+
1825
if (enable === false) return;
1926

2027
languageClient = createClient(config);
21-
2228
languageClient.start();
2329
}
2430

@@ -60,26 +66,27 @@ function createClient(config: any): LanguageClient {
6066
clientOptions
6167
);
6268

63-
6469
vscode.commands.registerCommand('phpactor.reindex', reindex);
6570
vscode.commands.registerCommand('phpactor.config.dump', dumpConfig);
6671
vscode.commands.registerCommand('phpactor.services.list', servicesList);
6772
vscode.commands.registerCommand('phpactor.status', status);
73+
const updateConfig = {cwd: dirname(dirname(config.path))}
74+
vscode.commands.registerCommand('phpactor.update', updatePhpactor, updateConfig);
6875

6976
return languageClient;
7077
}
7178

7279
function reindex(): void {
73-
if(!languageClient) {
74-
return;
80+
if(!languageClient) {
81+
return;
7582
}
7683

7784
languageClient.sendRequest('indexer/reindex');
7885
}
7986

8087
async function dumpConfig(): Promise<void> {
81-
if(!languageClient) {
82-
return;
88+
if(!languageClient) {
89+
return;
8390
}
8491

8592
const channel = vscode.window.createOutputChannel('Phpactor Config')
@@ -89,20 +96,74 @@ async function dumpConfig(): Promise<void> {
8996
}
9097

9198
function servicesList(): void {
92-
if(!languageClient) {
93-
return;
99+
if(!languageClient) {
100+
return;
94101
}
95102

96103
languageClient.sendRequest('service/running');
97104
}
98105

99106
async function status(): Promise<any> {
100-
if(!languageClient) {
101-
return;
107+
if(!languageClient) {
108+
return;
102109
}
103110

104111
const channel = vscode.window.createOutputChannel('Phpactor Status')
105112
const result = await languageClient.sendRequest<string>('phpactor/status');
106113
channel.append(result)
107114
channel.show()
108115
}
116+
117+
async function installPhpactor(storagePath: string): Promise<string> {
118+
const channel = vscode.window.createOutputChannel("Phpactor Installation")
119+
vscode.window.showInformationMessage("Installing Phpactor")
120+
if (!existsSync(storagePath)) {
121+
mkdirSync(storagePath)
122+
}
123+
124+
const path = `${storagePath}/phpactor`
125+
126+
if (!existsSync(path)) {
127+
await exec(channel, 'git', ['clone', 'https://github.com/phpactor/phpactor', '--depth=1'], storagePath)
128+
await exec(channel, 'composer', ['install', '--no-dev'], path)
129+
vscode.window.showInformationMessage(`Phpactor installed at ${path}`)
130+
}
131+
132+
return `${storagePath}/phpactor/bin/phpactor`
133+
}
134+
135+
export async function updatePhpactor(): Promise<void> {
136+
const channel = vscode.window.createOutputChannel('Phpactor Update')
137+
channel.appendLine(this.cwd)
138+
await exec(channel, 'git', ['pull'], this.cwd)
139+
await exec(channel, 'composer', ['install', '--no-dev'], this.cwd)
140+
channel.appendLine("Phpactor updated")
141+
vscode.window.showInformationMessage("Phpactor updated")
142+
}
143+
144+
145+
function exec(channel: vscode.OutputChannel, command: string, args: string[], cwd: string): Promise<void> {
146+
return new Promise(function (resolve, reject) {
147+
148+
const child = spawn(command, args, {
149+
cwd: cwd,
150+
timeout: 30000,
151+
})
152+
child.stdout.on('data', function (data) {
153+
channel.append(data.toString('utf8'))
154+
})
155+
child.stderr.on('data', function (data) {
156+
channel.append(data.toString('utf8'))
157+
})
158+
child.on('close', function (code) {
159+
if (code !== 0) {
160+
reject(`Expected git to exit with code 0 got "${code}"`)
161+
}
162+
resolve()
163+
});
164+
165+
child.on('error', function (err) {
166+
reject(err)
167+
});
168+
})
169+
}

src/test/runTests.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import * as path from 'path';
2+
3+
import { runTests } from '@vscode/test-electron';
4+
5+
async function main() {
6+
try {
7+
// The folder containing the Extension Manifest package.json
8+
// Passed to `--extensionDevelopmentPath`
9+
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
10+
11+
// The path to the extension test script
12+
// Passed to --extensionTestsPath
13+
const extensionTestsPath = path.resolve(__dirname, './suite/index');
14+
15+
// Download VS Code, unzip it and run the integration test
16+
await runTests({ extensionDevelopmentPath, extensionTestsPath });
17+
} catch (err) {
18+
console.error('Failed to run tests');
19+
process.exit(1);
20+
}
21+
}
22+
23+
main();

src/test/suite/extension.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as assert from 'assert';
2+
3+
// You can import and use all API from the 'vscode' module
4+
// as well as import your extension to test it
5+
import * as vscode from 'vscode';
6+
import * as myExtension from '../../extension';
7+
8+
suite('Extension Test Suite', () => {
9+
test('Extension is present', async () => {
10+
assert.ok(vscode.extensions.getExtension("dantleech.vscode-phpactor"));
11+
});
12+
test('Extension activates', async () => {
13+
await vscode.extensions.getExtension("dantleech.vscode-phpactor")?.activate();
14+
});
15+
});

src/test/suite/index.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
;import * as path from 'path';
2+
import Mocha from 'mocha';
3+
import glob from 'glob';
4+
5+
export function run(): Promise<void> {
6+
// Create the mocha test
7+
const mocha = new Mocha({
8+
ui: 'tdd',
9+
timeout: 30000
10+
});
11+
12+
const testsRoot = path.resolve(__dirname, '..');
13+
14+
return new Promise((c, e) => {
15+
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
16+
if (err) {
17+
return e(err);
18+
}
19+
20+
// Add files to the test suite
21+
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
22+
23+
try {
24+
// Run the mocha test
25+
mocha.run(failures => {
26+
if (failures > 0) {
27+
e(new Error(`${failures} tests failed.`));
28+
} else {
29+
c();
30+
}
31+
});
32+
} catch (err) {
33+
console.error(err);
34+
e(err);
35+
}
36+
});
37+
});
38+
}

0 commit comments

Comments
 (0)