@@ -933,4 +933,118 @@ console.log(blabla);`
933
933
} ) ;
934
934
} ) ;
935
935
} ) ;
936
+
937
+ describe ( "unittests:: tsserver:: Project Errors with npm install when" , ( ) => {
938
+ function verifyNpmInstall ( timeoutDuringPartialInstallation : boolean ) {
939
+ const main : File = {
940
+ path : `${ tscWatch . projectRoot } /src/main.ts` ,
941
+ content : "import * as _a from '@angular/core';"
942
+ } ;
943
+ const config : File = {
944
+ path : `${ tscWatch . projectRoot } /tsconfig.json` ,
945
+ content : "{}"
946
+ } ;
947
+ const projectFiles = [ main , libFile , config ] ;
948
+ const host = createServerHost ( projectFiles ) ;
949
+ const session = createSession ( host , { canUseEvents : true } ) ;
950
+ const service = session . getProjectService ( ) ;
951
+ openFilesForSession ( [ { file : main , projectRootPath : tscWatch . projectRoot } ] , session ) ;
952
+ const span = protocolTextSpanFromSubstring ( main . content , `'@angular/core'` ) ;
953
+ const moduleNotFoundErr : protocol . Diagnostic [ ] = [
954
+ createDiagnostic (
955
+ span . start ,
956
+ span . end ,
957
+ Diagnostics . Cannot_find_module_0 ,
958
+ [ "@angular/core" ]
959
+ )
960
+ ] ;
961
+ const expectedRecursiveWatches = arrayToMap ( [ `${ tscWatch . projectRoot } ` , `${ tscWatch . projectRoot } /src` , `${ tscWatch . projectRoot } /node_modules` , `${ tscWatch . projectRoot } /node_modules/@types` ] , identity , ( ) => 1 ) ;
962
+ verifyProject ( ) ;
963
+ verifyErrors ( moduleNotFoundErr ) ;
964
+
965
+ let npmInstallComplete = false ;
966
+
967
+ // Simulate npm install
968
+ let filesAndFoldersToAdd : ( File | Folder ) [ ] = [
969
+ { path : `${ tscWatch . projectRoot } /node_modules` } , // This should queue update
970
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging` } ,
971
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/@babel` } ,
972
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/@babel/helper-plugin-utils-a06c629f` } ,
973
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/core-js-db53158d` } ,
974
+ ] ;
975
+ verifyWhileNpmInstall ( { timeouts : 2 , semantic : moduleNotFoundErr } ) ;
976
+
977
+ filesAndFoldersToAdd = [
978
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/@angular/platform-browser-dynamic-5efaaa1a` } ,
979
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/@angular/cli-c1e44b05/models/analytics.d.ts` , content : `export const x = 10;` } ,
980
+ { path : `${ tscWatch . projectRoot } /node_modules/.staging/@angular/core-0963aebf/index.d.ts` , content : `export const y = 10;` } ,
981
+ ] ;
982
+ // Since we added/removed in .staging no timeout
983
+ verifyWhileNpmInstall ( { timeouts : 0 , semantic : moduleNotFoundErr } ) ;
984
+
985
+ filesAndFoldersToAdd = [ ] ;
986
+ // Move things from staging to node_modules without triggering watch
987
+ const moduleFile : File = {
988
+ path : `${ tscWatch . projectRoot } /node_modules/@angular/core/index.d.ts` ,
989
+ content : `export const y = 10;`
990
+ } ;
991
+ host . ensureFileOrFolder ( moduleFile , /*ignoreWatchInvokedWithTriggerAsFileCreate*/ true , /*ignoreParentWatch*/ true ) ;
992
+ // Since we added/removed in .staging no timeout
993
+ verifyWhileNpmInstall ( { timeouts : 0 , semantic : moduleNotFoundErr } ) ;
994
+
995
+ // Remove staging folder to remove errors
996
+ host . deleteFolder ( `${ tscWatch . projectRoot } /node_modules/.staging` , /*recursive*/ true ) ;
997
+ npmInstallComplete = true ;
998
+ projectFiles . push ( moduleFile ) ;
999
+ // Additional watch for watching script infos from node_modules
1000
+ expectedRecursiveWatches . set ( `${ tscWatch . projectRoot } /node_modules` , 2 ) ;
1001
+ verifyWhileNpmInstall ( { timeouts : 2 , semantic : [ ] } ) ;
1002
+
1003
+ function verifyWhileNpmInstall ( { timeouts, semantic } : { timeouts : number ; semantic : protocol . Diagnostic [ ] } ) {
1004
+ filesAndFoldersToAdd . forEach ( f => host . ensureFileOrFolder ( f ) ) ;
1005
+ if ( npmInstallComplete || timeoutDuringPartialInstallation ) {
1006
+ host . checkTimeoutQueueLengthAndRun ( timeouts ) ;
1007
+ }
1008
+ else {
1009
+ host . checkTimeoutQueueLength ( 2 ) ;
1010
+ }
1011
+ verifyProject ( ) ;
1012
+ verifyErrors ( semantic , ! npmInstallComplete && ! timeoutDuringPartialInstallation ? 2 : undefined ) ;
1013
+ }
1014
+
1015
+ function verifyProject ( ) {
1016
+ checkNumberOfConfiguredProjects ( service , 1 ) ;
1017
+
1018
+ const project = service . configuredProjects . get ( config . path ) ! ;
1019
+ checkProjectActualFiles ( project , map ( projectFiles , f => f . path ) ) ;
1020
+
1021
+ checkWatchedFilesDetailed ( host , mapDefined ( projectFiles , f => f === main || f === moduleFile ? undefined : f . path ) , 1 ) ;
1022
+ checkWatchedDirectoriesDetailed ( host , expectedRecursiveWatches , /*recursive*/ true ) ;
1023
+ checkWatchedDirectories ( host , [ ] , /*recursive*/ false ) ;
1024
+ }
1025
+
1026
+ function verifyErrors ( semantic : protocol . Diagnostic [ ] , existingTimeouts ?: number ) {
1027
+ verifyGetErrRequest ( {
1028
+ session,
1029
+ host,
1030
+ expected : [ {
1031
+ file : main ,
1032
+ syntax : [ ] ,
1033
+ semantic,
1034
+ suggestion : [ ]
1035
+ } ] ,
1036
+ existingTimeouts
1037
+ } ) ;
1038
+
1039
+ }
1040
+ }
1041
+
1042
+ it ( "timeouts occur inbetween installation" , ( ) => {
1043
+ verifyNpmInstall ( /*timeoutDuringPartialInstallation*/ true ) ;
1044
+ } ) ;
1045
+
1046
+ it ( "timeout occurs after installation" , ( ) => {
1047
+ verifyNpmInstall ( /*timeoutDuringPartialInstallation*/ false ) ;
1048
+ } ) ;
1049
+ } ) ;
936
1050
}
0 commit comments