11import assert from 'assert' ;
22import { spawnSync } from 'child_process' ;
3- import { existsSync , renameSync } from 'fs' ;
3+ import { existsSync , opendirSync , renameSync } from 'fs' ;
44import path from 'path' ;
55import * as vscode from 'vscode' ;
66import { SemanticTokensParams , SemanticTokensRequest , integer } from 'vscode-languageclient' ;
77import { contextClients } from '../../src/extension' ;
88import { assertEqualToFileContent , update } from './utils' ;
99
10- suite ( 'Semantic Highlighting' , function ( ) {
10+ suite ( 'Highlighting' , function ( ) {
1111 this . beforeAll ( async function ( ) {
1212 await activate ( ) ;
1313 } ) ;
@@ -16,34 +16,75 @@ suite('Semantic Highlighting', function () {
1616 await vscode . commands . executeCommand ( 'workbench.action.closeActiveEditor' ) ;
1717 } ) ;
1818
19- suite ( 'test1' , function ( ) {
20- const relFilePath = 'src/gnatpp.adb' ;
19+ const highlightingTestRoot = getDocUri ( 'highlighing' ) . fsPath ;
20+ const adaFilePaths : string [ ] = [ ] ;
2121
22- test ( 'syntax.main' , function ( ) {
23- testSyntaxHighlighting ( relFilePath , 'syntaxes' ) ;
24- } ) ;
22+ function walk ( dir : string ) {
23+ const openDir = opendirSync ( dir ) ;
24+ try {
25+ let child ;
26+ while ( ( child = openDir . readSync ( ) ) != null ) {
27+ const childPath = path . join ( dir , child . name ) ;
28+ if ( child . isDirectory ( ) ) {
29+ walk ( childPath ) ;
30+ } else if ( child . isFile ( ) ) {
31+ if ( child . name . match ( / \. a d [ b s ] $ / ) ) {
32+ adaFilePaths . push ( childPath ) ;
33+ }
34+ }
35+ }
36+ } finally {
37+ openDir . closeSync ( ) ;
38+ }
39+ }
2540
26- test ( 'syntax.advanced' , function ( ) {
27- testSyntaxHighlighting ( relFilePath , 'advanced' ) ;
28- } ) ;
41+ walk ( highlightingTestRoot ) ;
2942
30- test ( 'semantic' , async function ( ) {
31- await testSemanticHighlighting ( relFilePath ) ;
43+ for ( const absPath of adaFilePaths ) {
44+ const relFilePath = path . relative ( highlightingTestRoot , absPath ) ;
45+ const testName = relFilePath ;
46+ const absFileUri = vscode . Uri . file ( absPath ) ;
47+
48+ suite ( testName , function ( ) {
49+ test ( 'syntax.main' , function ( ) {
50+ testSyntaxHighlighting ( absPath , 'syntaxes' ) ;
51+ } ) ;
52+
53+ test ( 'syntax.advanced' , function ( ) {
54+ testSyntaxHighlighting ( absPath , 'advanced' ) ;
55+ } ) ;
56+
57+ test ( 'semantic' , async function ( ) {
58+ await testSemanticHighlighting ( absFileUri ) ;
59+ } ) ;
3260 } ) ;
33- } ) ;
61+ }
3462} ) ;
3563
36- async function testSemanticHighlighting ( relFilePath : string ) {
37- const docUri = getDocUri ( relFilePath ) ;
38- const expFilePath = `${ relFilePath } .sem.tokens` ;
39- const expectedUri = getDocUri ( expFilePath ) ;
64+ /**
65+ * This function runs a semantic highlighting test on the given Ada source file
66+ * Uri. The test works as follows:
67+ *
68+ * 1. A SemanticTokensRequest is sent to the ALS for the given input Uri
69+ *
70+ * 2. The tokens received from the ALS are converted to a string representation
71+ * that helps assess the result in comparison with the source file
72+ *
73+ * 3. The string representation is compared to a test reference stored as a file
74+ * next to the original source file. The convention is to append '.sem.tokens'
75+ * to the original file name.
76+ *
77+ * @param docUri - a Uri to an Ada source file to apply semantic highlighting
78+ * testing to
79+ */
80+ async function testSemanticHighlighting ( docUri : vscode . Uri ) {
81+ const expectedUri = docUri . with ( { path : docUri . path + '.sem.tokens' } ) ;
4082
4183 const initResult = contextClients . adaClient . initializeResult ;
4284 const legend = initResult ?. capabilities . semanticTokensProvider ?. legend ;
4385
4486 assert ( legend ) ;
4587
46- // console.debug('Legend: ' + JSON.stringify(legend, null, 4));
4788 const doc = await vscode . workspace . openTextDocument ( docUri ) ;
4889
4990 const request : SemanticTokensParams = {
@@ -53,7 +94,6 @@ async function testSemanticHighlighting(relFilePath: string) {
5394 SemanticTokensRequest . type ,
5495 request
5596 ) ;
56- // console.debug('Semantic Tokens: ' + JSON.stringify(semanticTokens, null, 4));
5797 const data = semanticTokens ?. data || [ ] ;
5898 type TokenInfo = {
5999 line : integer ;
@@ -146,12 +186,20 @@ const extensionRootPath = path.resolve(__dirname, '../../../');
146186
147187type Syntaxes = 'syntaxes' | 'advanced' ;
148188
149- function testSyntaxHighlighting ( relFilePath : string , syntax : Syntaxes ) {
189+ /**
190+ * This function runs a syntax highlighting test on the given Ada source file
191+ * using the chose TextMate grammar. The test relies on the
192+ * vscode-tmgrammar-snap tool which operates on a preexisting test reference
193+ * file (aka a snapshot) and reports differences wrt that reference.
194+ *
195+ * @param absFilePath - an Ada source file to apply syntax highlighting to
196+ * @param syntax - the selected TextMate grammar to use for the test
197+ */
198+ function testSyntaxHighlighting ( absFilePath : string , syntax : Syntaxes ) {
150199 const syntaxPath = path . join ( extensionRootPath , syntax , 'ada.tmLanguage.json' ) ;
151200
152- const basename = path . basename ( relFilePath ) ;
153- const adaFilePath = getDocUri ( relFilePath ) . fsPath ;
154- const workDirPath = path . dirname ( adaFilePath ) ;
201+ const basename = path . basename ( absFilePath ) ;
202+ const workDirPath = path . dirname ( absFilePath ) ;
155203
156204 /*
157205 * vscode-tmgrammar-snap works with .snap files, but since we're testing two
@@ -176,7 +224,22 @@ function testSyntaxHighlighting(relFilePath: string, syntax: Syntaxes) {
176224 ) ;
177225 }
178226
179- const cmd = [ 'vscode-tmgrammar-snap' , '-g' , syntaxPath , '-s' , 'source.ada' , adaFilePath ] ;
227+ const cmd = [
228+ 'vscode-tmgrammar-snap' ,
229+ // We pass a non-existing language configuration, otherwise the tool
230+ // picks up the package.json file and always loads the grammar in
231+ // use.
232+ '--config' ,
233+ 'none' ,
234+ // Show diffs on separate lines because color coding isn't visible
235+ // in the VS Code debug console.
236+ '--expandDiff' ,
237+ '-g' ,
238+ syntaxPath ,
239+ '-s' ,
240+ 'source.ada' ,
241+ absFilePath ,
242+ ] ;
180243
181244 if ( update ( ) ) {
182245 cmd . push ( '--updateSnapshot' ) ;
0 commit comments