1+ /// <reference path="../harness.ts" />
2+ /// <reference path="./tsserverProjectSystem.ts" />
3+ /// <reference path="../../server/typingsInstaller/typingsInstaller.ts" />
4+
5+ namespace ts . projectSystem {
6+ describe ( "Project errors" , ( ) => {
7+ function checkProjectErrors ( projectFiles : server . ProjectFilesWithTSDiagnostics , expectedErrors : string [ ] ) {
8+ assert . isTrue ( projectFiles !== undefined , "missing project files" ) ;
9+ const errors = projectFiles . projectErrors ;
10+ assert . equal ( errors ? errors . length : 0 , expectedErrors . length , `expected ${ expectedErrors . length } error in the list` ) ;
11+ if ( expectedErrors . length ) {
12+ for ( let i = 0 ; i < errors . length ; i ++ ) {
13+ const actualMessage = flattenDiagnosticMessageText ( errors [ i ] . messageText , "\n" ) ;
14+ const expectedMessage = expectedErrors [ i ] ;
15+ assert . isTrue ( actualMessage . indexOf ( expectedMessage ) === 0 , `error message does not match, expected ${ actualMessage } to start with ${ expectedMessage } ` ) ;
16+ }
17+ }
18+ }
19+
20+ it ( "external project - diagnostics for missing files" , ( ) => {
21+ const file1 = {
22+ path : "/a/b/app.ts" ,
23+ content : ""
24+ } ;
25+ const file2 = {
26+ path : "/a/b/lib.ts" ,
27+ content : ""
28+ } ;
29+ // only file1 exists - expect error
30+ const host = createServerHost ( [ file1 ] ) ;
31+ const projectService = createProjectService ( host ) ;
32+ const projectFileName = "/a/b/test.csproj" ;
33+
34+ {
35+ projectService . openExternalProject ( {
36+ projectFileName,
37+ options : { } ,
38+ rootFiles : toExternalFiles ( [ file1 . path , file2 . path ] )
39+ } ) ;
40+
41+ projectService . checkNumberOfProjects ( { externalProjects : 1 } ) ;
42+ const knownProjects = projectService . synchronizeProjectList ( [ ] ) ;
43+ checkProjectErrors ( knownProjects [ 0 ] , [ "File '/a/b/lib.ts' not found." ] ) ;
44+ }
45+ // only file2 exists - expect error
46+ host . reloadFS ( [ file2 ] ) ;
47+ {
48+ projectService . openExternalProject ( {
49+ projectFileName,
50+ options : { } ,
51+ rootFiles : toExternalFiles ( [ file1 . path , file2 . path ] )
52+ } ) ;
53+ projectService . checkNumberOfProjects ( { externalProjects : 1 } ) ;
54+ const knownProjects = projectService . synchronizeProjectList ( [ ] ) ;
55+ checkProjectErrors ( knownProjects [ 0 ] , [ "File '/a/b/app.ts' not found." ] ) ;
56+ }
57+
58+ // both files exist - expect no errors
59+ host . reloadFS ( [ file1 , file2 ] ) ;
60+ {
61+ projectService . openExternalProject ( {
62+ projectFileName,
63+ options : { } ,
64+ rootFiles : toExternalFiles ( [ file1 . path , file2 . path ] )
65+ } ) ;
66+
67+ projectService . checkNumberOfProjects ( { externalProjects : 1 } ) ;
68+ const knownProjects = projectService . synchronizeProjectList ( [ ] ) ;
69+ checkProjectErrors ( knownProjects [ 0 ] , [ ] ) ;
70+ }
71+ } ) ;
72+
73+ it ( "configured projects - diagnostics for missing files" , ( ) => {
74+ const file1 = {
75+ path : "/a/b/app.ts" ,
76+ content : ""
77+ } ;
78+ const file2 = {
79+ path : "/a/b/lib.ts" ,
80+ content : ""
81+ } ;
82+ const config = {
83+ path : "/a/b/tsconfig.json" ,
84+ content : JSON . stringify ( { files : [ file1 , file2 ] . map ( f => getBaseFileName ( f . path ) ) } )
85+ } ;
86+ const host = createServerHost ( [ file1 , config ] ) ;
87+ const projectService = createProjectService ( host ) ;
88+
89+ projectService . openClientFile ( file1 . path ) ;
90+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
91+ checkProjectErrors ( projectService . synchronizeProjectList ( [ ] ) [ 0 ] , [ "File '/a/b/lib.ts' not found." ] ) ;
92+
93+ host . reloadFS ( [ file1 , file2 , config ] ) ;
94+
95+ projectService . openClientFile ( file1 . path ) ;
96+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
97+ checkProjectErrors ( projectService . synchronizeProjectList ( [ ] ) [ 0 ] , [ ] ) ;
98+ } ) ;
99+
100+ it ( "configured projects - diagnostics for corrupted config 1" , ( ) => {
101+ const file1 = {
102+ path : "/a/b/app.ts" ,
103+ content : ""
104+ } ;
105+ const file2 = {
106+ path : "/a/b/lib.ts" ,
107+ content : ""
108+ } ;
109+ const correctConfig = {
110+ path : "/a/b/tsconfig.json" ,
111+ content : JSON . stringify ( { files : [ file1 , file2 ] . map ( f => getBaseFileName ( f . path ) ) } )
112+ } ;
113+ const corruptedConfig = {
114+ path : correctConfig . path ,
115+ content : correctConfig . content . substr ( 1 )
116+ } ;
117+ const host = createServerHost ( [ file1 , file2 , corruptedConfig ] ) ;
118+ const projectService = createProjectService ( host ) ;
119+
120+ projectService . openClientFile ( file1 . path ) ;
121+ {
122+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
123+ const configuredProject = forEach ( projectService . synchronizeProjectList ( [ ] ) , f => f . info . projectName === corruptedConfig . path && f ) ;
124+ assert . isTrue ( configuredProject !== undefined , "should find configured project" ) ;
125+ checkProjectErrors ( configuredProject , [
126+ "')' expected." ,
127+ "Declaration or statement expected." ,
128+ "Declaration or statement expected." ,
129+ "Failed to parse file '/a/b/tsconfig.json'"
130+ ] ) ;
131+ }
132+ // fix config and trigger watcher
133+ host . reloadFS ( [ file1 , file2 , correctConfig ] ) ;
134+ host . triggerFileWatcherCallback ( correctConfig . path , /*false*/ ) ;
135+ {
136+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
137+ const configuredProject = forEach ( projectService . synchronizeProjectList ( [ ] ) , f => f . info . projectName === corruptedConfig . path && f ) ;
138+ assert . isTrue ( configuredProject !== undefined , "should find configured project" ) ;
139+ checkProjectErrors ( configuredProject , [ ] ) ;
140+ }
141+ } ) ;
142+
143+ it ( "configured projects - diagnostics for corrupted config 2" , ( ) => {
144+ const file1 = {
145+ path : "/a/b/app.ts" ,
146+ content : ""
147+ } ;
148+ const file2 = {
149+ path : "/a/b/lib.ts" ,
150+ content : ""
151+ } ;
152+ const correctConfig = {
153+ path : "/a/b/tsconfig.json" ,
154+ content : JSON . stringify ( { files : [ file1 , file2 ] . map ( f => getBaseFileName ( f . path ) ) } )
155+ } ;
156+ const corruptedConfig = {
157+ path : correctConfig . path ,
158+ content : correctConfig . content . substr ( 1 )
159+ } ;
160+ const host = createServerHost ( [ file1 , file2 , correctConfig ] ) ;
161+ const projectService = createProjectService ( host ) ;
162+
163+ projectService . openClientFile ( file1 . path ) ;
164+ {
165+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
166+ const configuredProject = forEach ( projectService . synchronizeProjectList ( [ ] ) , f => f . info . projectName === corruptedConfig . path && f ) ;
167+ assert . isTrue ( configuredProject !== undefined , "should find configured project" ) ;
168+ checkProjectErrors ( configuredProject , [ ] ) ;
169+ }
170+ // break config and trigger watcher
171+ host . reloadFS ( [ file1 , file2 , corruptedConfig ] ) ;
172+ host . triggerFileWatcherCallback ( corruptedConfig . path , /*false*/ ) ;
173+ {
174+ projectService . checkNumberOfProjects ( { configuredProjects : 1 } ) ;
175+ const configuredProject = forEach ( projectService . synchronizeProjectList ( [ ] ) , f => f . info . projectName === corruptedConfig . path && f ) ;
176+ assert . isTrue ( configuredProject !== undefined , "should find configured project" ) ;
177+ checkProjectErrors ( configuredProject , [
178+ "')' expected." ,
179+ "Declaration or statement expected." ,
180+ "Declaration or statement expected." ,
181+ "Failed to parse file '/a/b/tsconfig.json'"
182+ ] ) ;
183+ }
184+ } ) ;
185+ } ) ;
186+ }
0 commit comments