Better diffs in ZIO test

(, en)

The diff output of ZIO test is awful, I find.

Assertion failed:
  ✗ Pokemon.name : expected 'Pikchu' got 'Pikachu'
Pokemon.level : expected '2' got '1'

  a did not satisfy equalTo(b)
  a = Pokemon(
    name = "Pikachu",
    level = 1
  )

Luckily there is difflicious.

Assertion failed:
  ✗ Pokemon(
      name: "Pikachu" -> "Pikchu",
      level: 1 -> 2
    )
  a did not satisfy Differ[Pokemon].noDiff(b)
  a = Pokemon(
    name = "Pikachu",
    level = 1
  )

Much better! If you want it, too, write an extension like this:

import difflicious.{DiffResultPrinter, Differ}
import zio.test.*

trait TestKit {
  extension [A](differ: Differ[A]) {
    def noDiff(expected: A): Assertion[A] =
      Assertion[A](
        TestArrow
          .make[A, Boolean] { actual =>
            val result = differ.diff(actual, expected)
            TestTrace.boolean(
              result.isOk
            ) {
              ErrorMessage.custom(DiffResultPrinter.consoleOutput(result, 0).render)
            }
          }
          .withCode("noDiff")
      )
  }
}

object TestKit extends TestKit

Use it like this:

import difflicious.implicits.*
import difflicious.Differ
import zio.*
import zio.test.*
import zio.test.Assertion.*
import org.bargsten.zio.test.TestKit.*

object TestKitTest extends ZIOSpecDefault {
  override def spec: Spec[TestEnvironment & Scope, Any] = suite("diff")(
    test("simple diff") {
      case class Pokemon(name: String, level: Int)
      given Differ[Pokemon] = Differ.derived
      val a = Pokemon("Pikachu", 1)
      val b = Pokemon("Pikchu", 2)
      assert(a)(Differ[Pokemon].noDiff(b))
    }
  )
}