0
votes

I'm trying out ScalaCheck and haven't been able to figure out how to build the first example on the ScalaTest user's manual. I'm pretty sure that the following needs to be preceded by some imports and wrapped inside a class that extends from some library class. The page in the user's manual says to "mix in" PropertyChecks, but it doesn't give an example of an appropriate class to mix it into:

forAll { (n: Int, d: Int) =>

  whenever (d != 0 && d != Integer.MIN_VALUE
      && n != Integer.MIN_VALUE) {

    val f = new Fraction(n, d)

    if (n < 0 && d < 0 || n > 0 && d > 0)
      f.numer should be > 0
    else if (n != 0)
      f.numer should be < 0
    else
      f.numer should be === 0

    f.denom should be > 0
  }
}

I've been trying various combinations, but the best result I've gotten so far is compilation errors like this:

[info] Compiling 1 Scala source to .../target/scala-2.11/test-classes...
[error] .../src/test/scala/TestFraction.scala:14: value should is not a member of Int
[error]         f.numer should be > 0
[error]                 ^

What would be a complete source file for the test, imports and all?

2

2 Answers

1
votes

If you check the github repository of scala test here you can find some extra code here

github source scalatest

For your source this are the imports and the structure

import org.scalatest.{Matchers, FlatSpec}
import org.scalatest.prop.PropertyChecks

class Fraction(n: Int, d: Int) {

  require(d != 0)
  require(d != Integer.MIN_VALUE)
  require(n != Integer.MIN_VALUE)

  val numer = if (d < 0) -1 * n else n
  val denom = d.abs

  override def toString = numer + " / " + denom
}

class PropertySpec extends FlatSpec with PropertyChecks with Matchers {
  forAll { (n: Int, d: Int) =>

    whenever(d != 0 && d != Integer.MIN_VALUE
      && n != Integer.MIN_VALUE) {

      val f = new Fraction(n, d)

      if (n < 0 && d < 0 || n > 0 && d > 0)
        f.numer should be > 0
      else if (n != 0)
        f.numer should be < 0
      else
        f.numer should be === 0

      f.denom should be > 0
    }
  }

  val invalidCombos =
    Table(
      ("n", "d"),
      (Integer.MIN_VALUE, Integer.MIN_VALUE),
      (1, Integer.MIN_VALUE),
      (Integer.MIN_VALUE, 1),
      (Integer.MIN_VALUE, 0),
      (1, 0)
    )

  forAll(invalidCombos) { (n: Int, d: Int) =>
    evaluating {
      new Fraction(n, d)
    } should produce[IllegalArgumentException]
  }
}
1
votes

Recent versions of scalatest do not implementevaluating and mark === as obsolete. So, I'd rewrite example as:

import org.scalatest._
import org.scalatest.prop.PropertyChecks

protected class Fraction(n: Int, d: Int) {
  require(d != 0 && d != Integer.MIN_VALUE && n != Integer.MIN_VALUE)
  val numer = if (d < 0) -1 * n else n
  val denom = d.abs
  override def toString = numer + " / " + denom
}

class SscceProps extends FlatSpec with PropertyChecks with Matchers {
  it should "valid combos" in { forAll { (n: Int, d: Int) =>
      whenever(d != 0 && d != Integer.MIN_VALUE && n != Integer.MIN_VALUE) {
        val f = new Fraction(n, d)
        if (n < 0 && d < 0 || n > 0 && d > 0) f.numer should be > 0
        else if (n != 0) f.numer should be < 0
        else f.numer shouldBe 0
        f.denom should be > 0
      }
  }}
  it should "invalid combos" in {
    forAll(Table(
      ("n", "d"),
      (Integer.MIN_VALUE, Integer.MIN_VALUE),
      (1, Integer.MIN_VALUE),
      (Integer.MIN_VALUE, 1),
      (Integer.MIN_VALUE, 0),
      (1, 0)
    )) { (n: Int, d: Int) =>
      an[IllegalArgumentException] should be thrownBy {new Fraction(n, d)}}
  }
}