@@ -53,6 +53,7 @@ import { MultiDataStoreFactoryProvider } from '../../src/datastore/DataStore';
5353import { FeatureFlagProvider } from '../../src/featureFlag/FeatureFlagProvider' ;
5454import { LspCapabilities } from '../../src/protocol/LspCapabilities' ;
5555import { LspConnection } from '../../src/protocol/LspConnection' ;
56+ import { SamStoreKey } from '../../src/schema/SamSchemas' ;
5657import { SchemaRetriever } from '../../src/schema/SchemaRetriever' ;
5758import { SchemaStore } from '../../src/schema/SchemaStore' ;
5859import { CfnExternal } from '../../src/server/CfnExternal' ;
@@ -61,39 +62,23 @@ import { CfnLspProviders } from '../../src/server/CfnLspProviders';
6162import { CfnServer } from '../../src/server/CfnServer' ;
6263import { AwsMetadata , ExtendedInitializeParams } from '../../src/server/InitParams' ;
6364import { RelationshipSchemaService } from '../../src/services/RelationshipSchemaService' ;
65+ import { DefaultSettings } from '../../src/settings/Settings' ;
6466import { LoggerFactory } from '../../src/telemetry/LoggerFactory' ;
6567import { Closeable } from '../../src/utils/Closeable' ;
6668import { ExtensionName } from '../../src/utils/ExtensionConfig' ;
6769import { createMockCfnLintService } from './MockServerComponents' ;
6870import { getTestPrivateSchemas , samFileType , SamSchemaFiles , schemaFileType , Schemas } from './SchemaUtils' ;
6971import { flushAllPromises , WaitFor } from './Utils' ;
7072
73+ type TestExtensionConfig = {
74+ id ?: string ;
75+ initializeParams ?: Partial < ExtendedInitializeParams > ;
76+ workspaceConfig ?: Record < string , unknown > [ ] ;
77+ } ;
78+
7179export class TestExtension implements Closeable {
72- private readonly id = v4 ( ) ;
73- private readonly rootDir = join ( process . cwd ( ) , 'node_modules' , '.cache' , 'e2e-tests' , this . id ) ;
74- private readonly awsMetadata : AwsMetadata = {
75- clientInfo : {
76- extension : {
77- name : `Test ${ ExtensionName } ` ,
78- version : '1.0.0-test' ,
79- } ,
80- clientId : this . id ,
81- } ,
82- encryption : {
83- key : randomBytes ( 32 ) . toString ( 'base64' ) ,
84- mode : 'JWT' ,
85- } ,
86- } ;
87- private readonly initializeParams : ExtendedInitializeParams = {
88- processId : process . pid ,
89- rootUri : null ,
90- capabilities : { } ,
91- clientInfo : this . awsMetadata . clientInfo ?. extension ,
92- workspaceFolders : [ ] ,
93- initializationOptions : {
94- aws : this . awsMetadata ,
95- } ,
96- } ;
80+ private readonly awsMetadata : AwsMetadata ;
81+ private readonly initializeParams : ExtendedInitializeParams ;
9782
9883 private readonly readStream = new PassThrough ( ) ;
9984 private readonly writeStream = new PassThrough ( ) ;
@@ -108,18 +93,45 @@ export class TestExtension implements Closeable {
10893 providers ! : CfnLspProviders ;
10994 server ! : CfnServer ;
11095
111- private lspClientReady = false ;
112- private lspServerReady = false ;
96+ private isReady = false ;
97+
98+ constructor ( config : TestExtensionConfig = { } ) {
99+ const id = config . id ?? v4 ( ) ;
100+ const rootDir = join ( process . cwd ( ) , 'node_modules' , '.cache' , 'e2e-tests' , id ) ;
101+
102+ this . awsMetadata = {
103+ clientInfo : {
104+ extension : {
105+ name : `Test ${ ExtensionName } ` ,
106+ version : '1.0.0-test' ,
107+ } ,
108+ clientId : id ,
109+ } ,
110+ encryption : {
111+ key : randomBytes ( 32 ) . toString ( 'base64' ) ,
112+ mode : 'JWT' ,
113+ } ,
114+ } ;
115+ this . initializeParams = {
116+ processId : process . pid ,
117+ rootUri : null ,
118+ capabilities : { } ,
119+ clientInfo : this . awsMetadata . clientInfo ?. extension ,
120+ workspaceFolders : [ ] ,
121+ initializationOptions : {
122+ aws : this . awsMetadata ,
123+ } ,
124+ ...config . initializeParams ,
125+ } ;
113126
114- constructor ( ) {
115127 this . serverConnection = new LspConnection (
116128 createConnection ( new StreamMessageReader ( this . readStream ) , new StreamMessageWriter ( this . writeStream ) ) ,
117129 {
118130 onInitialize : ( params ) => {
119131 const lsp = this . serverConnection . components ;
120132 LoggerFactory . reconfigure ( 'warn' ) ;
121133
122- const dataStoreFactory = new MultiDataStoreFactoryProvider ( this . rootDir ) ;
134+ const dataStoreFactory = new MultiDataStoreFactoryProvider ( rootDir ) ;
123135 this . core = new CfnInfraCore ( lsp , params , {
124136 dataStoreFactory,
125137 } ) ;
@@ -154,22 +166,15 @@ export class TestExtension implements Closeable {
154166 this . server = new CfnServer ( lsp , this . core , this . external , this . providers ) ;
155167 return LspCapabilities ;
156168 } ,
157- onInitialized : ( params ) => {
158- this . server . initialized ( params ) ;
159- this . lspServerReady = true ;
160- } ,
161- onShutdown : ( ) => {
162- return this . server . close ( ) ;
163- } ,
164- onExit : ( ) => {
165- return this . server . close ( ) ;
166- } ,
169+ onInitialized : ( params ) => this . server . initialized ( params ) ,
170+ onShutdown : ( ) => this . server . close ( ) ,
171+ onExit : ( ) => this . server . close ( ) ,
167172 } ,
168173 ) ;
169174
170175 // Handle workspace/configuration requests from the server
171176 this . clientConnection . onRequest ( 'workspace/configuration' , ( ) => {
172- return [ { } ] ; // Return empty configuration
177+ return config . workspaceConfig ?? [ { } ] ;
173178 } ) ;
174179
175180 this . serverConnection . listen ( ) ;
@@ -185,40 +190,39 @@ export class TestExtension implements Closeable {
185190 }
186191
187192 async ready ( ) {
188- if ( ! this . lspClientReady ) {
193+ if ( ! this . isReady ) {
189194 await this . clientConnection . sendRequest ( InitializeRequest . type , this . initializeParams ) ;
190195 await this . clientConnection . sendNotification ( InitializedNotification . type , { } ) ;
191- this . lspClientReady = true ;
192- }
193196
194- await WaitFor . waitFor ( ( ) => {
195- if ( ! this . lspServerReady ) {
196- throw new Error ( 'Server is not ready yet' ) ;
197- }
198- } , 5000 ) ;
197+ await WaitFor . waitFor ( ( ) => {
198+ const store = this . external . schemaStore ;
199+ const pbSchemas = store ?. publicSchemas ?. get ( DefaultSettings . profile . region ) ;
200+ const samSchemas = store ?. samSchemas ?. get ( SamStoreKey ) ;
199201
200- await flushAllPromises ( ) ;
202+ if ( pbSchemas === undefined || samSchemas === undefined ) {
203+ throw new Error ( 'Schemas not loaded yet' ) ;
204+ }
205+ } , 1_000 ) ;
206+
207+ await flushAllPromises ( ) ;
208+ this . isReady = true ;
209+ }
201210 }
202211
203212 async send ( method : string , params : any ) {
204213 await this . ready ( ) ;
205- const value = await this . clientConnection . sendRequest ( method , params ) ;
206- await wait ( 100 ) ;
207- return value ;
214+ return await this . clientConnection . sendRequest ( method , params ) ;
208215 }
209216
210217 async notify ( method : string , params : any ) {
211218 await this . ready ( ) ;
212- const value = await this . clientConnection . sendNotification ( method , params ) ;
213- await wait ( 100 ) ;
214- return value ;
219+ return await this . clientConnection . sendNotification ( method , params ) ;
215220 }
216221
217222 async close ( ) {
218223 await this . clientConnection . sendRequest ( ShutdownRequest . type ) ;
219224 await this . clientConnection . sendNotification ( ExitNotification . type ) ;
220225 this . clientConnection . dispose ( ) ;
221- await flushAllPromises ( ) ;
222226 }
223227
224228 // ====================================================================
@@ -227,18 +231,22 @@ export class TestExtension implements Closeable {
227231
228232 async openDocument ( params : DidOpenTextDocumentParams ) {
229233 await this . notify ( DidOpenTextDocumentNotification . method , params ) ;
234+ await wait ( 10 ) ;
230235 }
231236
232237 async changeDocument ( params : DidChangeTextDocumentParams ) {
233238 await this . notify ( DidChangeTextDocumentNotification . method , params ) ;
239+ await wait ( 10 ) ;
234240 }
235241
236242 async closeDocument ( params : DidCloseTextDocumentParams ) {
237243 await this . notify ( DidCloseTextDocumentNotification . method , params ) ;
244+ await wait ( 10 ) ;
238245 }
239246
240- saveDocument ( params : DidSaveTextDocumentParams ) {
241- return this . notify ( DidSaveTextDocumentNotification . method , params ) ;
247+ async saveDocument ( params : DidSaveTextDocumentParams ) {
248+ await this . notify ( DidSaveTextDocumentNotification . method , params ) ;
249+ await wait ( 10 ) ;
242250 }
243251
244252 completion ( params : CompletionParams ) {
0 commit comments