@@ -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,162 @@ 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+ info : sinon . spy ( ) ,
99+ }
100+
101+ testAction = {
102+ fs : fsMock ,
103+ messenger : messengerMock ,
104+ logger : loggerMock ,
105+ tokenSource : { token : { isCancellationRequested : false , onCancellationRequested : ( ) => { } } } ,
106+ }
107+
108+ registerNewFilesStub = sinon
109+ . stub ( filesModule , 'registerNewFiles' )
110+ . callsFake ( ( _ , newFileContents : any [ ] ) => {
111+ return newFileContents
112+ } )
113+ } )
114+
115+ afterEach ( ( ) => {
116+ sinon . restore ( )
117+ } )
118+
119+ it ( 'adds the log content to logger if present and excludes it from new files' , async ( ) => {
120+ const logFileInfo = {
121+ zipFilePath : RunCommandLogFileName ,
122+ fileContent : 'newLog' ,
123+ }
124+ const otherFile = { zipFilePath : 'other.ts' , fileContent : 'other content' }
125+ fakeProxyClient . exportResultArchive . resolves ( {
126+ newFileContents : [ logFileInfo , otherFile ] ,
127+ deletedFiles : [ ] ,
128+ references : [ ] ,
129+ } )
130+
131+ const testCodeGen = new TestCodeGen ( testConfig , 'tab1' )
132+
133+ const result = await testCodeGen . generateCode ( {
134+ messenger : messengerMock ,
135+ fs : fsMock ,
136+ codeGenerationId : 'codegen1' ,
137+ telemetry : telemetryMock ,
138+ workspaceFolders : [ ] as any ,
139+ action : testAction ,
140+ } )
141+
142+ sinon . assert . calledWith ( loggerMock . info , `Run Command logs: \n ${ logFileInfo . fileContent } ` )
143+
144+ sinon . assert . calledWith (
145+ registerNewFilesStub ,
146+ fsMock ,
147+ [ otherFile ] ,
148+ testConfig . uploadId ,
149+ [ ] as any ,
150+ testConfig . conversationId ,
151+ 'file'
152+ )
153+
154+ assert . deepStrictEqual ( result . newFiles , [ otherFile ] )
155+ } )
156+
157+ it ( 'skips log file handling if log file is not present' , async ( ) => {
158+ const file1 = { zipFilePath : 'file1.ts' , fileContent : 'content1' }
159+ fakeProxyClient . exportResultArchive . resolves ( {
160+ newFileContents : [ file1 ] ,
161+ deletedFiles : [ ] ,
162+ references : [ ] ,
163+ } )
164+
165+ const testCodeGen = new TestCodeGen ( testConfig , 'tab1' )
166+
167+ const result = await testCodeGen . generateCode ( {
168+ messenger : messengerMock ,
169+ fs : fsMock ,
170+ codeGenerationId : 'codegen2' ,
171+ telemetry : telemetryMock ,
172+ workspaceFolders : [ ] as any ,
173+ action : testAction ,
174+ } )
175+
176+ sinon . assert . notCalled ( loggerMock . info )
177+ sinon . assert . calledWith (
178+ registerNewFilesStub ,
179+ fsMock ,
180+ [ file1 ] ,
181+ testConfig . uploadId ,
182+ [ ] as any ,
183+ testConfig . conversationId ,
184+ 'file'
185+ )
186+ assert . deepStrictEqual ( result . newFiles , [ file1 ] )
187+ } )
188+ } )
29189} )
0 commit comments