@@ -480,6 +480,10 @@ namespace ts.projectSystem {
480480 checkNthEvent ( session , server . toEvent ( eventName , diagnostics ) , 0 , isMostRecent ) ;
481481 }
482482
483+ function createDiagnostic ( start : protocol . Location , end : protocol . Location , message : DiagnosticMessage , args : ReadonlyArray < string > = [ ] , category = diagnosticCategoryName ( message ) , reportsUnnecessary ?: { } ) : protocol . Diagnostic {
484+ return { start, end, text : formatStringFromArgs ( message . message , args ) , code : message . code , category, reportsUnnecessary, source : undefined } ;
485+ }
486+
483487 function checkCompleteEvent ( session : TestSession , numberOfCurrentEvents : number , expectedSequenceId : number , isMostRecent = true ) : void {
484488 checkNthEvent ( session , server . toEvent ( "requestCompleted" , { request_seq : expectedSequenceId } ) , numberOfCurrentEvents - 1 , isMostRecent ) ;
485489 }
@@ -496,7 +500,7 @@ namespace ts.projectSystem {
496500
497501 function checkNthEvent ( session : TestSession , expectedEvent : protocol . Event , index : number , isMostRecent : boolean ) {
498502 const events = session . events ;
499- assert . deepEqual ( events [ index ] , expectedEvent ) ;
503+ assert . deepEqual ( events [ index ] , expectedEvent , `Expected ${ JSON . stringify ( expectedEvent ) } at ${ index } in ${ JSON . stringify ( events ) } ` ) ;
500504
501505 const outputs = session . host . getOutput ( ) ;
502506 assert . equal ( outputs [ index ] , server . formatMessage ( expectedEvent , nullLogger , Utils . byteLength , session . host . newLine ) ) ;
@@ -3333,6 +3337,89 @@ namespace ts.projectSystem {
33333337 checkCompleteEvent ( session , 1 , expectedSequenceId ) ;
33343338 session . clearMessages ( ) ;
33353339 } ) ;
3340+
3341+ it ( "Reports errors correctly when file referenced by inferred project root, is opened right after closing the root file" , ( ) => {
3342+ const projectRoot = "/user/username/projects/myproject" ;
3343+ const app : FileOrFolder = {
3344+ path : `${ projectRoot } /src/client/app.js` ,
3345+ content : ""
3346+ } ;
3347+ const serverUtilities : FileOrFolder = {
3348+ path : `${ projectRoot } /src/server/utilities.js` ,
3349+ content : `function getHostName() { return "hello"; } export { getHostName };`
3350+ } ;
3351+ const backendTest : FileOrFolder = {
3352+ path : `${ projectRoot } /test/backend/index.js` ,
3353+ content : `import { getHostName } from '../../src/server/utilities';export default getHostName;`
3354+ } ;
3355+ const files = [ libFile , app , serverUtilities , backendTest ] ;
3356+ const host = createServerHost ( files ) ;
3357+ const session = createSession ( host , { useInferredProjectPerProjectRoot : true , canUseEvents : true } ) ;
3358+ session . executeCommandSeq < protocol . OpenRequest > ( {
3359+ command : protocol . CommandTypes . Open ,
3360+ arguments : {
3361+ file : app . path ,
3362+ projectRootPath : projectRoot
3363+ }
3364+ } ) ;
3365+ const service = session . getProjectService ( ) ;
3366+ checkNumberOfProjects ( service , { inferredProjects : 1 } ) ;
3367+ const project = service . inferredProjects [ 0 ] ;
3368+ checkProjectActualFiles ( project , [ libFile . path , app . path ] ) ;
3369+ session . executeCommandSeq < protocol . OpenRequest > ( {
3370+ command : protocol . CommandTypes . Open ,
3371+ arguments : {
3372+ file : backendTest . path ,
3373+ projectRootPath : projectRoot
3374+ }
3375+ } ) ;
3376+ checkNumberOfProjects ( service , { inferredProjects : 1 } ) ;
3377+ checkProjectActualFiles ( project , files . map ( f => f . path ) ) ;
3378+ checkErrors ( [ backendTest . path , app . path ] ) ;
3379+ session . executeCommandSeq < protocol . CloseRequest > ( {
3380+ command : protocol . CommandTypes . Close ,
3381+ arguments : {
3382+ file : backendTest . path
3383+ }
3384+ } ) ;
3385+ session . executeCommandSeq < protocol . OpenRequest > ( {
3386+ command : protocol . CommandTypes . Open ,
3387+ arguments : {
3388+ file : serverUtilities . path ,
3389+ projectRootPath : projectRoot
3390+ }
3391+ } ) ;
3392+ checkErrors ( [ serverUtilities . path , app . path ] ) ;
3393+
3394+ function checkErrors ( openFiles : [ string , string ] ) {
3395+ const expectedSequenceId = session . getNextSeq ( ) ;
3396+ session . executeCommandSeq < protocol . GeterrRequest > ( {
3397+ command : protocol . CommandTypes . Geterr ,
3398+ arguments : {
3399+ delay : 0 ,
3400+ files : openFiles
3401+ }
3402+ } ) ;
3403+
3404+ for ( const openFile of openFiles ) {
3405+ session . clearMessages ( ) ;
3406+ host . checkTimeoutQueueLength ( 3 ) ;
3407+ host . runQueuedTimeoutCallbacks ( host . getNextTimeoutId ( ) - 1 ) ;
3408+
3409+ checkErrorMessage ( session , "syntaxDiag" , { file : openFile , diagnostics : [ ] } ) ;
3410+ session . clearMessages ( ) ;
3411+
3412+ host . runQueuedImmediateCallbacks ( ) ;
3413+ checkErrorMessage ( session , "semanticDiag" , { file : openFile , diagnostics : [ ] } ) ;
3414+ session . clearMessages ( ) ;
3415+
3416+ host . runQueuedImmediateCallbacks ( 1 ) ;
3417+ checkErrorMessage ( session , "suggestionDiag" , { file : openFile , diagnostics : [ ] } ) ;
3418+ }
3419+ checkCompleteEvent ( session , 2 , expectedSequenceId ) ;
3420+ session . clearMessages ( ) ;
3421+ }
3422+ } ) ;
33363423 } ) ;
33373424
33383425 describe ( "tsserverProjectSystem autoDiscovery" , ( ) => {
@@ -4293,10 +4380,6 @@ namespace ts.projectSystem {
42934380
42944381 session . clearMessages ( ) ;
42954382 } ) ;
4296-
4297- function createDiagnostic ( start : protocol . Location , end : protocol . Location , message : DiagnosticMessage , args : ReadonlyArray < string > = [ ] , category = diagnosticCategoryName ( message ) , reportsUnnecessary ?: { } ) : protocol . Diagnostic {
4298- return { start, end, text : formatStringFromArgs ( message . message , args ) , code : message . code , category, reportsUnnecessary, source : undefined } ;
4299- }
43004383 } ) ;
43014384
43024385 describe ( "tsserverProjectSystem Configure file diagnostics events" , ( ) => {
0 commit comments