1
- import { strictEqual } from 'assert' ;
1
+ import { deepStrictEqual , strictEqual } from 'assert' ;
2
2
import * as path from 'path' ;
3
3
4
- import * as vscode from 'vscode' ;
4
+ import { glob } from 'glob' ;
5
+ import {
6
+ commands ,
7
+ Diagnostic ,
8
+ DiagnosticSeverity ,
9
+ Position ,
10
+ Range ,
11
+ TextDocument ,
12
+ Uri ,
13
+ window ,
14
+ workspace ,
15
+ } from 'vscode' ;
5
16
6
17
import {
7
18
CleanLintDiagnostics ,
8
19
CleanLintFiles ,
9
20
InitLint ,
10
21
RescanLint ,
11
22
} from '../../src/commands/commands' ;
23
+ import {
24
+ GNULinter ,
25
+ GNUModernLinter ,
26
+ IntelLinter ,
27
+ LFortranLinter ,
28
+ NAGLinter ,
29
+ } from '../../src/lint/compilers' ;
12
30
import { FortranLintingProvider } from '../../src/lint/provider' ;
31
+ import { LogLevel , Logger } from '../../src/services/logging' ;
32
+ import { EXTENSION_ID , pipInstall } from '../../src/util/tools' ;
13
33
14
- suite ( 'Linter' , async ( ) => {
15
- let doc : vscode . TextDocument ;
16
- const fileUri = vscode . Uri . file ( path . resolve ( __dirname , '../../../test/fortran/sample.f90' ) ) ;
34
+ suite ( 'Linter VS Code commands ' , async ( ) => {
35
+ let doc : TextDocument ;
36
+ const fileUri = Uri . file ( path . resolve ( __dirname , '../../../test/fortran/sample.f90' ) ) ;
17
37
const linter = new FortranLintingProvider ( ) ;
18
38
19
39
suiteSetup ( async ( ) => {
20
- doc = await vscode . workspace . openTextDocument ( fileUri ) ;
21
- await vscode . window . showTextDocument ( doc ) ;
40
+ doc = await workspace . openTextDocument ( fileUri ) ;
41
+ await window . showTextDocument ( doc ) ;
22
42
} ) ;
23
43
24
44
test ( 'Check disposables array has been populated' , async ( ) => {
@@ -27,19 +47,19 @@ suite('Linter', async () => {
27
47
} ) ;
28
48
29
49
// test(`Run command ${InitLint}`, async () => {
30
- // await vscode. commands.executeCommand(InitLint);
50
+ // await commands.executeCommand(InitLint);
31
51
// });
32
52
33
53
test ( `Run command is ${ RescanLint } ` , async ( ) => {
34
- await vscode . commands . executeCommand ( RescanLint ) ;
54
+ await commands . executeCommand ( RescanLint ) ;
35
55
} ) ;
36
56
37
57
test ( `Run command ${ CleanLintDiagnostics } ` , async ( ) => {
38
- await vscode . commands . executeCommand ( CleanLintDiagnostics ) ;
58
+ await commands . executeCommand ( CleanLintDiagnostics ) ;
39
59
} ) ;
40
60
41
61
test ( `Run command ${ CleanLintFiles } ` , async ( ) => {
42
- await vscode . commands . executeCommand ( CleanLintFiles ) ;
62
+ await commands . executeCommand ( CleanLintFiles ) ;
43
63
} ) ;
44
64
45
65
test ( 'Check disposables have been cleared' , ( ) => {
@@ -49,11 +69,133 @@ suite('Linter', async () => {
49
69
50
70
test ( 'Check file association overrides propagate to the linter' , async ( ) => {
51
71
const file = '../../../test/fortran/lint/fixed-as-free.f77' ;
52
- const fileUri = vscode . Uri . file ( path . resolve ( __dirname , file ) ) ;
53
- doc = await vscode . workspace . openTextDocument ( fileUri ) ;
54
- await vscode . window . showTextDocument ( doc ) ;
72
+ const fileUri = Uri . file ( path . resolve ( __dirname , file ) ) ;
73
+ doc = await workspace . openTextDocument ( fileUri ) ;
74
+ await window . showTextDocument ( doc ) ;
55
75
const res = await linter [ 'doLint' ] ( doc ) ;
56
76
strictEqual ( res !== undefined , true ) ;
57
77
strictEqual ( res ?. length , 0 ) ;
58
78
} ) ;
59
79
} ) ;
80
+
81
+ const logger = new Logger ( window . createOutputChannel ( 'Modern Fortran' , 'log' ) , LogLevel . DEBUG ) ;
82
+
83
+ suite ( 'Linter integration' , async ( ) => {
84
+ let doc : TextDocument ;
85
+ const linter = new FortranLintingProvider ( logger ) ;
86
+ const fileUri = Uri . file ( path . resolve ( __dirname , '../../../test/fortran/lint/test1.f90' ) ) ;
87
+ const root = path . resolve ( __dirname , '../../../test/fortran/' ) ;
88
+ const config = workspace . getConfiguration ( EXTENSION_ID ) ;
89
+ const oldVals = config . get < string [ ] > ( 'linter.includePaths' ) ;
90
+
91
+ suiteSetup ( async ( ) => {
92
+ doc = await workspace . openTextDocument ( fileUri ) ;
93
+ await window . showTextDocument ( doc ) ;
94
+ } ) ;
95
+ // different versions of gfortran report the error at a different column number
96
+ // need to implement a the compiler versioning see #523
97
+ test ( 'GNU - API call to doLint produces correct diagnostics' , async ( ) => {
98
+ const diags = await new FortranLintingProvider ( logger ) [ 'doLint' ] ( doc ) ;
99
+ const ref : Diagnostic [ ] = [
100
+ new Diagnostic (
101
+ new Range ( new Position ( 21 - 1 , 18 - 1 ) , new Position ( 21 - 1 , 18 - 1 ) ) ,
102
+ 'Syntax error in argument list at (1)' ,
103
+ DiagnosticSeverity . Error
104
+ ) ,
105
+ new Diagnostic (
106
+ new Range ( new Position ( 7 - 1 , 9 - 1 ) , new Position ( 7 - 1 , 9 - 1 ) ) ,
107
+ "Type specified for intrinsic function 'size' at (1) is ignored [-Wsurprising]" ,
108
+ DiagnosticSeverity . Warning
109
+ ) ,
110
+ ] ;
111
+
112
+ deepStrictEqual ( diags , ref ) ;
113
+ } ) ;
114
+
115
+ test ( 'Include path globs & internal variable resolution' , async ( ) => {
116
+ const paths = linter [ 'getGlobPathsFromSettings' ] ( 'linter.includePaths' ) ;
117
+ // const refs: string[] = fg.sync(path.dirname(fileUri.path) + '/**', { onlyDirectories: true });
118
+ const refs : string [ ] = glob . sync ( path . dirname ( fileUri . path ) + '/**/' ) ;
119
+ deepStrictEqual ( paths , refs ) ;
120
+ } ) ;
121
+
122
+ test ( 'Path cache contains expected values' , async ( ) => {
123
+ let refs : string [ ] = [ '${workspaceFolder}/lint/**' ] ;
124
+ deepStrictEqual ( linter [ 'pathCache' ] . get ( 'linter.includePaths' ) ?. globs , refs ) ;
125
+ // refs = fg.sync(path.join(root, 'lint') + '/**', { onlyDirectories: true });
126
+ refs = glob . sync ( path . join ( root , 'lint' ) + '/**/' ) ;
127
+ deepStrictEqual ( linter [ 'pathCache' ] . get ( 'linter.includePaths' ) ?. paths , refs ) ;
128
+ } ) ;
129
+
130
+ test ( 'Update paths using cache' , async ( ) => {
131
+ // const refs: string[] = fg.sync([path.join(root, 'lint') + '/**', path.join(root, 'debug')], {
132
+ // onlyDirectories: true,
133
+ // });
134
+ const refs : string [ ] = [ path . join ( root , 'lint' ) + '/**' , path . join ( root , 'debug' ) ]
135
+ . map ( d => glob . sync ( d + '/' ) )
136
+ . flat ( ) ;
137
+ await config . update (
138
+ 'linter.includePaths' ,
139
+ [ '${workspaceFolder}/lint/**' , path . join ( root , 'debug' ) ] ,
140
+ false
141
+ ) ;
142
+ const paths = linter [ 'getGlobPathsFromSettings' ] ( 'linter.includePaths' ) ;
143
+ deepStrictEqual ( paths , refs ) ;
144
+ } ) ;
145
+
146
+ test ( 'Linter user setting returns the right linter internally' , ( ) => {
147
+ const names = [ 'gfortran' , 'ifort' , 'ifx' , 'nagfor' , 'lfortran' , 'fake' ] ;
148
+ for ( const n of names ) {
149
+ const compiler = linter [ 'getLinter' ] ( n ) ;
150
+ if ( n === 'gfortran' ) {
151
+ if ( linter [ 'settings' ] . modernGNU ) {
152
+ strictEqual ( compiler instanceof GNUModernLinter , true ) ;
153
+ } else {
154
+ strictEqual ( compiler instanceof GNULinter , true ) ;
155
+ }
156
+ } else if ( n === 'ifort' || n === 'ifx' ) {
157
+ strictEqual ( compiler instanceof IntelLinter , true ) ;
158
+ } else if ( n === 'nagfor' ) {
159
+ strictEqual ( compiler instanceof NAGLinter , true ) ;
160
+ } else if ( n == 'lfortran' ) {
161
+ strictEqual ( compiler instanceof LFortranLinter , true ) ;
162
+ } else {
163
+ strictEqual ( compiler instanceof GNULinter , true ) ;
164
+ }
165
+ }
166
+ } ) ;
167
+
168
+ suiteTeardown ( async function ( ) : Promise < void > {
169
+ await config . update ( 'linter.includePaths' , oldVals , false ) ;
170
+ } ) ;
171
+ } ) ;
172
+
173
+ suite ( 'Linter (fypp) integration' , ( ) => {
174
+ const root = path . resolve ( __dirname , '../../../test/fortran/' ) ;
175
+ const config = workspace . getConfiguration ( EXTENSION_ID ) ;
176
+
177
+ suiteSetup ( async ( ) => {
178
+ await pipInstall ( 'fypp' ) ;
179
+ await config . update ( `linter.fypp.enabled` , true , false ) ;
180
+ } ) ;
181
+
182
+ test ( 'GNU - API call to doLint produces correct diagnostics' , async ( ) => {
183
+ const fileUri = Uri . file ( path . resolve ( __dirname , '../../../test/fortran/fypp/demo.fypp' ) ) ;
184
+ const doc = await workspace . openTextDocument ( fileUri ) ;
185
+ await window . showTextDocument ( doc ) ;
186
+
187
+ const diags = await new FortranLintingProvider ( logger ) [ 'doLint' ] ( doc ) ;
188
+ const refs : Diagnostic [ ] = [
189
+ new Diagnostic (
190
+ new Range ( new Position ( 18 , 35 ) , new Position ( 18 , 35 ) ) ,
191
+ "Unused dummy argument 'this' at (1) [-Wunused-dummy-argument]" ,
192
+ DiagnosticSeverity . Warning
193
+ ) ,
194
+ ] ;
195
+ deepStrictEqual ( diags , refs ) ;
196
+ } ) ;
197
+
198
+ suiteTeardown ( async ( ) => {
199
+ await config . update ( `linter.fypp.enabled` , false , false ) ;
200
+ } ) ;
201
+ } ) ;
0 commit comments