Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import assert from 'assert'
import * as sinon from 'sinon'
import { resetCodeWhispererGlobalVariables, createMockTextEditor } from 'aws-core-vscode/test'
import {
ConfigurationEntry,
invokeRecommendation,
InlineCompletionService,
isInlineCompletionEnabled,
DefaultCodeWhispererClient,
} from 'aws-core-vscode/codewhisperer'

describe('invokeRecommendation', function () {
describe('invokeRecommendation', function () {
let getRecommendationStub: sinon.SinonStub
let mockClient: DefaultCodeWhispererClient

beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
getRecommendationStub = sinon.stub(InlineCompletionService.instance, 'getPaginatedRecommendation')
})

afterEach(function () {
sinon.restore()
})

it('Should call getPaginatedRecommendation with OnDemand as trigger type when inline completion is enabled', async function () {
const mockEditor = createMockTextEditor()
const config: ConfigurationEntry = {
isShowMethodsEnabled: true,
isManualTriggerEnabled: true,
isAutomatedTriggerEnabled: true,
isSuggestionsWithCodeReferencesEnabled: true,
}
await invokeRecommendation(mockEditor, mockClient, config)
assert.strictEqual(getRecommendationStub.called, isInlineCompletionEnabled())
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import assert from 'assert'
import * as vscode from 'vscode'
import * as sinon from 'sinon'
import { onAcceptance, AcceptedSuggestionEntry, session, CodeWhispererTracker } from 'aws-core-vscode/codewhisperer'
import { resetCodeWhispererGlobalVariables, createMockTextEditor } from 'aws-core-vscode/test'

describe('onAcceptance', function () {
describe('onAcceptance', function () {
beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
session.reset()
})

afterEach(function () {
sinon.restore()
session.reset()
})

it('Should enqueue an event object to tracker', async function () {
const mockEditor = createMockTextEditor()
const trackerSpy = sinon.spy(CodeWhispererTracker.prototype, 'enqueue')
const fakeReferences = [
{
message: '',
licenseName: 'MIT',
repository: 'http://github.com/fake',
recommendationContentSpan: {
start: 0,
end: 10,
},
},
]
await onAcceptance({
editor: mockEditor,
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 26)),
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 26)),
acceptIndex: 0,
recommendation: "print('Hello World!')",
requestId: '',
sessionId: '',
triggerType: 'OnDemand',
completionType: 'Line',
language: 'python',
references: fakeReferences,
})
const actualArg = trackerSpy.getCall(0).args[0] as AcceptedSuggestionEntry
assert.ok(trackerSpy.calledOnce)
assert.strictEqual(actualArg.originalString, 'def two_sum(nums, target):')
assert.strictEqual(actualArg.requestId, '')
assert.strictEqual(actualArg.sessionId, '')
assert.strictEqual(actualArg.triggerType, 'OnDemand')
assert.strictEqual(actualArg.completionType, 'Line')
assert.strictEqual(actualArg.language, 'python')
assert.deepStrictEqual(actualArg.startPosition, new vscode.Position(1, 0))
assert.deepStrictEqual(actualArg.endPosition, new vscode.Position(1, 26))
assert.strictEqual(actualArg.index, 0)
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import assert from 'assert'
import * as vscode from 'vscode'
import * as sinon from 'sinon'
import { resetCodeWhispererGlobalVariables, createMockTextEditor } from 'aws-core-vscode/test'
import { onInlineAcceptance, RecommendationHandler, session } from 'aws-core-vscode/codewhisperer'

describe('onInlineAcceptance', function () {
describe('onInlineAcceptance', function () {
beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
session.reset()
})

afterEach(function () {
sinon.restore()
session.reset()
})

it('Should dispose inline completion provider', async function () {
const mockEditor = createMockTextEditor()
const spy = sinon.spy(RecommendationHandler.instance, 'disposeInlineCompletion')
await onInlineAcceptance({
editor: mockEditor,
range: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
effectiveRange: new vscode.Range(new vscode.Position(1, 0), new vscode.Position(1, 21)),
acceptIndex: 0,
recommendation: "print('Hello World!')",
requestId: '',
sessionId: '',
triggerType: 'OnDemand',
completionType: 'Line',
language: 'python',
references: undefined,
})
assert.ok(spy.calledWith())
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

import * as vscode from 'vscode'
import assert from 'assert'
import * as sinon from 'sinon'
import {
InlineCompletionService,
ReferenceInlineProvider,
RecommendationHandler,
ConfigurationEntry,
CWInlineCompletionItemProvider,
session,
DefaultCodeWhispererClient,
} from 'aws-core-vscode/codewhisperer'
import { createMockTextEditor, resetCodeWhispererGlobalVariables, createMockDocument } from 'aws-core-vscode/test'

describe('inlineCompletionService', function () {
beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
})

describe('getPaginatedRecommendation', function () {
const config: ConfigurationEntry = {
isShowMethodsEnabled: true,
isManualTriggerEnabled: true,
isAutomatedTriggerEnabled: true,
isSuggestionsWithCodeReferencesEnabled: true,
}

let mockClient: DefaultCodeWhispererClient

beforeEach(async function () {
mockClient = new DefaultCodeWhispererClient()
await resetCodeWhispererGlobalVariables()
})

afterEach(function () {
sinon.restore()
})

it('should call checkAndResetCancellationTokens before showing inline and next token to be null', async function () {
const mockEditor = createMockTextEditor()
sinon.stub(RecommendationHandler.instance, 'getRecommendations').resolves({
result: 'Succeeded',
errorMessage: undefined,
recommendationCount: 1,
})
const checkAndResetCancellationTokensStub = sinon.stub(
RecommendationHandler.instance,
'checkAndResetCancellationTokens'
)
session.recommendations = [{ content: "\n\t\tconsole.log('Hello world!');\n\t}" }, { content: '' }]
await InlineCompletionService.instance.getPaginatedRecommendation(
mockClient,
mockEditor,
'OnDemand',
config
)
assert.ok(checkAndResetCancellationTokensStub.called)
assert.strictEqual(RecommendationHandler.instance.hasNextToken(), false)
})
})

describe('clearInlineCompletionStates', function () {
it('should remove inline reference and recommendations', async function () {
const fakeReferences = [
{
message: '',
licenseName: 'MIT',
repository: 'http://github.com/fake',
recommendationContentSpan: {
start: 0,
end: 10,
},
},
]
ReferenceInlineProvider.instance.setInlineReference(1, 'test', fakeReferences)
session.recommendations = [{ content: "\n\t\tconsole.log('Hello world!');\n\t}" }, { content: '' }]
session.language = 'python'

assert.ok(session.recommendations.length > 0)
await RecommendationHandler.instance.clearInlineCompletionStates()
assert.strictEqual(ReferenceInlineProvider.instance.refs.length, 0)
assert.strictEqual(session.recommendations.length, 0)
})
})

describe('truncateOverlapWithRightContext', function () {
const fileName = 'test.py'
const language = 'python'
const rightContext = 'return target\n'
const doc = `import math\ndef two_sum(nums, target):\n`
const provider = new CWInlineCompletionItemProvider(0, 0, [], '', new vscode.Position(0, 0), '')

it('removes overlap with right context from suggestion', async function () {
const mockSuggestion = 'return target\n'
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, '')
})

it('only removes the overlap part from suggestion', async function () {
const mockSuggestion = 'print(nums)\nreturn target\n'
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, 'print(nums)\n')
})

it('only removes the last overlap pattern from suggestion', async function () {
const mockSuggestion = 'return target\nprint(nums)\nreturn target\n'
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, 'return target\nprint(nums)\n')
})

it('returns empty string if the remaining suggestion only contains white space', async function () {
const mockSuggestion = 'return target\n '
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, '')
})

it('returns the original suggestion if no match found', async function () {
const mockSuggestion = 'import numpy\n'
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, 'import numpy\n')
})

it('ignores the space at the end of recommendation', async function () {
const mockSuggestion = 'return target\n\n\n\n\n'
const mockEditor = createMockTextEditor(`${doc}${rightContext}`, fileName, language)
const cursorPosition = new vscode.Position(2, 0)
const result = provider.truncateOverlapWithRightContext(mockEditor.document, mockSuggestion, cursorPosition)
assert.strictEqual(result, '')
})
})
})

describe('CWInlineCompletionProvider', function () {
beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
})

describe('provideInlineCompletionItems', function () {
beforeEach(async function () {
await resetCodeWhispererGlobalVariables()
})

afterEach(function () {
sinon.restore()
})

it('should return undefined if position is before RecommendationHandler start pos', async function () {
const position = new vscode.Position(0, 0)
const document = createMockDocument()
const fakeContext = { triggerKind: 0, selectedCompletionInfo: undefined }
const token = new vscode.CancellationTokenSource().token
const provider = new CWInlineCompletionItemProvider(0, 0, [], '', new vscode.Position(1, 1), '')
const result = await provider.provideInlineCompletionItems(document, position, fakeContext, token)

assert.ok(result === undefined)
})
})
})
Loading
Loading