For loops

It is very tempting to use foreach to create examples or results from a sequence of values:

(1 to 3).foreach(i => "example " + i ! { i must ===(i) })

The problem with foreach is that the return value of the expression above is Unit. So you won’t be able to use it in an acceptance specification or a mutable one.

A list of examples

When we want to create a list of examples we need to return a Fragments object. The long-winded way to do so is to use a foldLeft:

(1 to 3).foldLeft(Fragments.empty)((res, i) => res.append("example " + i ! { i must ===(i) }))

Or, a bit fancier with foldMap:

// Fragments has a Monoid instance so you can use the foldMap method
    (1 to 3).toList.foldMap(i => Fragments("example " + i ! { i must ===(i) }))

Because this is a recurring pattern there are two methods encapsulating it:

// when the function only returns a Fragment
    Fragment.foreach(1 to 3)(i => "example " + i ! { i must ===(i) }): Fragments

// when the function returns a Fragments object
    Fragments.foreach(1 to 3) { i =>
      "examples for " + i ^ br ^
        "1 + " + i ! { (1 + i) must ===((i + 1)) } ^ br ^
        "2 + " + i ! { (2 + i) must ===((i + 2)) }
    }: Fragments

Now you can create a list of examples inside a “should” block in a mutable specification:

class MySpec extends mutable.Specification:
      "this block should have lots of examples" >> {
        Fragment.foreach(1 to 1000) { i =>
          "example " + i ! { i must ===(i) }
        }
      }

A list of expectations

Similarly, when you want to create a list of expectations inside an example, you should use a variant of foreach and forall methods:

class MySpec extends mutable.Specification:
      "this collects results of all expectations and throws an exception" >> {
        foreach(1 to 10) { i =>
          i === 2
        } // Collects results of all expectations. Throws an exception.
        foreach(1 to 10) { i =>
          i === i
        } // This is not executed.
      }
      "this stops after the first failed expectation and throws an exception" >> {
        forall(1 to 10) { i =>
          i === 2
        } // Stops after the first failed expectation. Throws an exception.
      }
class MySpec extends mutable.Specification:
      "this collects results of all expectations and returns a Result" >> {
        Result.forall(1 to 10) { i =>
          i === 2
        }
      }
      "this stops after the first failed expectation and returns a Result" >> {
        Result.foreach(1 to 10) { i =>
          i === 2
        }
      }

And if you want to know more