I was reading Scala with Cats and in the first chapter of the book, they describe Eq usage.
One of the exercises is about writing an instance of that typeclass for validating the equality of two cats. Consider this:
Model
final case class Cat(name: String, age: Int, color: String)
Typeclass instance
import cats.Eq
import cats.syntax.eq._
import cats.instances.string._
import cats.instances.int._
import co.alejandrome.typeclass.model.Cat
object CatsEqInstances {
implicit val catsEq: Eq[Cat] = Eq.instance[Cat] {
(cata, catb) =>
cata.color === catb.color && cata.age === catb.age && cata.name === catb.name
}
}
Unit tests
import co.alejandrome.typeclass.model.Cat
import org.scalatest.{FlatSpec, Matchers}
import cats.instances.option._
class EqTest extends FlatSpec with Matchers{
import CatsEqInstances._
"Eq" should "compare two cats" in {
val cat1 = Cat("Garfield", 38, "orange and black")
val cat2 = Cat("Heathcliff", 33, "orange and black")
catsEq.eqv(cat1, cat2) shouldBe false
val cat3 = Cat("Garfield", 38, "orange and black")
catsEq.eqv(cat1, cat3) shouldBe true
}
it should "compare two Optional cats" in {
val cat1 = Cat("Garfield", 38, "orange and black")
//val cat2 = Cat("Heathcliff", 33, "orange and black")
val optionCat1 = Option(cat1)
val optionCat2 = Option.empty[Cat]
optionCat1 === optionCat2
}
}
The first test works fine, but the second one doesn't because === operator is the Scalatest one, not the Eq one.
I explored if the typeclass has any syntax or implicit for this but I cannot find anything about it. I saw in this PR that there's a solution for this, based on Bill Venner's solution, but this is only for cats own unit tests.
I was poking with EqSyntax trait but I can't figure it out how to override scalatest own implementation of ===.
Is there any way to do this? Or is this not implemented yet?
Thanks