@@ -9,9 +9,10 @@ import { Position, CancellationToken, InlineCompletionItem } from 'vscode'
99import assert from 'assert'
1010import { RecommendationService } from '../../../../../src/app/inline/recommendationService'
1111import { SessionManager } from '../../../../../src/app/inline/sessionManager'
12- import { createMockDocument } from 'aws-core-vscode/test'
12+ import { createMockDocument , installFakeClock } from 'aws-core-vscode/test'
1313import { LineTracker } from '../../../../../src/app/inline/stateTracker/lineTracker'
1414import { InlineGeneratingMessage } from '../../../../../src/app/inline/inlineGeneratingMessage'
15+ import { inlineCompletionsDebounceDelay } from 'aws-core-vscode/codewhisperer'
1516
1617describe ( 'RecommendationService' , ( ) => {
1718 let languageClient : LanguageClient
@@ -119,5 +120,100 @@ describe('RecommendationService', () => {
119120 const items2 = sessionManager . getActiveRecommendation ( )
120121 assert . deepStrictEqual ( items2 , [ mockInlineCompletionItemTwo , { insertText : '1' } as InlineCompletionItem ] )
121122 } )
123+
124+ describe ( 'debounce functionality' , ( ) => {
125+ let clock : ReturnType < typeof installFakeClock >
126+
127+ beforeEach ( ( ) => {
128+ clock = installFakeClock ( )
129+ } )
130+
131+ afterEach ( ( ) => {
132+ clock . uninstall ( )
133+ } )
134+
135+ it ( 'debounces multiple rapid calls' , async ( ) => {
136+ const mockResult = {
137+ sessionId : 'test-session' ,
138+ items : [ mockInlineCompletionItemOne ] ,
139+ partialResultToken : undefined ,
140+ }
141+
142+ sendRequestStub . resolves ( mockResult )
143+
144+ // Make multiple rapid calls
145+ const promise1 = service . getAllRecommendations (
146+ languageClient ,
147+ mockDocument ,
148+ mockPosition ,
149+ mockContext ,
150+ mockToken
151+ )
152+ const promise2 = service . getAllRecommendations (
153+ languageClient ,
154+ mockDocument ,
155+ mockPosition ,
156+ mockContext ,
157+ mockToken
158+ )
159+ const promise3 = service . getAllRecommendations (
160+ languageClient ,
161+ mockDocument ,
162+ mockPosition ,
163+ mockContext ,
164+ mockToken
165+ )
166+
167+ // Verify that the promises are the same object (debounced)
168+ assert . strictEqual ( promise1 , promise2 )
169+ assert . strictEqual ( promise2 , promise3 )
170+
171+ await clock . tickAsync ( inlineCompletionsDebounceDelay + 1000 )
172+
173+ await promise1
174+ await promise2
175+ await promise3
176+ } )
177+
178+ it ( 'allows new calls after debounce period' , async ( ) => {
179+ const mockResult = {
180+ sessionId : 'test-session' ,
181+ items : [ mockInlineCompletionItemOne ] ,
182+ partialResultToken : undefined ,
183+ }
184+
185+ sendRequestStub . resolves ( mockResult )
186+
187+ const promise1 = service . getAllRecommendations (
188+ languageClient ,
189+ mockDocument ,
190+ mockPosition ,
191+ mockContext ,
192+ mockToken
193+ )
194+
195+ await clock . tickAsync ( inlineCompletionsDebounceDelay + 1000 )
196+
197+ await promise1
198+
199+ const promise2 = service . getAllRecommendations (
200+ languageClient ,
201+ mockDocument ,
202+ mockPosition ,
203+ mockContext ,
204+ mockToken
205+ )
206+
207+ assert . notStrictEqual (
208+ promise1 ,
209+ promise2 ,
210+ 'promises should be different when seperated by debounce period'
211+ )
212+
213+ await clock . tickAsync ( inlineCompletionsDebounceDelay + 1000 )
214+
215+ await promise2
216+ } )
217+ } )
122218 } )
123219} )
0 commit comments