Skip to content

Commit 3684ab8

Browse files
committed
address comments and refactor
1 parent 151507c commit 3684ab8

File tree

2 files changed

+100
-154
lines changed

2 files changed

+100
-154
lines changed

packages/amazonq/test/e2e/amazonq/testGen.test.ts

Lines changed: 99 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,15 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
// jscpd:ignore-start
76
import assert from 'assert'
87
import vscode from 'vscode'
9-
import os from 'os'
10-
import path from 'path'
11-
import fs from 'fs' // eslint-disable-line no-restricted-imports
128
import { qTestingFramework } from './framework/framework'
139
import sinon from 'sinon'
1410
import { Messenger } from './framework/messenger'
1511
import { FollowUpTypes } from 'aws-core-vscode/amazonq'
16-
import { registerAuthHook, using } from 'aws-core-vscode/test'
12+
import { registerAuthHook, using, TestFolder } from 'aws-core-vscode/test'
1713
import { loginToIdC } from './utils/setup'
18-
import { globals } from 'aws-core-vscode/shared'
19-
import { openTextDocument } from 'aws-core-vscode/shared'
14+
import { waitUntil, workspaceUtils } from 'aws-core-vscode/shared'
2015

2116
describe('Amazon Q Test Generation', function () {
2217
let framework: qTestingFramework
@@ -46,6 +41,31 @@ describe('Amazon Q Test Generation', function () {
4641
},
4742
]
4843

44+
async function setupTestDocument(filePath: string, language: string) {
45+
const document = await waitUntil(async () => {
46+
const doc = await workspaceUtils.openTextDocument(filePath)
47+
return doc
48+
}, {})
49+
50+
if (!document) {
51+
assert.fail(`Failed to open ${language} file`)
52+
}
53+
54+
await vscode.window.showTextDocument(document, { preview: false })
55+
56+
const activeEditor = vscode.window.activeTextEditor
57+
if (!activeEditor || activeEditor.document !== document) {
58+
assert.fail(`Failed to make temp file active`)
59+
}
60+
}
61+
62+
async function waitForChatItems(index: number) {
63+
await tab.waitForEvent(() => tab.getChatItems().length > index, {
64+
waitTimeoutInMs: 5000,
65+
waitIntervalInMs: 1000,
66+
})
67+
}
68+
4969
before(async function () {
5070
await using(registerAuthHook('amazonq-test-account'), async () => {
5171
await loginToIdC()
@@ -89,185 +109,111 @@ describe('Amazon Q Test Generation', function () {
89109
})
90110
})
91111

92-
describe('Unsupported language', () => {
93-
const { language, filePath } = unsupportedLanguages[0]
94-
95-
beforeEach(async () => {
96-
const document = await openTextDocument(filePath)
112+
describe('/test entry', () => {
113+
describe('Unsupported language', () => {
114+
const { language, filePath } = unsupportedLanguages[0]
97115

98-
if (!document) {
99-
assert.fail(`Failed to open ${language} file`)
100-
}
116+
beforeEach(async () => {
117+
await setupTestDocument(filePath, language)
118+
})
101119

102-
await vscode.window.showTextDocument(document, { preview: false })
120+
it(`/test for unsupported language redirects to chat`, async () => {
121+
tab.addChatMessage({ command: '/test' })
122+
await tab.waitForChatFinishesLoading()
103123

104-
const activeEditor = vscode.window.activeTextEditor
105-
if (!activeEditor || activeEditor.document !== document) {
106-
assert.fail(`Failed to make ${language} file active`)
107-
}
108-
})
124+
await waitForChatItems(3)
125+
const unsupportedLanguageMessage = tab.getChatItems()[3]
109126

110-
it(`Does not generate tests for unsupported language`, async () => {
111-
tab.addChatMessage({ command: '/test' })
112-
await tab.waitForChatFinishesLoading()
113-
114-
await tab.waitForEvent(() => tab.getChatItems().length > 3, {
115-
waitTimeoutInMs: 5000,
116-
waitIntervalInMs: 1000,
127+
assert.deepStrictEqual(unsupportedLanguageMessage.type, 'answer')
128+
assert.deepStrictEqual(
129+
unsupportedLanguageMessage.body,
130+
`<span style="color: #EE9D28;">&#9888;<b>I'm sorry, but /test only supports Python and Java</b><br></span> While ${language.charAt(0).toUpperCase() + language.slice(1)} is not supported, I will generate a suggestion below.`
131+
)
117132
})
118-
const message = tab.getChatItems()[3]
119-
assert.deepStrictEqual(message.type, 'answer')
120-
assert.deepStrictEqual(
121-
message.body,
122-
`<span style="color: #EE9D28;">&#9888;<b>I'm sorry, but /test only supports Python and Java</b><br></span> While ${language.charAt(0).toUpperCase() + language.slice(1)} is not supported, I will generate a suggestion below.`
123-
)
124133
})
125-
})
126-
127-
describe('External file outside of project', async () => {
128-
let tempDir: string
129-
let tempFileName: string
130-
131-
beforeEach(async () => {
132-
tempDir = path.join(os.tmpdir(), `testgen-test-${globals.clock.Date.now()}`)
133-
await fs.promises.mkdir(tempDir)
134-
tempFileName = `testfile-${globals.clock.Date.now()}.py`
135-
const tempFilePath = path.join(tempDir, tempFileName)
136-
await fs.promises.writeFile(tempFilePath, 'def add(a, b): return a + b')
137-
const uri = vscode.Uri.file(tempFilePath)
138134

139-
if (!fs.existsSync(tempFilePath)) {
140-
throw new Error('Failed to create temporary file')
141-
}
142-
143-
const document = await vscode.workspace.openTextDocument(uri)
144-
if (!document) {
145-
assert.fail(`Failed to open temp file`)
146-
}
135+
describe('External file', async () => {
136+
let testFolder: TestFolder
137+
let fileName: string
147138

148-
await vscode.window.showTextDocument(document, { preview: false })
139+
beforeEach(async () => {
140+
testFolder = await TestFolder.create()
141+
fileName = 'test.py'
142+
const filePath = await testFolder.write(fileName, 'def add(a, b): return a + b')
149143

150-
const activeEditor = vscode.window.activeTextEditor
151-
if (!activeEditor || activeEditor.document !== document) {
152-
assert.fail(`Failed to make temp file active`)
153-
}
154-
})
144+
const document = await vscode.workspace.openTextDocument(filePath)
145+
await vscode.window.showTextDocument(document, { preview: false })
146+
})
155147

156-
afterEach(async () => {
157-
if (fs.existsSync(tempDir)) {
158-
await fs.promises.rm(tempDir, { recursive: true, force: true })
159-
}
160-
})
148+
it('/test for external file redirects to chat', async () => {
149+
tab.addChatMessage({ command: '/test' })
150+
await tab.waitForChatFinishesLoading()
161151

162-
it('Generate tests for external file redirects to chat', async () => {
163-
tab.addChatMessage({ command: '/test' })
164-
await tab.waitForChatFinishesLoading()
152+
await waitForChatItems(3)
153+
const externalFileMessage = tab.getChatItems()[3]
165154

166-
await tab.waitForEvent(() => tab.getChatItems().length > 3, {
167-
waitTimeoutInMs: 5000,
168-
waitIntervalInMs: 1000,
155+
assert.deepStrictEqual(externalFileMessage.type, 'answer')
156+
assert.deepStrictEqual(
157+
externalFileMessage.body,
158+
`<span style="color: #EE9D28;">&#9888;<b>I can't generate tests for ${fileName}</b> because the file is outside of workspace scope.<br></span> I can still provide examples, instructions and code suggestions.`
159+
)
169160
})
170-
const message = tab.getChatItems()[3]
171-
assert.deepStrictEqual(message.type, 'answer')
172-
assert.deepStrictEqual(
173-
message.body,
174-
`<span style="color: #EE9D28;">&#9888;<b>I can't generate tests for ${tempFileName}</b> because the file is outside of workspace scope.<br></span> I can still provide examples, instructions and code suggestions.`
175-
)
176161
})
177-
})
178162

179-
for (const { language, filePath } of testFiles) {
180-
describe(`Test Generation for ${language}`, () => {
181-
beforeEach(async () => {
182-
// retry mechanism as loading active document can be sometimes flaky
183-
for (let attempt = 1; attempt <= 3; attempt++) {
184-
const document = await openTextDocument(filePath)
185-
186-
if (!document) {
187-
if (attempt === 3) {
188-
assert.fail(`Failed to open ${language} file`)
189-
}
190-
continue
191-
}
192-
193-
await vscode.window.showTextDocument(document, { preview: false })
194-
195-
const activeEditor = vscode.window.activeTextEditor
196-
if (!activeEditor || activeEditor.document !== document) {
197-
if (attempt === 3) {
198-
assert.fail(`Failed to make ${language} file active`)
199-
}
200-
continue
201-
}
202-
return
203-
}
204-
})
163+
for (const { language, filePath } of testFiles) {
164+
describe(`${language} file`, () => {
165+
beforeEach(async () => {
166+
await setupTestDocument(filePath, language)
205167

206-
describe('View diff', async () => {
207-
it('Clicks on view diff', async () => {
208168
tab.addChatMessage({ command: '/test' })
209169
await tab.waitForChatFinishesLoading()
210170

211171
await tab.waitForButtons([FollowUpTypes.ViewDiff])
212172
tab.clickButton(FollowUpTypes.ViewDiff)
213173
await tab.waitForChatFinishesLoading()
214-
215-
const chatItems = tab.getChatItems()
216-
assert.deepStrictEqual(chatItems[5].type, 'answer')
217-
assert.deepStrictEqual(
218-
chatItems[5].body,
219-
'Please see the unit tests generated below. Click “View diff” to review the changes in the code editor.'
220-
)
221174
})
222-
})
223175

224-
describe('Accept code', async () => {
225-
it('Clicks on accept', async () => {
226-
tab.addChatMessage({ command: '/test' })
227-
await tab.waitForChatFinishesLoading()
176+
describe('View diff', async () => {
177+
it('Clicks on view diff', async () => {
178+
const chatItems = tab.getChatItems()
179+
const viewDiffMessage = chatItems[5]
228180

229-
await tab.waitForButtons([FollowUpTypes.ViewDiff])
230-
tab.clickButton(FollowUpTypes.ViewDiff)
231-
await tab.waitForChatFinishesLoading()
181+
assert.deepStrictEqual(viewDiffMessage.type, 'answer')
182+
assert.deepStrictEqual(
183+
viewDiffMessage.body,
184+
'Please see the unit tests generated below. Click “View diff” to review the changes in the code editor.'
185+
)
186+
})
187+
})
232188

233-
await tab.waitForButtons([FollowUpTypes.AcceptCode, FollowUpTypes.RejectCode])
234-
tab.clickButton(FollowUpTypes.AcceptCode)
235-
await tab.waitForChatFinishesLoading()
189+
describe('Accept code', async () => {
190+
it('Clicks on accept', async () => {
191+
await tab.waitForButtons([FollowUpTypes.AcceptCode, FollowUpTypes.RejectCode])
192+
tab.clickButton(FollowUpTypes.AcceptCode)
193+
await tab.waitForChatFinishesLoading()
236194

237-
await tab.waitForEvent(() => tab.getChatItems().length > 7, {
238-
waitTimeoutInMs: 5000,
239-
waitIntervalInMs: 1000,
195+
await waitForChatItems(7)
196+
const acceptedMessage = tab.getChatItems()[7]
197+
198+
assert.deepStrictEqual(acceptedMessage?.type, 'answer-part')
199+
assert.deepStrictEqual(acceptedMessage?.followUp?.options?.[0].pillText, 'Accepted')
240200
})
241-
const message = tab.getChatItems()[7]
242-
assert.deepStrictEqual(message?.type, 'answer-part')
243-
assert.deepStrictEqual(message?.followUp?.options?.[0].pillText, 'Accepted')
244201
})
245-
})
246202

247-
describe('Reject code', async () => {
248-
it('Clicks on reject', async () => {
249-
tab.addChatMessage({ command: '/test' })
250-
await tab.waitForChatFinishesLoading()
203+
describe('Reject code', async () => {
204+
it('Clicks on reject', async () => {
205+
await tab.waitForButtons([FollowUpTypes.AcceptCode, FollowUpTypes.RejectCode])
206+
tab.clickButton(FollowUpTypes.RejectCode)
207+
await tab.waitForChatFinishesLoading()
251208

252-
await tab.waitForButtons([FollowUpTypes.ViewDiff])
253-
tab.clickButton(FollowUpTypes.ViewDiff)
254-
await tab.waitForChatFinishesLoading()
209+
await waitForChatItems(7)
210+
const rejectedMessage = tab.getChatItems()[7]
255211

256-
await tab.waitForButtons([FollowUpTypes.AcceptCode, FollowUpTypes.RejectCode])
257-
tab.clickButton(FollowUpTypes.RejectCode)
258-
await tab.waitForChatFinishesLoading()
259-
260-
await tab.waitForEvent(() => tab.getChatItems().length > 7, {
261-
waitTimeoutInMs: 5000,
262-
waitIntervalInMs: 1000,
212+
assert.deepStrictEqual(rejectedMessage?.type, 'answer-part')
213+
assert.deepStrictEqual(rejectedMessage?.followUp?.options?.[0].pillText, 'Rejected')
263214
})
264-
const message = tab.getChatItems()[7]
265-
assert.deepStrictEqual(message?.type, 'answer-part')
266-
assert.deepStrictEqual(message?.followUp?.options?.[0].pillText, 'Rejected')
267215
})
268216
})
269-
})
270-
}
217+
}
218+
})
271219
})
272-
273-
// jscpd:ignore-end

packages/core/src/shared/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export { AmazonqCreateUpload, Metric } from './telemetry/telemetry'
3030
export { getClientId, getOperatingSystem } from './telemetry/util'
3131
export { extensionVersion } from './vscode/env'
3232
export { cast } from './utilities/typeConstructors'
33-
export { openTextDocument } from './utilities/workspaceUtils'
33+
export * as workspaceUtils from './utilities/workspaceUtils'
3434
export {
3535
CodewhispererUserTriggerDecision,
3636
CodewhispererLanguage,

0 commit comments

Comments
 (0)