@@ -144,4 +144,150 @@ console.log('test');]]></replace></change>`
144144 expect ( result . suggestions . hasSuggestions ( ) ) . toBe ( true )
145145 } )
146146 } )
147+
148+ describe ( "codeSuggestion" , ( ) => {
149+ it ( "should call provideInlineCompletionItems and directly insert completion" , async ( ) => {
150+ // This test verifies that codeSuggestion calls the provider directly
151+ // and inserts the completion without using the VSCode inline suggest UI
152+ const initialContent = `console.log('test');`
153+ const { mockDocument } = await setupTestDocument ( "test.js" , initialContent )
154+
155+ const suggestionText = "// suggestion"
156+
157+ // Mock the inline completion provider
158+ const mockProvider = {
159+ provideInlineCompletionItems : vi . fn ( ) . mockResolvedValue ( [
160+ {
161+ insertText : suggestionText ,
162+ range : new vscode . Range ( new vscode . Position ( 0 , 0 ) , new vscode . Position ( 0 , 0 ) ) ,
163+ } ,
164+ ] ) ,
165+ }
166+
167+ // Mock editor.edit
168+ const mockEdit = vi . fn ( ) . mockImplementation ( ( callback ) => {
169+ const editBuilder = {
170+ insert : vi . fn ( ) ,
171+ }
172+ callback ( editBuilder )
173+ return Promise . resolve ( true )
174+ } )
175+
176+ // Mock the GhostServiceManager instance with necessary properties
177+ const mockManager = {
178+ inlineCompletionProvider : mockProvider ,
179+ model : { loaded : true } ,
180+ taskId : null ,
181+ async hasAccess ( _document : any ) {
182+ return true
183+ } ,
184+ async load ( ) { } ,
185+ async codeSuggestion ( ) {
186+ const editor = vscode . window . activeTextEditor
187+ if ( ! editor ) {
188+ return
189+ }
190+
191+ const document = editor . document
192+ if ( ! ( await this . hasAccess ( document ) ) ) {
193+ return
194+ }
195+
196+ if ( ! this . model . loaded ) {
197+ await this . load ( )
198+ }
199+
200+ const position = editor . selection . active
201+ const context : vscode . InlineCompletionContext = {
202+ triggerKind : 1 , // InlineCompletionTriggerKind.Invoke
203+ selectedCompletionInfo : undefined ,
204+ }
205+ const tokenSource = {
206+ token : { isCancellationRequested : false , onCancellationRequested : vi . fn ( ) } ,
207+ dispose : vi . fn ( ) ,
208+ }
209+
210+ try {
211+ const completions = await this . inlineCompletionProvider . provideInlineCompletionItems (
212+ document ,
213+ position ,
214+ context ,
215+ tokenSource . token ,
216+ )
217+
218+ if (
219+ completions &&
220+ ( Array . isArray ( completions ) ? completions . length > 0 : completions . items . length > 0 )
221+ ) {
222+ const items = Array . isArray ( completions ) ? completions : completions . items
223+ const firstCompletion = items [ 0 ]
224+
225+ if ( firstCompletion && firstCompletion . insertText ) {
226+ const insertText =
227+ typeof firstCompletion . insertText === "string"
228+ ? firstCompletion . insertText
229+ : firstCompletion . insertText . value
230+
231+ await editor . edit ( ( editBuilder ) => {
232+ editBuilder . insert ( position , insertText )
233+ } )
234+ }
235+ }
236+ } finally {
237+ tokenSource . dispose ( )
238+ }
239+ } ,
240+ }
241+
242+ // Set up active editor with mock edit function
243+ ; ( vscode . window as any ) . activeTextEditor = {
244+ document : mockDocument ,
245+ selection : {
246+ active : new vscode . Position ( 0 , 0 ) ,
247+ } ,
248+ edit : mockEdit ,
249+ }
250+
251+ // Call codeSuggestion
252+ await mockManager . codeSuggestion ( )
253+
254+ // Verify that provideInlineCompletionItems was called with correct parameters
255+ expect ( mockProvider . provideInlineCompletionItems ) . toHaveBeenCalledWith (
256+ mockDocument ,
257+ expect . any ( vscode . Position ) ,
258+ expect . objectContaining ( {
259+ triggerKind : 1 , // InlineCompletionTriggerKind.Invoke
260+ } ) ,
261+ expect . any ( Object ) ,
262+ )
263+
264+ // Verify that editor.edit was called to insert the completion
265+ expect ( mockEdit ) . toHaveBeenCalled ( )
266+ } )
267+
268+ it ( "should not call provider when no active editor" , async ( ) => {
269+ const mockProvider = {
270+ provideInlineCompletionItems : vi . fn ( ) ,
271+ }
272+
273+ const mockManager = {
274+ inlineCompletionProvider : mockProvider ,
275+ async codeSuggestion ( ) {
276+ const editor = vscode . window . activeTextEditor
277+ if ( ! editor ) {
278+ return
279+ }
280+ // Rest of the logic would go here
281+ } ,
282+ }
283+
284+ // No active editor
285+ ; ( vscode . window as any ) . activeTextEditor = null
286+
287+ await mockManager . codeSuggestion ( )
288+
289+ // Verify provider was not called
290+ expect ( mockProvider . provideInlineCompletionItems ) . not . toHaveBeenCalled ( )
291+ } )
292+ } )
147293} )
0 commit comments