1
- /// <reference path="..\harness.ts" />
1
+ /// <reference path="..\harness.ts" />
2
2
/// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
3
3
4
4
namespace ts . projectSystem {
@@ -136,6 +136,19 @@ namespace ts.projectSystem {
136
136
return map ( fileNames , toExternalFile ) ;
137
137
}
138
138
139
+ export class TestServerEventManager {
140
+ private events : server . ProjectServiceEvent [ ] = [ ] ;
141
+
142
+ handler : server . ProjectServiceEventHandler = ( event : server . ProjectServiceEvent ) => {
143
+ this . events . push ( event ) ;
144
+ }
145
+
146
+ checkEventCountOfType ( eventType : "context" | "configFileDiag" , expectedCount : number ) {
147
+ const eventsOfType = filter ( this . events , e => e . eventName === eventType ) ;
148
+ assert . equal ( eventsOfType . length , expectedCount , `The actual event counts of type ${ eventType } is ${ eventsOfType . length } , while expected ${ expectedCount } ` ) ;
149
+ }
150
+ }
151
+
139
152
export interface TestServerHostCreationParameters {
140
153
useCaseSensitiveFileNames ?: boolean ;
141
154
executingFilePath ?: string ;
@@ -159,11 +172,11 @@ namespace ts.projectSystem {
159
172
return host ;
160
173
}
161
174
162
- export function createSession ( host : server . ServerHost , typingsInstaller ?: server . ITypingsInstaller ) {
175
+ export function createSession ( host : server . ServerHost , typingsInstaller ?: server . ITypingsInstaller , projectServiceEventHandler ?: server . ProjectServiceEventHandler ) {
163
176
if ( typingsInstaller === undefined ) {
164
177
typingsInstaller = new TestTypingsInstaller ( "/a/data/" , /*throttleLimit*/ 5 , host ) ;
165
178
}
166
- return new server . Session ( host , nullCancellationToken , /*useSingleInferredProject*/ false , typingsInstaller , Utils . byteLength , process . hrtime , nullLogger , /*canUseEvents*/ false ) ;
179
+ return new server . Session ( host , nullCancellationToken , /*useSingleInferredProject*/ false , typingsInstaller , Utils . byteLength , process . hrtime , nullLogger , /*canUseEvents*/ projectServiceEventHandler !== undefined , projectServiceEventHandler ) ;
167
180
}
168
181
169
182
export interface CreateProjectServiceParameters {
@@ -2084,7 +2097,7 @@ namespace ts.projectSystem {
2084
2097
const projectFileName = "externalProject" ;
2085
2098
const host = createServerHost ( [ f ] ) ;
2086
2099
const projectService = createProjectService ( host ) ;
2087
- // create a project
2100
+ // create a project
2088
2101
projectService . openExternalProject ( { projectFileName, rootFiles : [ toExternalFile ( f . path ) ] , options : { } } ) ;
2089
2102
projectService . checkNumberOfProjects ( { externalProjects : 1 } ) ;
2090
2103
@@ -2121,4 +2134,179 @@ namespace ts.projectSystem {
2121
2134
projectService . inferredProjects [ 0 ] . getLanguageService ( ) . getProgram ( ) ;
2122
2135
} ) ;
2123
2136
} ) ;
2137
+
2138
+ describe ( "rename a module file and rename back" , ( ) => {
2139
+ it ( "should restore the states for inferred projects" , ( ) => {
2140
+ const moduleFile = {
2141
+ path : "/a/b/moduleFile.ts" ,
2142
+ content : "export function bar() { };"
2143
+ } ;
2144
+ const file1 = {
2145
+ path : "/a/b/file1.ts" ,
2146
+ content : "import * as T from './moduleFile'; T.bar();"
2147
+ } ;
2148
+ const host = createServerHost ( [ moduleFile , file1 ] ) ;
2149
+ const session = createSession ( host ) ;
2150
+
2151
+ openFilesForSession ( [ file1 ] , session ) ;
2152
+ const getErrRequest = makeSessionRequest < server . protocol . SemanticDiagnosticsSyncRequestArgs > (
2153
+ server . CommandNames . SemanticDiagnosticsSync ,
2154
+ { file : file1 . path }
2155
+ ) ;
2156
+ let diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2157
+ assert . equal ( diags . length , 0 ) ;
2158
+
2159
+ const moduleFileOldPath = moduleFile . path ;
2160
+ const moduleFileNewPath = "/a/b/moduleFile1.ts" ;
2161
+ moduleFile . path = moduleFileNewPath ;
2162
+ host . reloadFS ( [ moduleFile , file1 ] ) ;
2163
+ host . triggerFileWatcherCallback ( moduleFileOldPath ) ;
2164
+ host . triggerDirectoryWatcherCallback ( "/a/b" , moduleFile . path ) ;
2165
+ host . runQueuedTimeoutCallbacks ( ) ;
2166
+ diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2167
+ assert . equal ( diags . length , 1 ) ;
2168
+
2169
+ moduleFile . path = moduleFileOldPath ;
2170
+ host . reloadFS ( [ moduleFile , file1 ] ) ;
2171
+ host . triggerFileWatcherCallback ( moduleFileNewPath ) ;
2172
+ host . triggerDirectoryWatcherCallback ( "/a/b" , moduleFile . path ) ;
2173
+ host . runQueuedTimeoutCallbacks ( ) ;
2174
+
2175
+ // Make a change to trigger the program rebuild
2176
+ const changeRequest = makeSessionRequest < server . protocol . ChangeRequestArgs > (
2177
+ server . CommandNames . Change ,
2178
+ { file : file1 . path , line : 1 , offset : 44 , endLine : 1 , endOffset : 44 , insertString : "\n" }
2179
+ ) ;
2180
+ session . executeCommand ( changeRequest ) ;
2181
+ host . runQueuedTimeoutCallbacks ( ) ;
2182
+
2183
+ diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2184
+ assert . equal ( diags . length , 0 ) ;
2185
+ } ) ;
2186
+
2187
+ it ( "should restore the states for configured projects" , ( ) => {
2188
+ const moduleFile = {
2189
+ path : "/a/b/moduleFile.ts" ,
2190
+ content : "export function bar() { };"
2191
+ } ;
2192
+ const file1 = {
2193
+ path : "/a/b/file1.ts" ,
2194
+ content : "import * as T from './moduleFile'; T.bar();"
2195
+ } ;
2196
+ const configFile = {
2197
+ path : "/a/b/tsconfig.json" ,
2198
+ content : `{}`
2199
+ } ;
2200
+ const host = createServerHost ( [ moduleFile , file1 , configFile ] ) ;
2201
+ const session = createSession ( host ) ;
2202
+
2203
+ openFilesForSession ( [ file1 ] , session ) ;
2204
+ const getErrRequest = makeSessionRequest < server . protocol . SemanticDiagnosticsSyncRequestArgs > (
2205
+ server . CommandNames . SemanticDiagnosticsSync ,
2206
+ { file : file1 . path }
2207
+ ) ;
2208
+ let diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2209
+ assert . equal ( diags . length , 0 ) ;
2210
+
2211
+ const moduleFileOldPath = moduleFile . path ;
2212
+ const moduleFileNewPath = "/a/b/moduleFile1.ts" ;
2213
+ moduleFile . path = moduleFileNewPath ;
2214
+ host . reloadFS ( [ moduleFile , file1 , configFile ] ) ;
2215
+ host . triggerFileWatcherCallback ( moduleFileOldPath ) ;
2216
+ host . triggerDirectoryWatcherCallback ( "/a/b" , moduleFile . path ) ;
2217
+ host . runQueuedTimeoutCallbacks ( ) ;
2218
+ diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2219
+ assert . equal ( diags . length , 1 ) ;
2220
+
2221
+ moduleFile . path = moduleFileOldPath ;
2222
+ host . reloadFS ( [ moduleFile , file1 , configFile ] ) ;
2223
+ host . triggerFileWatcherCallback ( moduleFileNewPath ) ;
2224
+ host . triggerDirectoryWatcherCallback ( "/a/b" , moduleFile . path ) ;
2225
+ host . runQueuedTimeoutCallbacks ( ) ;
2226
+ diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2227
+ assert . equal ( diags . length , 0 ) ;
2228
+ } ) ;
2229
+
2230
+ } ) ;
2231
+
2232
+ describe ( "add the missing module file for inferred project" , ( ) => {
2233
+ it ( "should remove the `module not found` error" , ( ) => {
2234
+ const moduleFile = {
2235
+ path : "/a/b/moduleFile.ts" ,
2236
+ content : "export function bar() { };"
2237
+ } ;
2238
+ const file1 = {
2239
+ path : "/a/b/file1.ts" ,
2240
+ content : "import * as T from './moduleFile'; T.bar();"
2241
+ } ;
2242
+ const host = createServerHost ( [ file1 ] ) ;
2243
+ const session = createSession ( host ) ;
2244
+ openFilesForSession ( [ file1 ] , session ) ;
2245
+ const getErrRequest = makeSessionRequest < server . protocol . SemanticDiagnosticsSyncRequestArgs > (
2246
+ server . CommandNames . SemanticDiagnosticsSync ,
2247
+ { file : file1 . path }
2248
+ ) ;
2249
+ let diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2250
+ assert . equal ( diags . length , 1 ) ;
2251
+
2252
+ host . reloadFS ( [ file1 , moduleFile ] ) ;
2253
+ host . triggerDirectoryWatcherCallback ( getDirectoryPath ( file1 . path ) , moduleFile . path ) ;
2254
+ host . runQueuedTimeoutCallbacks ( ) ;
2255
+
2256
+ // Make a change to trigger the program rebuild
2257
+ const changeRequest = makeSessionRequest < server . protocol . ChangeRequestArgs > (
2258
+ server . CommandNames . Change ,
2259
+ { file : file1 . path , line : 1 , offset : 44 , endLine : 1 , endOffset : 44 , insertString : "\n" }
2260
+ ) ;
2261
+ session . executeCommand ( changeRequest ) ;
2262
+
2263
+ // Recheck
2264
+ diags = < server . protocol . Diagnostic [ ] > session . executeCommand ( getErrRequest ) . response ;
2265
+ assert . equal ( diags . length , 0 ) ;
2266
+ } ) ;
2267
+ } ) ;
2268
+
2269
+ describe ( "Configure file diagnostics events" , ( ) => {
2270
+
2271
+ it ( "are generated when the config file has errors" , ( ) => {
2272
+ const serverEventManager = new TestServerEventManager ( ) ;
2273
+ const file = {
2274
+ path : "/a/b/app.ts" ,
2275
+ content : "let x = 10"
2276
+ } ;
2277
+ const configFile = {
2278
+ path : "/a/b/tsconfig.json" ,
2279
+ content : `{
2280
+ "compilerOptions": {
2281
+ "foo": "bar",
2282
+ "allowJS": true
2283
+ }
2284
+ }`
2285
+ } ;
2286
+
2287
+ const host = createServerHost ( [ file , configFile ] ) ;
2288
+ const session = createSession ( host , /*typingsInstaller*/ undefined , serverEventManager . handler ) ;
2289
+ openFilesForSession ( [ file ] , session ) ;
2290
+ serverEventManager . checkEventCountOfType ( "configFileDiag" , 1 ) ;
2291
+ } ) ;
2292
+
2293
+ it ( "are generated when the config file doesn't have errors" , ( ) => {
2294
+ const serverEventManager = new TestServerEventManager ( ) ;
2295
+ const file = {
2296
+ path : "/a/b/app.ts" ,
2297
+ content : "let x = 10"
2298
+ } ;
2299
+ const configFile = {
2300
+ path : "/a/b/tsconfig.json" ,
2301
+ content : `{
2302
+ "compilerOptions": {}
2303
+ }`
2304
+ } ;
2305
+
2306
+ const host = createServerHost ( [ file , configFile ] ) ;
2307
+ const session = createSession ( host , /*typingsInstaller*/ undefined , serverEventManager . handler ) ;
2308
+ openFilesForSession ( [ file ] , session ) ;
2309
+ serverEventManager . checkEventCountOfType ( "configFileDiag" , 1 ) ;
2310
+ } ) ;
2311
+ } ) ;
2124
2312
}
0 commit comments