Skip to content

Commit 5291de4

Browse files
committed
Initial tests
1 parent 032809d commit 5291de4

File tree

222 files changed

+31135
-28
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

222 files changed

+31135
-28
lines changed

.eslintrc.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
"ecmaVersion": 6,
66
"sourceType": "module"
77
},
8-
"plugins": [
9-
"@typescript-eslint"
10-
],
8+
"plugins": ["@typescript-eslint"],
119
"rules": {
1210
"@typescript-eslint/naming-convention": [
1311
"warn",
1412
{
1513
"selector": "import",
16-
"format": [ "camelCase", "PascalCase" ]
14+
"format": ["camelCase", "PascalCase"]
1715
}
1816
],
1917
"@typescript-eslint/semi": "warn",
@@ -22,9 +20,5 @@
2220
"no-throw-literal": "warn",
2321
"semi": "off"
2422
},
25-
"ignorePatterns": [
26-
"out",
27-
"dist",
28-
"**/*.d.ts"
29-
]
30-
}
23+
"ignorePatterns": ["out", "dist", "**/*.d.ts", "src/test/fixtures"]
24+
}

.github/workflows/tests.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Tests
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- reopened
8+
- synchronize
9+
10+
jobs:
11+
extension-tests:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: 20
22+
cache: npm
23+
24+
- name: Setup PHP
25+
uses: shivammathur/setup-php@v2
26+
with:
27+
php-version: "8.3"
28+
tools: composer:v2
29+
30+
- name: Install extension dependencies
31+
run: npm ci
32+
33+
- name: Install Laravel fixture dependencies
34+
run: composer install --no-interaction --prefer-dist --no-progress
35+
working-directory: src/test/fixtures/laravel-react
36+
37+
- name: Run extension test suite
38+
run: npm test

.vscode-test.mjs

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
import { defineConfig } from "@vscode/test-cli";
22

3-
export default defineConfig([
4-
{
5-
label: "unitTests",
6-
files: "out/test/**/*.test.js",
7-
version: "insiders",
8-
workspaceFolder: "./sampleWorkspace",
9-
mocha: {
10-
ui: "tdd",
11-
timeout: 20000,
12-
},
3+
export default defineConfig({
4+
files: "out/test/**/*.test.js",
5+
workspaceFolder: "./src/test/fixtures/laravel-react",
6+
mocha: {
7+
ui: "tdd",
8+
timeout: 20000,
139
},
14-
// you can specify additional test configurations, too
15-
]);
16-
17-
// export default defineConfig({
18-
// files: 'out/test/**/*.test.js',
19-
// });
10+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@
11421142
}
11431143
},
11441144
"scripts": {
1145-
"pretest": "npm run compile && npm run lint",
1145+
"pretest": "npm run compile && tsc && npm run lint",
11461146
"lint": "eslint src --ext ts",
11471147
"format": "prettier --write \"src/**/*.{ts,js,json,md}\"",
11481148
"test": "vscode-test",

src/test/app-binding.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import * as vscode from "vscode";
2+
import { assertCompletions, assertHovers, assertLinks } from "./assertions";
3+
import { activateExtension, uri } from "./helper";
4+
5+
suite("App Binding Test Suite", () => {
6+
suiteSetup(async () => {
7+
await activateExtension();
8+
});
9+
10+
test("provides app binding completions", async () => {
11+
await assertCompletions({
12+
doc: await vscode.workspace.openTextDocument(
13+
uri("app/app-binding.php"),
14+
),
15+
lines: [
16+
"app('test.binding');",
17+
"app()->make('test.binding.alt');",
18+
"app()->bound('test.binding');",
19+
"App::make('test.binding.alt');",
20+
"App::bound('test.binding');",
21+
"App::isShared('test.binding.alt');",
22+
],
23+
expects: ["test.binding", "test.binding.alt"],
24+
});
25+
});
26+
27+
test("provides links for app bindings", async () => {
28+
await assertLinks({
29+
doc: await vscode.workspace.openTextDocument(
30+
uri("app/app-binding.php"),
31+
),
32+
lines: [
33+
{
34+
line: "app('test.binding');",
35+
target: "app/Providers/AppBindingTestServiceProvider.php",
36+
},
37+
{
38+
line: "app()->make('test.binding.alt');",
39+
target: "app/Providers/AppBindingTestServiceProvider.php",
40+
},
41+
{
42+
line: "app()->bound('test.binding');",
43+
target: "app/Providers/AppBindingTestServiceProvider.php",
44+
},
45+
{
46+
line: "App::make('test.binding.alt');",
47+
target: "app/Providers/AppBindingTestServiceProvider.php",
48+
},
49+
{
50+
line: "App::bound('test.binding');",
51+
target: "app/Providers/AppBindingTestServiceProvider.php",
52+
},
53+
{
54+
line: "App::isShared('test.binding.alt');",
55+
target: "app/Providers/AppBindingTestServiceProvider.php",
56+
},
57+
],
58+
});
59+
});
60+
61+
test("provides app binding hover details", async () => {
62+
await assertHovers({
63+
doc: await vscode.workspace.openTextDocument(
64+
uri("app/app-binding.php"),
65+
),
66+
lines: [
67+
{
68+
line: "app('test.binding');",
69+
contains: [
70+
"AppBindingTestServiceProvider",
71+
"app/Providers/AppBindingTestServiceProvider.php",
72+
],
73+
},
74+
{
75+
line: "app()->make('test.binding.alt');",
76+
contains: [
77+
"AppBindingTestServiceProvider",
78+
"app/Providers/AppBindingTestServiceProvider.php",
79+
],
80+
},
81+
],
82+
});
83+
});
84+
});

src/test/assertions.ts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import * as assert from "assert";
2+
import * as vscode from "vscode";
3+
import { getCompletions, getHovers, getLinks, hoverToText } from "./helper";
4+
5+
type AssertCompletionsOptions = {
6+
doc: vscode.TextDocument;
7+
lines: string[];
8+
expects: string[];
9+
};
10+
11+
export async function assertCompletions({
12+
doc,
13+
lines,
14+
expects,
15+
}: AssertCompletionsOptions): Promise<void> {
16+
const text = doc.getText();
17+
18+
for (const line of lines) {
19+
const lineIndex = text.indexOf(line);
20+
21+
assert.ok(
22+
lineIndex !== -1,
23+
`Could not find test case '${line}' in fixture`,
24+
);
25+
26+
const match = line.match(/'([^']+)'/);
27+
28+
assert.ok(match, `Could not extract quoted value from '${line}'`);
29+
30+
const value = match[1];
31+
const valueOffset = lineIndex + line.indexOf(value);
32+
const completions = await getCompletions(
33+
doc,
34+
doc.positionAt(valueOffset),
35+
);
36+
37+
const labels = completions.items.map((entry) =>
38+
typeof entry.label === "string" ? entry.label : entry.label.label,
39+
);
40+
41+
for (const expected of expects) {
42+
assert.ok(
43+
labels.some((label) => label.includes(expected)),
44+
`Case '${line}': Should suggest '${expected}'. Got: ${labels.join(", ")}`,
45+
);
46+
}
47+
}
48+
}
49+
50+
export async function assertLinks({
51+
doc,
52+
lines,
53+
}: {
54+
doc: vscode.TextDocument;
55+
lines: {
56+
line: string;
57+
target: string;
58+
argument?: string;
59+
}[];
60+
}): Promise<void> {
61+
const text = doc.getText();
62+
const links = await getLinks(doc);
63+
64+
assert.ok(links.length > 0, "Expected links to be provided");
65+
66+
for (const item of lines) {
67+
const lineIndex = text.indexOf(item.line);
68+
69+
assert.ok(
70+
lineIndex !== -1,
71+
`Could not find link case '${item.line}' in fixture`,
72+
);
73+
74+
const selector = item.argument ?? item.line.match(/'([^']+)'/)?.[1];
75+
76+
if (!selector) {
77+
assert.fail(
78+
`Could not extract selector from '${item.line}'. Provide 'argument' explicitly for this case.`,
79+
);
80+
}
81+
82+
const selectorOffset = lineIndex + item.line.indexOf(selector);
83+
84+
const matchedLink = links.find((link) => {
85+
return (
86+
selectorOffset >= doc.offsetAt(link.range.start) &&
87+
selectorOffset < doc.offsetAt(link.range.end)
88+
);
89+
});
90+
91+
assert.ok(
92+
matchedLink?.target,
93+
`Case '${item.line}': Expected link target`,
94+
);
95+
96+
assert.ok(
97+
matchedLink?.target?.fsPath.includes(item.target),
98+
`Case '${item.line}': Expected link target to include '${item.target}'. Got: ${matchedLink?.target?.toString()}`,
99+
);
100+
}
101+
}
102+
103+
export async function assertHovers({
104+
doc,
105+
lines,
106+
}: {
107+
doc: vscode.TextDocument;
108+
lines: {
109+
line: string;
110+
contains: string[];
111+
argument?: string;
112+
}[];
113+
}): Promise<void> {
114+
const text = doc.getText();
115+
116+
for (const item of lines) {
117+
const lineIndex = text.indexOf(item.line);
118+
119+
assert.ok(
120+
lineIndex !== -1,
121+
`Could not find hover case '${item.line}' in fixture`,
122+
);
123+
124+
const selector = item.argument ?? item.line.match(/'([^']+)'/)?.[1];
125+
126+
if (!selector) {
127+
assert.fail(
128+
`Could not extract selector from '${item.line}'. Provide 'argument' explicitly for this case.`,
129+
);
130+
}
131+
132+
const selectorOffset = lineIndex + item.line.indexOf(selector);
133+
const hovers = await getHovers(doc, doc.positionAt(selectorOffset + 1));
134+
135+
assert.ok(
136+
hovers.length > 0,
137+
`Case '${item.line}': Expected hover information`,
138+
);
139+
140+
const hoverText = hoverToText(hovers[0]);
141+
142+
for (const expected of item.contains) {
143+
assert.ok(
144+
hoverText.includes(expected),
145+
`Case '${item.line}': Expected hover to include '${expected}'. Got: ${hoverText}`,
146+
);
147+
}
148+
}
149+
}

src/test/asset.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as vscode from "vscode";
2+
import { assertCompletions, assertLinks } from "./assertions";
3+
import { activateExtension, uri } from "./helper";
4+
5+
suite("Asset Test Suite", () => {
6+
suiteSetup(async () => {
7+
await activateExtension();
8+
});
9+
10+
test("provides asset completions", async () => {
11+
await assertCompletions({
12+
doc: await vscode.workspace.openTextDocument(
13+
uri("app/asset-helper.php"),
14+
),
15+
lines: [
16+
"asset('robots.txt');",
17+
"asset('favicon.svg');",
18+
"asset('build/manifest.json');",
19+
],
20+
expects: ["robots.txt", "favicon.svg"],
21+
});
22+
});
23+
24+
test("provides links for assets", async () => {
25+
await assertLinks({
26+
doc: await vscode.workspace.openTextDocument(
27+
uri("app/asset-helper.php"),
28+
),
29+
lines: [
30+
{
31+
line: "asset('robots.txt');",
32+
target: "public/robots.txt",
33+
},
34+
{
35+
line: "asset('favicon.svg');",
36+
target: "public/favicon.svg",
37+
},
38+
{
39+
line: "asset('build/manifest.json');",
40+
target: "public/build/manifest.json",
41+
},
42+
],
43+
});
44+
});
45+
});

0 commit comments

Comments
 (0)