Skip to content

Commit 38c05b5

Browse files
committed
Create TM syntax highlighting test infrastructure
1 parent 9226ecb commit 38c05b5

File tree

3 files changed

+102
-8
lines changed

3 files changed

+102
-8
lines changed

integration/vscode/ada/test/suite/highlighting.test.ts

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import assert from 'assert';
2+
import { spawnSync } from 'child_process';
3+
import { existsSync, renameSync } from 'fs';
4+
import path from 'path';
25
import * as vscode from 'vscode';
36
import { SemanticTokensParams, SemanticTokensRequest, integer } from 'vscode-languageclient';
47
import { contextClients } from '../../src/extension';
5-
import { assertEqualToFileContent } from './utils';
8+
import { assertEqualToFileContent, update } from './utils';
69

710
suite('Semantic Highlighting', function () {
811
this.beforeAll(async function () {
@@ -13,19 +16,28 @@ suite('Semantic Highlighting', function () {
1316
await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
1417
});
1518

16-
test('test1', async function () {
19+
suite('test1', function () {
1720
const relFilePath = 'src/gnatpp.adb';
18-
await testFile(relFilePath);
21+
22+
test('syntax.main', function () {
23+
testSyntaxHighlighting(relFilePath, 'syntaxes');
24+
});
25+
26+
test('syntax.advanced', function () {
27+
testSyntaxHighlighting(relFilePath, 'advanced');
28+
});
29+
30+
test('semantic', async function () {
31+
await testSemanticHighlighting(relFilePath);
32+
});
1933
});
2034
});
2135

22-
async function testFile(relFilePath: string) {
36+
async function testSemanticHighlighting(relFilePath: string) {
2337
const docUri = getDocUri(relFilePath);
2438
const expFilePath = `${relFilePath}.sem.tokens`;
2539
const expectedUri = getDocUri(expFilePath);
2640

27-
// const doc = await vscode.workspace.openTextDocument(docUri);
28-
// await vscode.window.showTextDocument(doc);
2941
const initResult = contextClients.adaClient.initializeResult;
3042
const legend = initResult?.capabilities.semanticTokensProvider?.legend;
3143

@@ -129,3 +141,71 @@ function getDocUri(path: string): vscode.Uri {
129141
assert(vscode.workspace.workspaceFolders !== undefined);
130142
return vscode.Uri.joinPath(vscode.workspace.workspaceFolders[0].uri, path);
131143
}
144+
145+
const extensionRootPath = path.resolve(__dirname, '../../../');
146+
147+
type Syntaxes = 'syntaxes' | 'advanced';
148+
149+
function testSyntaxHighlighting(relFilePath: string, syntax: Syntaxes) {
150+
const syntaxPath = path.join(extensionRootPath, syntax, 'ada.tmLanguage.json');
151+
152+
const basename = path.basename(relFilePath);
153+
const adaFilePath = getDocUri(relFilePath).fsPath;
154+
const workDirPath = path.dirname(adaFilePath);
155+
156+
/*
157+
* vscode-tmgrammar-snap works with .snap files, but since we're testing two
158+
* grammars, the snapshots are stored as .snap.<syntax-name> files. Before
159+
* calling vscode-tmgrammar-snap, the test will rename the
160+
* .snap.<syntax-name> file to .snap and rename it back after.
161+
*/
162+
const workSnapPath = path.join(workDirPath, `${basename}.snap`);
163+
const refSnapPath = `${workSnapPath}.${syntax}`;
164+
165+
try {
166+
if (existsSync(refSnapPath)) {
167+
// Rename .snap.<syntax> --> .snap
168+
renameSync(refSnapPath, workSnapPath);
169+
} else if (!update()) {
170+
// Complain if the reference snapshot doesn't exist, except if we're
171+
// running in update mode, in which case the test will create the
172+
// snapshot.
173+
throw Error(
174+
`Could not find reference snapshot: ${refSnapPath}\n` +
175+
'Re-run testsuite in update mode to create a snapshot.'
176+
);
177+
}
178+
179+
const cmd = ['vscode-tmgrammar-snap', '-g', syntaxPath, '-s', 'source.ada', adaFilePath];
180+
181+
if (update()) {
182+
cmd.push('--updateSnapshot');
183+
}
184+
185+
const proc = spawnSync(cmd[0], cmd.slice(1));
186+
187+
if (proc.error) {
188+
// proc.error is set if we fail to spawn the child process
189+
throw proc.error;
190+
}
191+
192+
if (proc.status === null) {
193+
const msg =
194+
`Null return code for command: ${cmd.join(' ')}\n` +
195+
String(proc.stdout) +
196+
String(proc.stderr);
197+
assert.fail(msg);
198+
} else if (proc.status != 0) {
199+
const msg =
200+
`Return code ${proc.status.toString()} for command: ${cmd.join(' ')}\n` +
201+
String(proc.stdout) +
202+
String(proc.stderr);
203+
assert.fail(msg);
204+
}
205+
} finally {
206+
if (existsSync(workSnapPath)) {
207+
// Rename .snap --> .snap.<syntax>
208+
renameSync(workSnapPath, refSnapPath);
209+
}
210+
}
211+
}

integration/vscode/ada/test/suite/index.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { Glob, GlobOptionsWithFileTypesUnset } from 'glob';
22
import Mocha, { MochaOptions } from 'mocha';
3-
import { resolve } from 'path';
3+
import path, { resolve } from 'path';
44
import { env } from 'process';
55

66
export function run(): Promise<void> {
7+
// Make package executables visible
8+
const extensionRootPath = path.resolve(__dirname, '../../../');
9+
const nodeModulesBin = path.join(extensionRootPath, 'node_modules', '.bin');
10+
process.env.PATH = `${nodeModulesBin}${path.delimiter}${process.env.PATH as string}`;
11+
712
const mochaOptions: MochaOptions = {
813
ui: 'tdd',
914
color: true,

integration/vscode/ada/test/suite/utils.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import * as vscode from 'vscode';
1313
* @param expectedUri - path to the file containing the expected output
1414
*/
1515
export function assertEqualToFileContent(actual: string, expectedUri: vscode.Uri) {
16-
if (process.env.MOCHA_ALS_UPDATE) {
16+
if (update()) {
1717
writeFileSync(expectedUri.fsPath, actual);
1818
} else {
1919
if (!existsSync(expectedUri.fsPath)) {
@@ -24,3 +24,12 @@ export function assertEqualToFileContent(actual: string, expectedUri: vscode.Uri
2424
assert.strictEqual(actual, expected);
2525
}
2626
}
27+
28+
/**
29+
*
30+
* @returns true if the testsuite is running in update mode, i.e. the
31+
* environment variable MOCHA_ALS_UPDATE is set
32+
*/
33+
export function update(): boolean {
34+
return process.env.MOCHA_ALS_UPDATE ? true : false;
35+
}

0 commit comments

Comments
 (0)