Search code examples
scalaspecs2

Some List specs2 matcher


Why doesn't the following work?

Some(List()) must beSome(Nil)

'Some(List())' is Some but List() is not equal to 'org.specs2.matcher.ValueChecks$$anon$3@480ba116'


Solution

  • Note that

    Some(List()) must beSome(List())
    

    also don't work.

     'Some(List())' is Some but List() is not equal to 
     'org.specs2.matcher.ValueChecks$$anon$4@48d1978f' 
     Actual:   List()
     Expected: org.specs2.matcher.ValueChecks$$anon$4@48d1978f
    

    So the problem is not Nil

    We know that what we are really doing is something like:

     Some(List()).must(beSome(List()))
    

    The problem seems with beSome. Let's see what beSome is returning:

    val bl = beSome(List())  // SomeCheckedMatcher[Int]
    val bn = beSome(Nil)     // SomeCheckedMatcher[Int]
    

    This doesn't seen right since the return type is like were are checking an Option for a Integer:

    val b = beSome(2)        // SomeCheckedMatcher[Int]
    

    And those are not our target types:

    val myList = List()  // myList: List[Nothing] = List()
    val myList2 = Nil    // myList2: scala.collection.immutable.Nil.type = List()
    

    So, what's wrong?

    Looking at the documentation (Option/Either), you can use beSome the folowing ways:

    • beSome check if an element is Some(_)

    • beSome(exp) check if an element is Some(exp)

    • beSome(matcher) check if an element is Some(a) where a satisfies the matcher

    • beSome(function: A => AsResult[B]) check if an element is Some(a) where function(a) returns a successful Result (note that a Seq[A] is also a function Int => A so if you want to check that a sequence is contained in Some you need to use a matcher: beSome(===(Seq(1)))

    The last alternative seems to be our problem here. Note the List() is like Seq, a function from Int => A. In, our example:

    val myList = List()                 // myList: List[Nothing] = List()
    val func: Int => Nothing = myList   // func: Int => Nothing = List()
    

    To fix this we should use a matcher (the third alternative of the documentation):

    Some(List()) must beSome(beEqualTo(List()))
    Some(List()) must beSome(beEqualTo(Nil))
    
    // or 
    
    Some(List()) must beSome(be_==(List()))  
    Some(List()) must beSome(be_==(Nil))