Skip to content

Commit 692847a

Browse files
authored
test(amazonq): add tests for edge cases (#7305)
## Problem There are two edge cases discovered during testing that warrant some tests. 1. the language server will respond without a range, causing the result to not be rendered. 2. the language server COULD respond with a `StringValue` instead of string (currently doesn't, but valid in the type contract). ## Solution - add tests for these cases, and do minor refactoring to make this easier. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent b649dbd commit 692847a

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

packages/amazonq/src/app/inline/completion.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
InlineCompletionContext,
99
InlineCompletionItem,
1010
InlineCompletionItemProvider,
11-
InlineCompletionList,
1211
Position,
1312
TextDocument,
1413
commands,
@@ -214,7 +213,7 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
214213
position: Position,
215214
context: InlineCompletionContext,
216215
token: CancellationToken
217-
): Promise<InlineCompletionItem[] | InlineCompletionList> {
216+
): Promise<InlineCompletionItem[]> {
218217
try {
219218
vsCodeState.isRecommendationsActive = true
220219
if (this.isNewSession) {
@@ -246,8 +245,7 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
246245
return []
247246
}
248247

249-
const start = document.validatePosition(editor.selection.active)
250-
const end = position
248+
const cursorPosition = document.validatePosition(position)
251249
for (const item of items) {
252250
item.command = {
253251
command: 'aws.amazonq.acceptInline',
@@ -257,17 +255,18 @@ export class AmazonQInlineCompletionItemProvider implements InlineCompletionItem
257255
item,
258256
editor,
259257
session.requestStartTime,
260-
position.line,
258+
cursorPosition.line,
261259
session.firstCompletionDisplayLatency,
262260
],
263261
}
264-
item.range = new Range(start, end)
262+
item.range = new Range(cursorPosition, cursorPosition)
263+
item.insertText = typeof item.insertText === 'string' ? item.insertText : item.insertText.value
265264
ReferenceInlineProvider.instance.setInlineReference(
266-
position.line,
267-
item.insertText as string,
265+
cursorPosition.line,
266+
item.insertText,
268267
item.references
269268
)
270-
ImportAdderProvider.instance.onShowRecommendation(document, position.line, item)
269+
ImportAdderProvider.instance.onShowRecommendation(document, cursorPosition.line, item)
271270
}
272271
return items as InlineCompletionItem[]
273272
} catch (e) {

packages/amazonq/src/app/inline/recommendationService.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class RecommendationService {
4848

4949
// Handle first request
5050
const firstResult: InlineCompletionListWithReferences = await languageClient.sendRequest(
51-
inlineCompletionWithReferencesRequestType as any,
51+
inlineCompletionWithReferencesRequestType.method,
5252
request,
5353
token
5454
)
@@ -98,7 +98,7 @@ export class RecommendationService {
9898
while (nextToken) {
9999
const request = { ...initialRequest, partialResultToken: nextToken }
100100
const result: InlineCompletionListWithReferences = await languageClient.sendRequest(
101-
inlineCompletionWithReferencesRequestType as any,
101+
inlineCompletionWithReferencesRequestType.method,
102102
request,
103103
token
104104
)

packages/amazonq/test/unit/amazonq/apps/inline/completion.test.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55
import sinon from 'sinon'
6-
import { CancellationToken, commands, InlineCompletionItem, languages, Position, window } from 'vscode'
6+
import { CancellationToken, commands, InlineCompletionItem, languages, Position, window, Range } from 'vscode'
77
import assert from 'assert'
88
import { LanguageClient } from 'vscode-languageclient'
9+
import { StringValue } from 'vscode-languageserver-types'
910
import { AmazonQInlineCompletionItemProvider, InlineCompletionManager } from '../../../../../src/app/inline/completion'
1011
import { RecommendationService } from '../../../../../src/app/inline/recommendationService'
1112
import { SessionManager } from '../../../../../src/app/inline/sessionManager'
@@ -344,6 +345,61 @@ describe('InlineCompletionManager', () => {
344345
)
345346
)
346347
}),
348+
it('should add a range to the completion item when missing', async function () {
349+
provider = new AmazonQInlineCompletionItemProvider(
350+
languageClient,
351+
recommendationService,
352+
mockSessionManager,
353+
inlineTutorialAnnotation,
354+
true
355+
)
356+
getActiveRecommendationStub.returns([
357+
{
358+
insertText: 'testText',
359+
itemId: 'itemId',
360+
},
361+
{
362+
insertText: 'testText2',
363+
itemId: 'itemId2',
364+
range: undefined,
365+
},
366+
])
367+
const cursorPosition = new Position(5, 6)
368+
const result = await provider.provideInlineCompletionItems(
369+
mockDocument,
370+
cursorPosition,
371+
mockContext,
372+
mockToken
373+
)
374+
375+
for (const item of result) {
376+
assert.deepStrictEqual(item.range, new Range(cursorPosition, cursorPosition))
377+
}
378+
}),
379+
it('should handle StringValue instead of strings', async function () {
380+
provider = new AmazonQInlineCompletionItemProvider(
381+
languageClient,
382+
recommendationService,
383+
mockSessionManager,
384+
inlineTutorialAnnotation,
385+
true
386+
)
387+
const expectedText = 'this is my text'
388+
getActiveRecommendationStub.returns([
389+
{
390+
insertText: { kind: 'snippet', value: 'this is my text' } satisfies StringValue,
391+
itemId: 'itemId',
392+
},
393+
])
394+
const result = await provider.provideInlineCompletionItems(
395+
mockDocument,
396+
mockPosition,
397+
mockContext,
398+
mockToken
399+
)
400+
401+
assert.strictEqual(result[0].insertText, expectedText)
402+
}),
347403
describe('debounce behavior', function () {
348404
let clock: ReturnType<typeof installFakeClock>
349405

0 commit comments

Comments
 (0)