scalafix.testkit.DiffAssertions.scala Maven / Gradle / Ivy
package scalafix.testkit
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.TimeZone
import org.scalatest.Suite
import org.scalatest.exceptions.TestFailedException
object DiffAssertions {
def compareContents(original: String, revised: String): String = {
def splitLines(s: String) =
s.trim
.replaceAllLiterally("\r\n", "\n")
.replace(" +$", "")
.split("\n")
compareContents(splitLines(original), splitLines(revised))
}
def compareContents(original: Seq[String], revised: Seq[String]): String = {
import collection.JavaConverters._
val diff = difflib.DiffUtils.diff(original.asJava, revised.asJava)
if (diff.getDeltas.isEmpty) ""
else
difflib.DiffUtils
.generateUnifiedDiff(
"obtained",
"expected",
original.asJava,
diff,
1
)
.asScala
.mkString("\n")
}
}
trait DiffAssertions extends Suite {
def assertEqual[A](a: A, b: A): Unit = {
assert(a === b)
}
def header[T](t: T): String = {
val line = s"=" * (t.toString.length + 3)
s"$line\n=> $t\n$line"
}
case class DiffFailure(
title: String,
expected: String,
obtained: String,
diff: String
) extends TestFailedException(
title + "\n--- obtained\n+++ expected\n" + error2message(
obtained,
expected
),
3
)
def error2message(obtained: String, expected: String): String = {
val sb = new StringBuilder
if (obtained.length < 1000) {
sb.append(s"""
#${header("Obtained")}
#${trailingSpace(obtained)}
""".stripMargin('#'))
}
sb.append(s"""
#${header("Diff")}
#${trailingSpace(compareContents(obtained, expected))}
""".stripMargin('#'))
sb.toString()
}
def assertNoDiffOrPrintExpected(
obtained: String,
expected: String
): Boolean = {
assertNoDiff(obtained, expected, printObtained = true)
}
def assertNoDiff(
obtained: String,
expected: String,
title: String = "",
printObtained: Boolean = false
): Boolean = {
val result = compareContents(obtained, expected)
if (result.isEmpty) true
else if (obtained.linesIterator.toList == expected.linesIterator.toList) {
// Ignore \r\n and \n differences
true
} else {
if (printObtained) {
println("\"\"\"|")
obtained.linesIterator.foreach { line =>
print(" |")
println(line)
}
}
throw DiffFailure(title, expected, obtained, result)
}
}
def trailingSpace(str: String): String = str.replaceAll(" \n", "∙\n")
def compareContents(original: String, revised: String): String =
DiffAssertions.compareContents(original, revised)
def compareContents(original: Seq[String], revised: Seq[String]): String =
DiffAssertions.compareContents(original, revised)
def fileModificationTimeOrEpoch(file: File): String = {
val format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss Z")
if (file.exists) format.format(new Date(file.lastModified()))
else {
format.setTimeZone(TimeZone.getTimeZone("UTC"))
format.format(new Date(0L))
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy