@@ -8,8 +8,10 @@ import assert from 'assert'
88import sinon from 'sinon'
99import { DocPrepareCodeGenState } from '../../../amazonqDoc'
1010import { createMockSessionStateAction } from '../../amazonq/utils'
11-
1211import { createTestContext , setupTestHooks } from '../../amazonq/session/testSetup'
12+ import * as filesModule from '../../../amazonq/util/files'
13+ import { CodeGenBase } from '../../../amazonq/session/sessionState'
14+ import { RunCommandLogFileName } from '../../../amazonq/session/sessionState'
1315
1416describe ( 'sessionStateDoc' , ( ) => {
1517 const context = createTestContext ( )
@@ -26,4 +28,161 @@ describe('sessionStateDoc', () => {
2628 } )
2729 } )
2830 } )
31+
32+ describe ( 'CodeGenBase generateCode log file handling' , ( ) => {
33+ class TestCodeGen extends CodeGenBase {
34+ public generatedFiles : any [ ] = [ ]
35+ constructor ( config : any , tabID : string ) {
36+ super ( config , tabID )
37+ }
38+ protected handleProgress ( _messenger : any ) : void {
39+ // No-op for test.
40+ }
41+ protected getScheme ( ) : string {
42+ return 'file'
43+ }
44+ protected getTimeoutErrorCode ( ) : string {
45+ return 'test_timeout'
46+ }
47+ protected handleGenerationComplete ( _messenger : any , newFileInfo : any [ ] ) : void {
48+ this . generatedFiles = newFileInfo
49+ }
50+ protected handleError ( _messenger : any , _codegenResult : any ) : Error {
51+ throw new Error ( 'handleError called' )
52+ }
53+ }
54+
55+ let fakeProxyClient : any
56+ let testConfig : any
57+ let fsMock : any
58+ let messengerMock : any
59+ let telemetryMock : any
60+ let loggerMock : any
61+ let testAction : any
62+ let registerNewFilesStub : any
63+
64+ beforeEach ( ( ) => {
65+ fakeProxyClient = {
66+ getCodeGeneration : sinon . stub ( ) . resolves ( {
67+ codeGenerationStatus : { status : 'Complete' } ,
68+ codeGenerationRemainingIterationCount : 0 ,
69+ codeGenerationTotalIterationCount : 1 ,
70+ } ) ,
71+ exportResultArchive : sinon . stub ( ) ,
72+ }
73+
74+ testConfig = {
75+ conversationId : 'conv_test' ,
76+ uploadId : 'upload_test' ,
77+ workspaceRoots : [ '/workspace' ] ,
78+ proxyClient : fakeProxyClient ,
79+ }
80+
81+ fsMock = {
82+ writeFile : sinon . stub ( ) . resolves ( ) ,
83+ }
84+
85+ messengerMock = { sendAnswer : sinon . spy ( ) }
86+
87+ telemetryMock = {
88+ setCodeGenerationResult : sinon . spy ( ) ,
89+ setNumberOfFilesGenerated : sinon . spy ( ) ,
90+ setAmazonqNumberOfReferences : sinon . spy ( ) ,
91+ setGenerateCodeIteration : sinon . spy ( ) ,
92+ setGenerateCodeLastInvocationTime : sinon . spy ( ) ,
93+ recordUserCodeGenerationTelemetry : sinon . spy ( ) ,
94+ }
95+
96+ loggerMock = {
97+ addContent : sinon . spy ( ) ,
98+ }
99+
100+ testAction = {
101+ fs : fsMock ,
102+ messenger : messengerMock ,
103+ logger : loggerMock ,
104+ tokenSource : { token : { isCancellationRequested : false , onCancellationRequested : ( ) => { } } } ,
105+ }
106+
107+ registerNewFilesStub = sinon
108+ . stub ( filesModule , 'registerNewFiles' )
109+ . callsFake ( ( _ , newFileContents : any [ ] ) => {
110+ return newFileContents
111+ } )
112+ } )
113+
114+ afterEach ( ( ) => {
115+ sinon . restore ( )
116+ } )
117+
118+ it ( 'adds the log content to logger if present and excludes it from new files' , async ( ) => {
119+ const logFileInfo = {
120+ zipFilePath : RunCommandLogFileName ,
121+ fileContent : 'newLog' ,
122+ }
123+ const otherFile = { zipFilePath : 'other.ts' , fileContent : 'other content' }
124+ fakeProxyClient . exportResultArchive . resolves ( {
125+ newFileContents : [ logFileInfo , otherFile ] ,
126+ deletedFiles : [ ] ,
127+ references : [ ] ,
128+ } )
129+
130+ const testCodeGen = new TestCodeGen ( testConfig , 'tab1' )
131+
132+ const result = await testCodeGen . generateCode ( {
133+ messenger : messengerMock ,
134+ fs : fsMock ,
135+ codeGenerationId : 'codegen1' ,
136+ telemetry : telemetryMock ,
137+ workspaceFolders : [ ] as any ,
138+ action : testAction ,
139+ } )
140+
141+ sinon . assert . calledWith ( loggerMock . addContent , `Run Command logs: \n ${ logFileInfo . fileContent } ` )
142+
143+ sinon . assert . calledWith (
144+ registerNewFilesStub ,
145+ fsMock ,
146+ [ otherFile ] ,
147+ testConfig . uploadId ,
148+ [ ] as any ,
149+ testConfig . conversationId ,
150+ 'file'
151+ )
152+
153+ assert . deepStrictEqual ( result . newFiles , [ otherFile ] )
154+ } )
155+
156+ it ( 'skips log file handling if log file is not present' , async ( ) => {
157+ const file1 = { zipFilePath : 'file1.ts' , fileContent : 'content1' }
158+ fakeProxyClient . exportResultArchive . resolves ( {
159+ newFileContents : [ file1 ] ,
160+ deletedFiles : [ ] ,
161+ references : [ ] ,
162+ } )
163+
164+ const testCodeGen = new TestCodeGen ( testConfig , 'tab1' )
165+
166+ const result = await testCodeGen . generateCode ( {
167+ messenger : messengerMock ,
168+ fs : fsMock ,
169+ codeGenerationId : 'codegen2' ,
170+ telemetry : telemetryMock ,
171+ workspaceFolders : [ ] as any ,
172+ action : testAction ,
173+ } )
174+
175+ sinon . assert . notCalled ( loggerMock . addContent )
176+ sinon . assert . calledWith (
177+ registerNewFilesStub ,
178+ fsMock ,
179+ [ file1 ] ,
180+ testConfig . uploadId ,
181+ [ ] as any ,
182+ testConfig . conversationId ,
183+ 'file'
184+ )
185+ assert . deepStrictEqual ( result . newFiles , [ file1 ] )
186+ } )
187+ } )
29188} )
0 commit comments