Pretty diffs for case classes.
The library is published for Scala 2.12 and 2.13.
- goals of the project
- integrations
- direct usage
- customization
- ignoring
- tagging support
- similar projects
- commercial support
- human-readable case class diffs
- support for popular testing frameworks
- OTB collections support
- OTB non-case class support
- smaller compilation overhead compared to shapless based solutions (thanks to magnolia <3)
- programmer friendly and type safe api for partial ignore
To use with scalatest, add the following dependency:
"com.softwaremill.diffx" %% "diffx-scalatest" % "0.3.11"
Then, extend the com.softwaremill.diffx.scalatest.DiffMatcher
trait or import com.softwaremill.diffx.scalatest.DiffMatcher._
.
After that you will be able to use syntax such as:
left should matchTo(right)
Giving you nice error messages:
To use with specs2, add the following dependency:
"com.softwaremill.diffx" %% "diffx-specs2" % "0.3.11"
Then, extend the com.softwaremill.diffx.specs2.DiffMatcher
trait or import com.softwaremill.diffx.specs2.DiffMatcher._
.
After that you will be able to use syntax such as:
left must matchTo(right)
Add the following dependency:
"com.softwaremill.diffx" %% "diffx-core" % "0.3.11"
Then call:
import com.softwaremill.diffx.Diff
Diff[T].apply(o1, o2)
If you'd like to implement custom matching logic for the given type, create an implicit Diff
instance for that
type, and make sure it's in scope when any any Diff
instances depending on that type are created.
Fields can be excluded from comparision by calling the ignore
method on the Diff
instance.
Since Diff
instances are immutable, the ignore
method creates a copy of the instance with modified logic.
You can use this instance explicitly.
If you still would like to use it implicitly, you first need to summon the instance of the Diff
typeclass using
the Derived
typeclass wrapper: Derived[Diff[Person]]
. Thanks to that trick, later you will be able to put your modified
instance of the Diff
typeclass into the implicit scope. The whole process looks as follows:
implicit modifiedDiff: Diff[Person] = Derived[Diff[Person]].ignore(_.name)
To use with softwaremill-tagging library, add the following dependency:
"com.softwaremill.diffx" %% "diffx-tagging" % "0.3.11"
And then extend com.softwaremill.diffx.tagging.DiffTaggingSupport
trait or import com.softwaremill.diffx.tagging.DiffTaggingSupport._
Diffx should be able to work with any other tagging library. I decided to create this module in order to check if any future changes won't break this integration.
If you want to use diffx with other tagging library you need to provide a way for creating Diff
type class for tagged types:
implicit def taggedDiff[T: Diff, U]: Derived[Diff[T @@ U]] = Derived(Diff[T].contramap[T @@ U](identity))
There is a number of similar projects from which diffx draws inspiration.
Below is a list of some of them, which I am aware of, with their main differences:
- xotai/diff - based on shapeless, seems not to be activly developed anymore
- ratatool-diffy - the main purpose is to compare large data sets stored on gs or hdfs
We offer commercial support for diffx and related technologies, as well as development services. Contact us to learn more about our offer!
Copyright (C) 2019 SoftwareMill https://softwaremill.com.