Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment with shouldEqv ScalaTest matcher #294

Closed
non opened this issue Aug 5, 2014 · 7 comments
Closed

Experiment with shouldEqv ScalaTest matcher #294

non opened this issue Aug 5, 2014 · 7 comments

Comments

@non
Copy link
Contributor

non commented Aug 5, 2014

As @denisrosset suggested, it would be nice to have a custom matcher which uses our Eq[A] type class and which integrates with ScalaTest.

@denisrosset
Copy link
Collaborator

Something like this ?

I'm not (yet) doing a PR because I do not know the good strategy w.r.t. having dependencies on a particular version of scalatest from the Spire dependency.

package org.scalatest

import MatchersHelper.newTestFailedException
import spire.algebra.Eq

trait EqMatchers {
  final implicit class ShouldEqvWrapper[T](val lhs: T) {
    def shouldEqv(rhs: T)(implicit ev: Eq[T]) {
      if (!ev.eqv(lhs, rhs)) {
        val (leftee, rightee) = Suite.getObjectsForFailureMessage(lhs, rhs)
        throw newTestFailedException(FailureMessages("wasNotEqvTo", leftee, rightee))
      }
    }
  }
}

@denisrosset
Copy link
Collaborator

Note that EqMatchers has to live in the org.scalatest package because Suite and MatchersHelper are private.

@bvenners
Copy link

bvenners commented Aug 6, 2014

Just noticed this. There's a better way to do this. I'm teaching a class today but will try and work up an example. In short, scalatest's (scalactic's really) equality is designed so you can plug in other equality tyoeclasses such as the ones in spite or scalaz and use that for === instead of the built-in one.

@bvenners
Copy link

bvenners commented Aug 7, 2014

I whipped up a demo and put it here: https://github.com/bvenners/equality-integration-demo

@denisrosset
Copy link
Collaborator

It's cool that scalactic has thought of this. Still, I don't like the idea of having to silence spire === to use scalatest own operators instead.

Would it be possible to offer a base trait for should-like operators, with people extending them by implementing isEqual(x,y) ? scalatest would provide a ShouldEqBase trait with a default message and an abstract isEq method.

trait SpireEqv extends FunSuite with NonImplicitAssertions with Matchers {
  final implicit class ShouldEqvWrapper[T](val lhs: T)(implicit ev: SomeEqual[T]) extends ShouldEqBase[T] {
     override def message = "was not equivalent (in some way) to"
     def isEqual(x: T, y: T) = ev.someEqual(x, y)
  }
}

@bvenners
Copy link

bvenners commented Aug 8, 2014

I'm not sure I understand what you're suggesting. You can easily make a custom matcher that takes an Eq, which I think was your original idea. Say you call it spireEqual. You could then write:

result should spireEqual (22)

You could also use Spire's === operator already in assertions, like this:

assert(a === b)

But right now you won't get the nice good error message. What I think we could do is look at enabling a nice equality error message using any === operator, not just ScalaTest's. But this wouldn't help you using ScalaTest's Matchers for equal. I think enhancing our assert macro to handle any === operator is worth doing, if it is possible and doesn't add to compile time, but otherwise I suspect the extension points that will make sense is what I posted in the equality integration demo and custom matchers. However, I would like to make sure I understand what you're suggesting. Can you clarify?

@denisrosset
Copy link
Collaborator

Regrouped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants