Skip to content

Commit

Permalink
Render diff for failed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kdubb committed Oct 29, 2024
1 parent 73093ed commit e9b50ec
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 3 deletions.
2 changes: 2 additions & 0 deletions generator/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ dependencies {
testRuntimeOnly(libs.junitEngine)

testImplementation(libs.hamcrest)
testImplementation(libs.diffutils)
testImplementation(libs.cliktMarkdown)

testImplementation(libs.dockerJava)
testImplementation(libs.dockerJavaTransport)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.outfoxx.sunday.generator.kotlin

import io.outfoxx.sunday.test.extensions.DiffingExtension
import io.outfoxx.sunday.test.extensions.ResourceExtension
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.api.parallel.Execution
Expand All @@ -24,5 +25,5 @@ import org.junit.jupiter.api.parallel.ResourceLock

@Execution(ExecutionMode.CONCURRENT)
@ResourceLock("Kotlin")
@ExtendWith(ResourceExtension::class)
@ExtendWith(ResourceExtension::class, DiffingExtension::class)
annotation class KotlinTest
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.outfoxx.sunday.generator.kotlin

import com.github.difflib.text.DiffRowGenerator
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import io.outfoxx.sunday.generator.GenerationMode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.outfoxx.sunday.generator.swift

import io.outfoxx.sunday.test.extensions.DiffingExtension
import io.outfoxx.sunday.test.extensions.ResourceExtension
import io.outfoxx.sunday.test.extensions.SwiftCompilerExtension
import org.junit.jupiter.api.extension.ExtendWith
Expand All @@ -25,5 +26,5 @@ import org.junit.jupiter.api.parallel.ResourceLock

@Execution(ExecutionMode.CONCURRENT)
@ResourceLock("Swift")
@ExtendWith(ResourceExtension::class, SwiftCompilerExtension::class)
@ExtendWith(ResourceExtension::class, SwiftCompilerExtension::class, DiffingExtension::class)
annotation class SwiftTest
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.outfoxx.sunday.generator.typescript

import io.outfoxx.sunday.test.extensions.DiffingExtension
import io.outfoxx.sunday.test.extensions.ResourceExtension
import io.outfoxx.sunday.test.extensions.TypeScriptCompilerExtension
import org.junit.jupiter.api.extension.ExtendWith
Expand All @@ -25,5 +26,5 @@ import org.junit.jupiter.api.parallel.ResourceLock

@Execution(CONCURRENT)
@ResourceLock("TypeScript")
@ExtendWith(ResourceExtension::class, TypeScriptCompilerExtension::class)
@ExtendWith(ResourceExtension::class, TypeScriptCompilerExtension::class, DiffingExtension::class)
annotation class TypeScriptTest
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright 2020 Outfox, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.outfoxx.sunday.test.extensions

import com.github.ajalt.mordant.markdown.Markdown
import com.github.ajalt.mordant.rendering.TextAlign.CENTER
import com.github.ajalt.mordant.rendering.TextColors.*
import com.github.ajalt.mordant.rendering.TextStyle
import com.github.ajalt.mordant.rendering.Whitespace
import com.github.ajalt.mordant.table.Borders
import com.github.ajalt.mordant.table.ColumnWidth
import com.github.ajalt.mordant.table.table
import com.github.ajalt.mordant.terminal.Terminal
import com.github.difflib.text.DiffRow
import com.github.difflib.text.DiffRowGenerator
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.api.extension.TestExecutionExceptionHandler
import org.opentest4j.AssertionFailedError
import kotlin.math.max


class DiffingExtension : TestExecutionExceptionHandler {

private val differ: DiffRowGenerator =
DiffRowGenerator.create()
.lineNormalizer { it }
.build()
private val terminal = Terminal()

override fun handleTestExecutionException(context: ExtensionContext, throwable: Throwable) {
if (throwable !is AssertionFailedError || !throwable.isStringMismatch()) {
throw throwable
}
val diff =
differ
.generateDiffRows(
throwable.expected.value.toString().split("\n"),
throwable.actual.value.toString().split("\n")
)
val maxWidth = diff.maxOf { max(it.oldLine.length, it.newLine.length) }
terminal.println(
table {
style = TextStyle(color = white, bgColor = black, dim = true)
whitespace = Whitespace.PRE
borderStyle = TextStyle(color = white, bgColor = black, dim = true)

header {
row {
cell("Expected") { align = CENTER }
cell("Actual") { align = CENTER }
}
}
body {
for ((idx, row) in diff.withIndex()) {
val (changeStyle, prefix) =
when (row.tag) {
DiffRow.Tag.INSERT -> TextStyle(color = green) to "+"
DiffRow.Tag.DELETE -> TextStyle(color = red) to row.oldLine.ifBlank { "-" }
DiffRow.Tag.CHANGE -> TextStyle(color = cyan) to ""
null, DiffRow.Tag.EQUAL -> TextStyle(color = white, dim = true) to ""
}
row {
val borders = if (idx == diff.size - 1) Borders.LEFT_RIGHT_BOTTOM else Borders.LEFT_RIGHT
cell(row.oldLine.padEnd(maxWidth)) {
cellBorders = borders
}
cell(row.newLine.ifEmpty { prefix }.padEnd(maxWidth)) {
style = changeStyle
cellBorders = borders
}
}
}
// row { cells("", "") { cellBorders = Borders.LEFT_RIGHT_BOTTOM } }
}
}
)

throw throwable
}

private fun AssertionFailedError.isStringMismatch(): Boolean =
isExpectedDefined && isActualDefined &&
CharSequence::class.java.isAssignableFrom(expected.type) && CharSequence::class.java.isAssignableFrom(actual.type)

}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ kotlinLanguage = "1.9"
##
amfClient = "5.4.0"
clikt = "5.0.1"
diffutils = "4.12"
dockerJava = "3.4.0"
dokka = "1.9.0"
# @pin
Expand Down Expand Up @@ -60,6 +61,7 @@ versions = { id = "com.github.ben-manes.versions", version.ref = "versions" }
amfClient = { module = "com.github.amlorg:amf-api-contract_2.12", version.ref = "amfClient" }
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" }
cliktMarkdown = { module = "com.github.ajalt.clikt:clikt-markdown", version.ref = "clikt" }
diffutils = { module = "io.github.java-diff-utils:java-diff-utils", version.ref = "diffutils" }
dockerJava = { module = "com.github.docker-java:docker-java-core", version.ref = "dockerJava" }
dockerJavaTransport = { module = "com.github.docker-java:docker-java-transport-httpclient5", version.ref = "dockerJava" }
hamcrest = { module = "org.hamcrest:hamcrest-library", version.ref = "hamcrest" }
Expand Down

0 comments on commit e9b50ec

Please sign in to comment.