Skip to content

Commit

Permalink
WI-79725 Fix error stripe highlighting for arbitrary highlighting pat…
Browse files Browse the repository at this point in the history
…terns

GitOrigin-RevId: b1ac8cdb2f2232edae96f63f831d1d5b1b1160ba
  • Loading branch information
smirok authored and intellij-monorepo-bot committed Nov 15, 2024
1 parent 93f7f6b commit 8d06963
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class LogEvent(val rawText: CharSequence, val startOffset: Int, fileType: LogFil
val endOffset = startOffset + rawText.length

val date: String
private val rawLevel: String
val rawLevel: String
val category: String
val message: String
private val fullMessage: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class LogFileMapRenderer(private val myLogFileEditor: LogFileEditor) {
}
}

private fun getBucketForOffset(offsStart: Int) = (offsStart.toDouble() / (myLogFileEditor.editor.document.textLength + 1) * numBuckets).toInt()
private fun getBucketForOffset(offsStart: Int) = (offsStart.toDouble() / (myLogFileEditor.editor.document.textLength) * (numBuckets - 1)).toInt()

private var myIsPendingEventMap = true
private var myIsRunningEventMap = false
Expand Down Expand Up @@ -135,7 +135,7 @@ class LogFileMapRenderer(private val myLogFileEditor: LogFileEditor) {
var offs = 0
val isRenderingTimeHighlighting = myIsRenderingTimeHighlighting
val customPatterns = LogHighlightingSettingsStore.getInstance().myState.patterns
.filter { it.enabled && it.showOnStripe && fileFormat.validateFormatUUID(it.uuid) }
.filter { it.enabled && it.showOnStripe && fileFormat.validateFormatUUID(it.formatId) }
.map { Pattern.compile(it.pattern, Pattern.CASE_INSENSITIVE) to it }
.toTypedArray()
val customHighlightings = myLogFileEditor.editor.getUserData(highlightingSetUserKey) ?: emptySet()
Expand Down Expand Up @@ -169,14 +169,14 @@ class LogFileMapRenderer(private val myLogFileEditor: LogFileEditor) {
val logEvent = LogEvent.fromEditor(myLogFileEditor.editor, offs)
if (logEvent.rawText.isEmpty()) // At EOF
break
offs += logEvent.rawText.length
offs += logEvent.rawText.length + 1

// Attrs of this entry
val timestamp = if (isRenderingTimeHighlighting) (logEvent.date.let { fileFormat.parseLogEventTimeSeconds(it) }
?: timestampPrev) else 0
val timeDelta = if ((timestamp != null) && (timestampPrev != null)) timestamp - timestampPrev else 0
timestampPrev = timestamp
var colorCustomHighlighter: Color? = customPatterns.firstOrNull { it.first.matcher(logEvent.rawText).find() }?.second?.let {
var colorCustomHighlighter: Color? = customPatterns.firstOrNull { it.first.matcher(logEvent.rawLevel).find() }?.second?.let {
it.foregroundColor ?: it.backgroundColor
}
@Suppress("LoopToCallChain")
Expand All @@ -188,7 +188,7 @@ class LogFileMapRenderer(private val myLogFileEditor: LogFileEditor) {
}

// Roll to affected buckets
val nBucketEnd = getBucketForOffset(logEvent.startOffset + logEvent.rawText.length - 1)
val nBucketEnd = getBucketForOffset(logEvent.startOffset + logEvent.rawText.length)
(nBucketCur..nBucketEnd).forEach {
// Apply attrs to bucket
nCurBucketMaxTimeDelta = max(nCurBucketMaxTimeDelta, timeDelta)
Expand Down
123 changes: 123 additions & 0 deletions src/test/kotlin/com/intellij/ideolog/highlighting/ErrorStripeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.intellij.ideolog.highlighting

import com.intellij.ideolog.file.LogFileEditor
import com.intellij.ideolog.file.LogFileEditorProvider
import com.intellij.ideolog.highlighting.settings.DefaultSettingsStoreItems
import com.intellij.ideolog.highlighting.settings.LogHighlightingPattern
import com.intellij.ideolog.highlighting.settings.LogHighlightingSettingsStore
import com.intellij.ideolog.util.ideologContext
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl
import com.intellij.openapi.editor.markup.MarkupModel
import com.intellij.openapi.editor.markup.RangeHighlighter
import com.intellij.openapi.util.Disposer
import com.intellij.testFramework.PlatformTestUtil
import com.intellij.testFramework.TestDataPath
import com.intellij.testFramework.fixtures.BasePlatformTestCase
import com.intellij.util.ui.UIUtil
import java.awt.Color
import kotlin.math.abs

@TestDataPath("\$CONTENT_ROOT/src/test/resources/highlighting/errorStripe")
class ErrorStripeTest : BasePlatformTestCase() {
private lateinit var editor: LogFileEditor
private lateinit var highlightingPatternsBackup: List<LogHighlightingPattern>

override fun setUp() {
super.setUp()
highlightingPatternsBackup = LogHighlightingSettingsStore.getInstance().myState.patterns.map { it.copy() }
}

override fun tearDown() {
try {
LogHighlightingSettingsStore.getInstance().myState.patterns.clear()
LogHighlightingSettingsStore.getInstance().myState.patterns.addAll(highlightingPatternsBackup)
if (::editor.isInitialized) {
Disposer.dispose(editor)
}
}
catch (e: Throwable) {
addSuppressedException(e)
}
finally {
super.tearDown()
}
}

override fun getTestDataPath(): String = "src/test/resources/highlighting/errorStripe"

fun testUndetectedFormat() {
val markupModel = createMarkupModel()
val format = markupModel.document.ideologContext.detectLogFileFormat()
assertNull(format.myRegexLogParser?.uuid)

val highlighters = markupModel.allHighlighters.map { highlighter ->
highlighter.getTextAttributes(editor.editor.colorsScheme)?.errorStripeColor?.toTimeIndependent()
}.toSet()
assertSize(1, highlighters)
}

fun testFirstNonStripedEventLineNotOnStripe() {
val highlighters = calculateHighlighters()
val endOfFirstLine = editor.editor.document.getLineEndOffset(0)
val visibleHighlighters = highlighters.filter { it.startOffset > endOfFirstLine + 1 }.mapNotNull { highlighter ->
highlighter.getTextAttributes(editor.editor.colorsScheme)?.errorStripeColor?.toTimeIndependent()
}.toSet()
assertSize(1, visibleHighlighters)
}

fun testFirstStripedEventLineNotOnStripe() {
val highlighters = calculateHighlighters()
val endOfFirstLine = editor.editor.document.getLineEndOffset(0)
val visibleHighlighters = highlighters.filter { it.startOffset > endOfFirstLine + 1 }.mapNotNull { highlighter ->
highlighter.getTextAttributes(editor.editor.colorsScheme)?.errorStripeColor?.toTimeIndependent()
}.toSet()
assertSize(1, visibleHighlighters)
}

fun testNoStripedEvents() {
val highlighters = calculateUniqueHighlighters()
assertSize(1, highlighters)
}

fun testDefaultErrorStripedEvents() {
val highlighters = calculateUniqueHighlighters()
assertSize(2, highlighters)
}

fun testCustomStripedEvents() {
assertTrue(LogHighlightingSettingsStore.getInstance().myState.patterns.removeIf {
it.uuid.toString() == "11ff1574-2118-4722-905a-61bec89b079e"
})
LogHighlightingSettingsStore.getInstance().myState.patterns.add(DefaultSettingsStoreItems.Warning.copy(showOnStripe = true))
val highlighters = calculateUniqueHighlighters()
assertSize(2, highlighters)
}

private fun calculateHighlighters(): Array<out RangeHighlighter> {
val markupModel = createMarkupModel()
return markupModel.allHighlighters
}

private fun calculateUniqueHighlighters(): Set<Color?> {
val markupModel = createMarkupModel()
return markupModel.allHighlighters.mapNotNull { highlighter ->
highlighter.getTextAttributes(editor.editor.colorsScheme)?.errorStripeColor?.toTimeIndependent()
}.toSet()
}

private fun createMarkupModel(): MarkupModel {
val file = myFixture.copyFileToProject(getTestName(false) + ".log")
editor = LogFileEditorProvider().createEditor(project, file) as LogFileEditor
val mapRenderer = LogFileMapRenderer.getLogFileMapRenderer(editor.editor)
Thread.sleep(1000)
NonBlockingReadActionImpl.waitForAsyncTaskCompletion()
UIUtil.dispatchAllInvocationEvents()
PlatformTestUtil.dispatchAllEventsInIdeEventQueue()
assertNotNull(mapRenderer)
val markupModel = editor.editor.markupModel
assertEquals(1024, markupModel.allHighlighters.size)
return markupModel
}

private fun Color.toTimeIndependent(): Color = Color(abs(this.red - this.blue), 0, 0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[2022-07-11 10:00:47] production.WARNING: No application encryption key has been specified.
[2022-07-11 10:00:47] custom.INFO: Successfully imported customer 123456
[2022-07-11 10:00:47] production.WARNING: No application encryption key has been specified.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[2022-07-11 10:00:47] production.ERROR: No application encryption key has been specified.
[2022-07-11 10:00:47] custom.INFO: Successfully imported customer 123456
[2022-07-11 10:00:47] production.ERROR: No application encryption key has been specified.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[2022-07-11 10:00:47] custom.INFO: Successfully imported customer 123456
[2022-07-11 10:00:47] production.ERROR: No application encryption key has been specified.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[2022-07-11 10:00:47] production.ERROR: No application encryption key has been specified.
[2022-07-11 10:00:47] custom.INFO: Successfully imported customer 123456
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[2022-07-11 10:00:47] production.WARNING: Vite manifest not found
[2018-08-02 03:02:42] custom.INFO: Successfully imported customer 123456
[2022-07-11 10:00:47] production.WARNING: Vite manifest not found
[2018-08-02 03:02:42] custom.INFO: Successfully imported customer 123456
[2018-08-02 03:02:42] custom.INFO: Successfully imported customer 123456
[2022-07-11 10:00:47] production.WARNING: Vite manifest not found
12 changes: 12 additions & 0 deletions src/test/resources/highlighting/errorStripe/UndetectedFormat.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[??] production.WARNING: Vite manifest not found
[??] custom.INFO: Successfully imported customer 123456
[??] production.WARNING: Vite manifest not found
[??] production.ERROR: No application encryption key has been specified.
#0 something
at somewhere
[??] custom.INFO: Successfully imported customer 123456
[??] custom.INFO: Successfully imported customer 123456
[??] production.WARNING: Vite manifest not found
[??] production.ERROR: No application encryption key has been specified.
#0 something
at somewhere

0 comments on commit 8d06963

Please sign in to comment.