diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/clients/FeatureDevClient.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/clients/FeatureDevClient.kt index 7d6abb05d9f..29a1feb1a05 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/clients/FeatureDevClient.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/clients/FeatureDevClient.kt @@ -89,6 +89,42 @@ class FeatureDevClient( requestBuilder.userContext(featureDevUserContext) } + fun sendFeatureDevCodeGenerationEvent( + conversationId: String, + linesOfCodeGenerated: Int, + charactersOfCodeGenerated: Int, + ): SendTelemetryEventResponse = + bearerClient().sendTelemetryEvent { requestBuilder -> + requestBuilder.telemetryEvent { telemetryEventBuilder -> + telemetryEventBuilder.featureDevCodeGenerationEvent { + it + .conversationId(conversationId) + .linesOfCodeGenerated(linesOfCodeGenerated) + .charactersOfCodeGenerated(charactersOfCodeGenerated) + } + } + requestBuilder.optOutPreference(getTelemetryOptOutPreference()) + requestBuilder.userContext(featureDevUserContext) + } + + fun sendFeatureDevCodeAcceptanceEvent( + conversationId: String, + linesOfCodeAccepted: Int, + charactersOfCodeAccepted: Int, + ): SendTelemetryEventResponse = + bearerClient().sendTelemetryEvent { requestBuilder -> + requestBuilder.telemetryEvent { telemetryEventBuilder -> + telemetryEventBuilder.featureDevCodeAcceptanceEvent { + it + .conversationId(conversationId) + .linesOfCodeAccepted(linesOfCodeAccepted) + .charactersOfCodeAccepted(charactersOfCodeAccepted) + } + } + requestBuilder.optOutPreference(getTelemetryOptOutPreference()) + requestBuilder.userContext(featureDevUserContext) + } + fun createTaskAssistConversation(): CreateTaskAssistConversationResponse = bearerClient().createTaskAssistConversation( CreateTaskAssistConversationRequest.builder().build(), diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationState.kt index 802db7dcf31..5b172e73c7d 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationState.kt @@ -20,6 +20,9 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.ThrottlingExce import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.sendAnswerPart import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.sendUpdatePlaceholder import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.getChangeIdentifier +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.getDiffMetrics +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.readFileToString import software.aws.toolkits.jetbrains.services.cwc.controller.chat.telemetry.getStartUrl import software.aws.toolkits.resources.message import software.aws.toolkits.telemetry.AmazonqTelemetry @@ -40,6 +43,7 @@ class CodeGenerationState( override var codeGenerationTotalIterationCount: Int? = null, var currentCodeGenerationId: String? = "EMPTY_CURRENT_CODE_GENERATION_ID", override var token: CancellationTokenSource?, + override var diffMetricsProcessed: DiffMetricsProcessed, ) : SessionState { override val phase = SessionStatePhase.CODEGEN @@ -81,6 +85,41 @@ class CodeGenerationState( codeGenerationRemainingIterationCount = codeGenerationResult.codeGenerationRemainingIterationCount codeGenerationTotalIterationCount = codeGenerationResult.codeGenerationTotalIterationCount + runCatching { + var insertedLines = 0 + var insertedCharacters = 0 + codeGenerationResult.newFiles.forEach { file -> + // FIXME: Ideally, the before content should be read from the uploaded context instead of from disk, to avoid drift + val before = config.repoContext.selectedSourceFolder + .toNioPath() + .resolve(file.zipFilePath) + .toFile() + .let { f -> + if (f.exists() && f.canRead()) { + readFileToString(f) + } else { + "" + } + } + + val changeIdentifier = getChangeIdentifier(file.zipFilePath, before, file.fileContent) + + if (!diffMetricsProcessed.generated.contains(changeIdentifier)) { + val diffMetrics = getDiffMetrics(before, file.fileContent) + insertedLines += diffMetrics.insertedLines + insertedCharacters += diffMetrics.insertedCharacters + diffMetricsProcessed.generated.add(changeIdentifier) + } + } + if (insertedLines > 0) { + config.featureDevService.sendFeatureDevCodeGenerationEvent( + conversationId = config.conversationId, + linesOfCodeGenerated = insertedLines, + charactersOfCodeGenerated = insertedCharacters, + ) + } + }.onFailure { /* Noop on diff telemetry failure */ } + val nextState = PrepareCodeGenerationState( tabID = tabID, @@ -95,6 +134,7 @@ class CodeGenerationState( codeGenerationRemainingIterationCount = codeGenerationRemainingIterationCount, codeGenerationTotalIterationCount = codeGenerationTotalIterationCount, token = this.token, + diffMetricsProcessed = diffMetricsProcessed, ) // It is not needed to interact right away with the PrepareCodeGeneration. diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/ConversationNotStartedState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/ConversationNotStartedState.kt index 9d1fa195ade..2b687d144d4 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/ConversationNotStartedState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/ConversationNotStartedState.kt @@ -12,6 +12,7 @@ class ConversationNotStartedState( override var codeGenerationRemainingIterationCount: Int?, override var codeGenerationTotalIterationCount: Int?, override var currentIteration: Int?, + override var diffMetricsProcessed: DiffMetricsProcessed, ) : SessionState { override val phase = SessionStatePhase.INIT diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationState.kt index 5a397919ac5..61cf36737b0 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationState.kt @@ -34,6 +34,7 @@ class PrepareCodeGenerationState( private var messenger: MessagePublisher, override var codeGenerationRemainingIterationCount: Int? = null, override var codeGenerationTotalIterationCount: Int? = null, + override var diffMetricsProcessed: DiffMetricsProcessed, ) : SessionState { override val phase = SessionStatePhase.CODEGEN override suspend fun interact(action: SessionStateAction): SessionStateInteraction { @@ -74,7 +75,8 @@ class PrepareCodeGenerationState( currentIteration = this.currentIteration, repositorySize = zipFileLength.toDouble(), messenger = messenger, - token = this.token + token = this.token, + diffMetricsProcessed = diffMetricsProcessed ) } catch (e: Exception) { result = Result.Failed diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/Session.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/Session.kt index 2a37e020eee..7a2b42110eb 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/Session.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/Session.kt @@ -18,9 +18,13 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.sendA import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.updateFileComponent import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.CancellationTokenSource import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.FeatureDevService +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.getChangeIdentifier +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.getDiffMetrics +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.readFileToString import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.resolveAndCreateOrUpdateFile import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.resolveAndDeleteFile import software.aws.toolkits.jetbrains.services.cwc.controller.ReferenceLogController +import java.util.HashSet class Session(val tabID: String, val project: Project) { var context: FeatureDevSessionContext @@ -45,7 +49,15 @@ class Session(val tabID: String, val project: Project) { context = FeatureDevSessionContext(project, MAX_PROJECT_SIZE_BYTES) proxyClient = FeatureDevClient.getInstance(project) featureDevService = FeatureDevService(proxyClient, project) - _state = ConversationNotStartedState("", tabID, null, 0, CODE_GENERATION_RETRY_LIMIT, 0) + _state = ConversationNotStartedState( + approach = "", + tabID = tabID, + token = null, + codeGenerationRemainingIterationCount = 0, + codeGenerationTotalIterationCount = CODE_GENERATION_RETRY_LIMIT, + currentIteration = 0, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()) + ) isAuthenticating = false codegenRetries = CODE_GENERATION_RETRY_LIMIT } @@ -86,6 +98,7 @@ class Session(val tabID: String, val project: Project) { uploadId = "", // There is no code gen uploadId so far messenger = messenger, token = CancellationTokenSource(), + diffMetricsProcessed = sessionState.diffMetricsProcessed, ) } @@ -110,6 +123,42 @@ class Session(val tabID: String, val project: Project) { val selectedSourceFolder = context.selectedSourceFolder.toNioPath() val newFilePaths = filePaths.filter { !it.rejected && !it.changeApplied } val newDeletedFiles = deletedFiles.filter { !it.rejected && !it.changeApplied } + + runCatching { + var insertedLines = 0 + var insertedCharacters = 0 + filePaths.forEach { file -> + // FIXME: Ideally, the before content should be read from the uploaded context instead of from disk, to avoid drift + val before = selectedSourceFolder + .resolve(file.zipFilePath) + .toFile() + .let { f -> + if (f.exists() && f.canRead()) { + readFileToString(f) + } else { + "" + } + } + + val changeIdentifier = getChangeIdentifier(file.zipFilePath, before, file.fileContent) + + if (_state?.diffMetricsProcessed?.accepted?.contains(changeIdentifier) != true) { + val diffMetrics = getDiffMetrics(before, file.fileContent) + insertedLines += diffMetrics.insertedLines + insertedCharacters += diffMetrics.insertedCharacters + _state?.diffMetricsProcessed?.accepted?.add(changeIdentifier) + } + } + + if (insertedLines > 0) { + featureDevService.sendFeatureDevCodeAcceptanceEvent( + conversationId = conversationId, + linesOfCodeAccepted = insertedLines, + charactersOfCodeAccepted = insertedCharacters, + ) + } + }.onFailure { /* Noop on diff telemetry failure */ } + newFilePaths.forEach { resolveAndCreateOrUpdateFile(selectedSourceFolder, it.zipFilePath, it.fileContent) it.changeApplied = true diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionState.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionState.kt index cc98e0f0b95..c1248a74dd8 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionState.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionState.kt @@ -13,5 +13,6 @@ interface SessionState { var codeGenerationTotalIterationCount: Int? var currentIteration: Int? var approach: String + var diffMetricsProcessed: DiffMetricsProcessed suspend fun interact(action: SessionStateAction): SessionStateInteraction } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionStateTypes.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionStateTypes.kt index e0af47770b9..0567bf980a1 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionStateTypes.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/SessionStateTypes.kt @@ -77,3 +77,8 @@ data class CodeGenerationStreamResult( data class ExportTaskAssistResultArchiveStreamResult( var code_generation_result: CodeGenerationStreamResult, ) + +data class DiffMetricsProcessed( + var accepted: HashSet, + var generated: HashSet, +) diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetrics.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetrics.kt index 23e9dcd4f3e..46b44bf7f90 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetrics.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetrics.kt @@ -7,6 +7,9 @@ import com.intellij.diff.comparison.ComparisonManager import com.intellij.diff.comparison.ComparisonPolicy import com.intellij.diff.fragments.LineFragment import com.intellij.openapi.progress.EmptyProgressIndicator +import io.ktor.utils.io.core.toByteArray +import java.nio.charset.Charset +import java.security.MessageDigest data class DiffMetrics( val insertedLines: Int, @@ -37,7 +40,7 @@ fun getDiffMetrics(before: String, after: String): DiffMetrics { val fragments = comparisonManager.compareLines( before, after, - ComparisonPolicy.DEFAULT, + ComparisonPolicy.IGNORE_WHITESPACES, EmptyProgressIndicator() ) @@ -71,3 +74,11 @@ fun getDiffMetrics(before: String, after: String): DiffMetrics { insertedCharacters = accCharCount, ) } + +fun getChangeIdentifier(filePath: String, before: String, after: String): String { + val hash = MessageDigest.getInstance("SHA-1") + hash.update(filePath.toByteArray(Charset.forName("UTF-8"))) + hash.update(before.toByteArray(Charset.forName("UTF-8"))) + hash.update(after.toByteArray(Charset.forName("UTF-8"))) + return hash.digest().joinToString("") { "%02x".format(it) } +} diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt index 7f5676162c8..57f0dac8ef9 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FeatureDevService.kt @@ -215,4 +215,32 @@ class FeatureDevService(val proxyClient: FeatureDevClient, val project: Project) logger.warn(e) { "$FEATURE_NAME: failed to send feature dev telemetry" } } } + + fun sendFeatureDevCodeGenerationEvent(conversationId: String, linesOfCodeGenerated: Int, charactersOfCodeGenerated: Int) { + val sendFeatureDevTelemetryEventResponse: SendTelemetryEventResponse + try { + sendFeatureDevTelemetryEventResponse = proxyClient + .sendFeatureDevCodeGenerationEvent(conversationId, linesOfCodeGenerated, charactersOfCodeGenerated) + val requestId = sendFeatureDevTelemetryEventResponse.responseMetadata().requestId() + logger.debug { + "$FEATURE_NAME: successfully sent feature dev code generation telemetry: ConversationId: $conversationId RequestId: $requestId" + } + } catch (e: Exception) { + logger.warn(e) { "$FEATURE_NAME: failed to send feature dev code generation telemetry" } + } + } + + fun sendFeatureDevCodeAcceptanceEvent(conversationId: String, linesOfCodeAccepted: Int, charactersOfCodeAccepted: Int) { + val sendFeatureDevTelemetryEventResponse: SendTelemetryEventResponse + try { + sendFeatureDevTelemetryEventResponse = proxyClient + .sendFeatureDevCodeAcceptanceEvent(conversationId, linesOfCodeAccepted, charactersOfCodeAccepted) + val requestId = sendFeatureDevTelemetryEventResponse.responseMetadata().requestId() + logger.debug { + "$FEATURE_NAME: successfully sent feature dev code acceptance telemetry: ConversationId: $conversationId RequestId: $requestId" + } + } catch (e: Exception) { + logger.warn(e) { "$FEATURE_NAME: failed to send feature dev code acceptance telemetry" } + } + } } diff --git a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FileUtils.kt b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FileUtils.kt index 7d901bc0e72..c1013708828 100644 --- a/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FileUtils.kt +++ b/plugins/amazonq/chat/jetbrains-community/src/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/FileUtils.kt @@ -6,7 +6,10 @@ package software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util import com.intellij.openapi.fileChooser.FileChooser import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.CharsetToolkit import com.intellij.openapi.vfs.VirtualFile +import java.io.File +import java.nio.charset.Charset import java.nio.file.Path import kotlin.io.path.createDirectories import kotlin.io.path.deleteIfExists @@ -33,3 +36,9 @@ fun selectFolder(project: Project, openOn: VirtualFile): VirtualFile? { val fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor() return FileChooser.chooseFile(fileChooserDescriptor, project, openOn) } + +fun readFileToString(file: File): String { + val charsetToolkit = CharsetToolkit(file.readBytes(), Charset.forName("UTF-8"), false) + val charset = charsetToolkit.guessEncoding(4096) + return file.readText(charset) +} diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevControllerTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevControllerTest.kt index 7b328b4e49f..3a3c2025d3d 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevControllerTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/controller/FeatureDevControllerTest.kt @@ -50,6 +50,7 @@ import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.sendS import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.sendUpdatePlaceholder import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.messages.updateFileComponent import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.DeletedFileInfo +import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.DiffMetricsProcessed import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.Interaction import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.NewFileZipInfo import software.aws.toolkits.jetbrains.services.amazonqFeatureDev.session.PrepareCodeGenerationState @@ -236,6 +237,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { messenger, 0, 0, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) @@ -295,6 +297,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) @@ -354,6 +357,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) whenever(mockSession.retries).thenReturn(3) @@ -393,6 +397,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) whenever(mockSession.retries).thenReturn(0) @@ -425,6 +430,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) @@ -458,6 +464,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) doReturn(testConversationId).`when`(spySession).conversationId @@ -514,6 +521,7 @@ class FeatureDevControllerTest : FeatureDevTestBase() { testUploadId, 0, messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ), ) doReturn(testConversationId).`when`(spySession).conversationId diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationStateTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationStateTest.kt index d655ffc60e7..bc31ea9d77f 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationStateTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/CodeGenerationStateTest.kt @@ -59,6 +59,7 @@ class CodeGenerationStateTest : FeatureDevTestBase() { messenger, token = null, currentCodeGenerationId = "EMPTY_CURRENT_CODE_GENERATION_ID", + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()), ) mockkStatic(MessagePublisher::sendAnswerPart) diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationStateTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationStateTest.kt index 49aa4d906e3..b7ef89ebd54 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationStateTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/session/PrepareCodeGenerationStateTest.kt @@ -61,7 +61,8 @@ class PrepareCodeGenerationStateTest : FeatureDevTestBase() { emptyList(), testUploadId, 0, - messenger + messenger, + diffMetricsProcessed = DiffMetricsProcessed(HashSet(), HashSet()) ) mockkStatic("software.aws.toolkits.jetbrains.services.amazonqFeatureDev.util.UploadArtifactKt") diff --git a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetricsTest.kt b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetricsTest.kt index 1283810dab2..8b4b5721ba4 100644 --- a/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetricsTest.kt +++ b/plugins/amazonq/chat/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/amazonqFeatureDev/util/DiffMetricsTest.kt @@ -117,10 +117,19 @@ class DiffMetricsTest : LightPlatformTestCase() { fun `test leading and trailing whitespace are not counted as characters`() { val before = "line1\nline2" - val after = "line1\n line2" + val after = "line1\n after " val metrics = getDiffMetrics(before, after) assertEquals(1, metrics.insertedLines) assertEquals(5, metrics.insertedCharacters) } + + fun `test ignore whitespace change when performing diff`() { + val before = "line1\nline2" + val after = "line1\n line2" + + val metrics = getDiffMetrics(before, after) + assertEquals(0, metrics.insertedLines) + assertEquals(0, metrics.insertedCharacters) + } }