Skip to content

Instantly share code, notes, and snippets.

@bvenners
Created November 27, 2013 17:40
Show Gist options
  • Save bvenners/7679915 to your computer and use it in GitHub Desktop.
Save bvenners/7679915 to your computer and use it in GitHub Desktop.
Typesafe equality and contains checking in ScalaTest
scala> import org.scalautils._
import org.scalautils._
scala> import org.scalatest._
import org.scalatest._
scala> import Matchers._
import Matchers._
scala> import TypeCheckedTripleEquals._
import TypeCheckedTripleEquals._
scala> val xs = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)
scala> val ys = List("1", "2", "3")
ys: List[String] = List(1, 2, 3)
// You can get equality checks with type checking via ===:
scala> xs should === (ys)
<console>:25: error: types List[Int] and List[String] do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalautils.Constraint[List[Int],List[String]]
xs should === (ys)
^
// Just using contain does not give you a type error, because contain can be used with and,
// or, and not in matcher compositions. I decided that carrying a type constrait along
// for the ride in logical expressions would make the user code harder to understand than
// the benefit of type errors versus test failures:
scala> xs should contain ("1")
org.scalatest.exceptions.TestFailedException: List(1, 2, 3) did not contain element "1"
at org.scalatest.MatchersHelper$.newTestFailedException(MatchersHelper.scala:160)
at org.scalatest.Matchers$ShouldMethodHelper$.shouldMatcher(Matchers.scala:5980)
...
// If you want a type error for contains checking, you should use inspectors
// or inspector shorthands instead. Here's an example:
scala> atLeast (1, xs) should === ("1")
<console>:24: error: types Int and String do not adhere to the type constraint selected for the === and !== operators; the missing implicit parameter is of type org.scalautils.Constraint[Int,String]
atLeast (1, xs) should === ("1")
^
// In the contain case, it works for more than just equality checks. Here you
// get a type error checking to see if a list of strings contains an Int greater
// than 7
scala> atLeast (1, ys) should be > 7
<console>:24: error: overloaded method value should with alternatives:
(fullyMatchWord: org.scalatest.words.FullyMatchWord)org.scalatest.Matchers.ResultOfFullyMatchWordForCollectedString <and>
(includeWord: org.scalatest.words.IncludeWord)org.scalatest.Matchers.ResultOfIncludeWordForCollectedString <and>
(endWithWord: org.scalatest.words.EndWithWord)org.scalatest.Matchers.ResultOfEndWithWordForCollectedString <and>
(startWithWord: org.scalatest.words.StartWithWord)org.scalatest.Matchers.ResultOfStartWithWordForCollectedString <and>
(notWord: org.scalatest.words.NotWord)org.scalatest.Matchers.ResultOfNotWordForCollectedString <and>
(notExist: org.scalatest.words.ResultOfNotExist)(implicit existence: org.scalatest.enablers.Existence[String])Unit <and>
(existWord: org.scalatest.words.ExistWord)(implicit existence: org.scalatest.enablers.Existence[String])Unit <and>
(containWord: org.scalatest.words.ContainWord)org.scalatest.Matchers.ResultOfContainWordForCollectedAny[String] <and>
(inv: org.scalautils.TripleEqualsSupport.TripleEqualsInvocationOnSpread[String])(implicit ev: Numeric[String])Unit <and>
[U](inv: org.scalautils.TripleEqualsSupport.TripleEqualsInvocation[U])(implicit constraint: org.scalautils.Constraint[String,U])Unit <and>
(haveWord: org.scalatest.words.HaveWord)org.scalatest.Matchers.ResultOfHaveWordForCollectedExtent[String] <and>
(beWord: org.scalatest.words.BeWord)org.scalatest.Matchers.ResultOfBeWordForCollectedAny[String] <and>
[TYPECLASS1[_], TYPECLASS2[_]](rightMatcherFactory2: org.scalatest.matchers.MatcherFactory2[String,TYPECLASS1,TYPECLASS2])(implicit typeClass1: TYPECLASS1[String], implicit typeClass2: TYPECLASS2[String])Unit <and>
[TYPECLASS1[_]](rightMatcherFactory1: org.scalatest.matchers.MatcherFactory1[String,TYPECLASS1])(implicit typeClass1: TYPECLASS1[String])Unit <and>
(rightMatcher: org.scalatest.matchers.Matcher[String])Unit
cannot be applied to (org.scalatest.matchers.Matcher[Int])
atLeast (1, ys) should be > 7
^
// Inspectors are described here:
http://doc.scalatest.org/2.0/index.html#org.scalatest.Inspectors
// Inspector shorhands are described here:
http://doc.scalatest.org/2.0/index.html#org.scalatest.Matchers@inspectorShorthands
// TypeCheckedTripleEquals is desribed here:
http://doc.scalatest.org/2.0/index.html#org.scalatest.Matchers@inspectorShorthands
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment