Skip to content

Commit

Permalink
Merge pull request #756 from majk-p/extract-diff-module
Browse files Browse the repository at this point in the history
Extract diff module
  • Loading branch information
tgodzik committed Apr 24, 2024
2 parents 83cb747 + 25ce89f commit a66abd5
Show file tree
Hide file tree
Showing 29 changed files with 406 additions and 283 deletions.
103 changes: 27 additions & 76 deletions build.sbt
@@ -1,4 +1,3 @@
import com.typesafe.tools.mima.core._
import sbtcrossproject.CrossPlugin.autoImport.crossProject
import sbtcrossproject.CrossPlugin.autoImport.CrossType
import scala.collection.mutable
Expand Down Expand Up @@ -66,81 +65,7 @@ def isScala3(v: Option[(Long, Long)]): Boolean = v.exists(_._1 == 3)
lazy val skipIdeaSettings =
SettingKey[Boolean]("ide-skip-project").withRank(KeyRanks.Invisible) := true
lazy val mimaEnable: List[Def.Setting[_]] = List(
mimaBinaryIssueFilters ++= List(
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.MUnitRunner.descriptions"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.MUnitRunner.testNames"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.MUnitRunner.munitTests"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.ValueTransforms.munitTimeout"
),
ProblemFilters.exclude[MissingTypesProblem]("munit.FailException"),
ProblemFilters.exclude[MissingTypesProblem]("munit.FailSuiteException"),
ProblemFilters.exclude[MissingTypesProblem](
"munit.TestValues$FlakyFailure"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.internal.junitinterface.JUnitComputer.this"
),
// Known breaking changes for MUnit v1
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.Assertions.assertNotEquals"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.Assertions.assertEquals"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.Assertions.assertNotEquals"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.Assertions.assertEquals"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.FunSuite.assertNotEquals"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.FunSuite.assertEquals"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.FunSuite.munitTestTransform"
),
ProblemFilters.exclude[MissingClassProblem]("munit.GenericAfterEach"),
ProblemFilters.exclude[MissingClassProblem]("munit.GenericBeforeEach"),
ProblemFilters.exclude[MissingClassProblem]("munit.GenericTest"),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.MUnitRunner.createTestDescription"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.Suite.beforeEach"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.Suite.afterEach"
),
ProblemFilters.exclude[MissingClassProblem]("munit.Suite$Fixture"),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.TestTransforms#TestTransform.apply"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.FunFixtures#FunFixture.this"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.SuiteTransforms#SuiteTransform.this"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.TestTransforms#TestTransform.this"
),
ProblemFilters.exclude[IncompatibleMethTypeProblem](
"munit.ValueTransforms#ValueTransform.this"
),
ProblemFilters.exclude[DirectMissingMethodProblem](
"munit.ScalaCheckSuite.unitToProp"
)
),
mimaBinaryIssueFilters ++= MimaExclusions.list,
mimaPreviousArtifacts := {
if (crossPaths.value)
Set("org.scalameta" %% moduleName.value % previousVersion)
Expand Down Expand Up @@ -246,6 +171,8 @@ lazy val munit = crossProject(JSPlatform, JVMPlatform, NativePlatform)
)
)
.jvmConfigure(_.dependsOn(junit))
.dependsOn(munitDiff)

lazy val munitJVM = munit.jvm
lazy val munitJS = munit.js
lazy val munitNative = munit.native
Expand All @@ -270,6 +197,30 @@ lazy val plugin = project
)
.disablePlugins(MimaPlugin)

lazy val munitDiff = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.in(file("munit-diff"))
.settings(
moduleName := "munit-diff",
sharedSettings,
libraryDependencies ++= List(
"org.scala-lang" % "scala-reflect" % {
if (isScala3Setting.value) scala213
else scalaVersion.value
} % Provided
)
)
.jvmSettings(
sharedJVMSettings
)
.nativeConfigure(sharedNativeConfigure)
.nativeSettings(
sharedNativeSettings
)
.jsConfigure(sharedJSConfigure)
.jsSettings(sharedJSSettings)
// TODO Reenable on 1.0.0
.disablePlugins(MimaPlugin)

lazy val tests = crossProject(JSPlatform, JVMPlatform, NativePlatform)
.dependsOn(munit)
.enablePlugins(BuildInfoPlugin)
Expand Down
4 changes: 2 additions & 2 deletions docs/tests.md
Expand Up @@ -132,7 +132,7 @@ Override `printer` to customize the comparison of two values :
```scala mdoc
import java.time.Instant
import munit.FunSuite
import munit.Printer
import munit.diff.Printer

class CompareDatesOnlyTest extends FunSuite {
override val printer = Printer.apply {
Expand All @@ -152,7 +152,7 @@ or to customize the printed clue in case of a failure :

```scala mdoc
import munit.FunSuite
import munit.Printer
import munit.diff.Printer

class CustomListOfCharPrinterTest extends FunSuite {
override val printer = Printer.apply {
Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

import java.util

Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

sealed abstract class Delta[T](original: Chunk[T], revised: Chunk[T]) {

Expand Down
@@ -1,7 +1,7 @@
package munit.internal.difflib
package munit.diff

import munit.internal.console.{AnsiColors, Printers}
import munit.internal.difflib
import munit.diff.console.Printers
import munit.diff.console.AnsiColors

import scala.collection.JavaConverters._

Expand Down Expand Up @@ -74,11 +74,11 @@ class Diff(val obtained: String, val expected: String) extends Serializable {
original: Seq[String],
revised: Seq[String]
): String = {
val diff = difflib.DiffUtils.diff(original.asJava, revised.asJava)
val diff = DiffUtils.diff(original.asJava, revised.asJava)
val result =
if (diff.getDeltas.isEmpty) ""
else {
difflib.DiffUtils
DiffUtils
.generateUnifiedDiff(
"obtained",
"expected",
Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

import java.util

Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

import java.util

Expand Down
@@ -1,3 +1,3 @@
package munit.internal.difflib
package munit.diff

class DifferentiationFailedException(message: String) extends Exception(message)
28 changes: 28 additions & 0 deletions munit-diff/shared/src/main/scala/munit/diff/Diffs.scala
@@ -0,0 +1,28 @@
package munit.diff

object Diffs {

def create(obtained: String, expected: String): Diff =
new Diff(obtained, expected)

def createDiffOnlyReport(
obtained: String,
expected: String
): String = {
create(obtained, expected).createDiffOnlyReport()
}

def createReport(
obtained: String,
expected: String,
title: String,
printObtainedAsStripMargin: Boolean = true
): String = {
create(obtained, expected).createReport(title, printObtainedAsStripMargin)
}

def unifiedDiff(obtained: String, expected: String): String = {
create(obtained, expected).unifiedDiff
}

}
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

trait Equalizer[T] {
def equals(original: T, revised: T): Boolean
Expand Down
@@ -1,29 +1,29 @@
package munit.internal.difflib
package munit.diff

import java.util

class MyersDiff[T](equalizer: Equalizer[T])
extends munit.internal.difflib.DiffAlgorithm[T] {
extends munit.diff.DiffAlgorithm[T] {
def this() = this(Equalizer.default[T])
override def diff(
original: util.List[T],
revised: util.List[T]
): munit.internal.difflib.Patch[T] = {
): munit.diff.Patch[T] = {
try {
buildRevision(buildPath(original, revised), original, revised)
} catch {
case e: DifferentiationFailedException =>
e.printStackTrace()
new munit.internal.difflib.Patch[T]()
new munit.diff.Patch[T]()
}
}
private def buildRevision(
_path: PathNode,
orig: util.List[T],
rev: util.List[T]
): munit.internal.difflib.Patch[T] = {
): munit.diff.Patch[T] = {
var path = _path
val patch = new munit.internal.difflib.Patch[T]
val patch = new munit.diff.Patch[T]
if (path.isSnake) path = path.prev
while (
path != null &&
Expand All @@ -40,22 +40,22 @@ class MyersDiff[T](equalizer: Equalizer[T])
val ianchor = path.i
val janchor = path.j
val original =
new munit.internal.difflib.Chunk[T](
new munit.diff.Chunk[T](
ianchor,
copyOfRange(orig, ianchor, i)
)
val revised =
new munit.internal.difflib.Chunk[T](
new munit.diff.Chunk[T](
janchor,
copyOfRange(rev, janchor, j)
)
val delta: munit.internal.difflib.Delta[T] =
val delta: munit.diff.Delta[T] =
if (original.size == 0 && revised.size != 0) {
new munit.internal.difflib.InsertDelta[T](original, revised)
new munit.diff.InsertDelta[T](original, revised)
} else if (original.size > 0 && revised.size == 0) {
new munit.internal.difflib.DeleteDelta[T](original, revised)
new munit.diff.DeleteDelta[T](original, revised)
} else {
new munit.internal.difflib.ChangeDelta[T](original, revised)
new munit.diff.ChangeDelta[T](original, revised)
}
patch.addDelta(delta)
if (path.isSnake) {
Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

import java.util
import java.util.{Collections, Comparator}
Expand Down
@@ -1,4 +1,4 @@
package munit.internal.difflib
package munit.diff

sealed abstract class PathNode(val i: Int, val j: Int, val prev: PathNode) {

Expand Down
@@ -1,4 +1,4 @@
package munit
package munit.diff

/**
* Implement this trait to customize the default printer
Expand Down
@@ -1,4 +1,4 @@
package munit.internal.console
package munit.diff.console

object AnsiColors {
val LightRed = "\u001b[91m"
Expand Down
59 changes: 59 additions & 0 deletions munit-diff/shared/src/main/scala/munit/diff/console/Printers.scala
@@ -0,0 +1,59 @@
package munit.diff.console

import munit.diff.{EmptyPrinter, Printer}

import scala.annotation.switch

object Printers {

def print(input: String): String = {
val out = new StringBuilder()
printString(input, out, EmptyPrinter)
munit.diff.console.AnsiColors.filterAnsi(out.toString())
}

def printString(
string: String,
out: StringBuilder,
printer: Printer
): Unit = {
val isMultiline = printer.isMultiline(string)
if (isMultiline) {
out.append('"')
out.append('"')
out.append('"')
out.append(string)
out.append('"')
out.append('"')
out.append('"')
} else {
out.append('"')
var i = 0
while (i < string.length()) {
printChar(string.charAt(i), out)
i += 1
}
out.append('"')
}
}

def printChar(
c: Char,
sb: StringBuilder,
isEscapeUnicode: Boolean = true
): Unit =
(c: @switch) match {
case '"' => sb.append("\\\"")
case '\\' => sb.append("\\\\")
case '\b' => sb.append("\\b")
case '\f' => sb.append("\\f")
case '\n' => sb.append("\\n")
case '\r' => sb.append("\\r")
case '\t' => sb.append("\\t")
case c =>
val isNonReadableAscii = c < ' ' || (c > '~' && isEscapeUnicode)
if (isNonReadableAscii && !Character.isLetter(c))
sb.append("\\u%04x".format(c.toInt))
else sb.append(c)
}
}
Expand Up @@ -4,7 +4,7 @@

package munit.internal.junitinterface

import munit.internal.console.AnsiColors
import munit.diff.console.AnsiColors
import sbt.testing._
import munit.internal.PlatformCompat

Expand Down

0 comments on commit a66abd5

Please sign in to comment.