alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (Test.scala)

This example Scala source code file (Test.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

int, int, intopt, params, result, result, set, set, status, string, string, testcallback, unit, use

The Scala Test.scala source code

/*-------------------------------------------------------------------------*\
**  ScalaCheck                                                             **
**  Copyright (c) 2007-2010 Rickard Nilsson. All rights reserved.          **
**  http://www.scalacheck.org                                              **
**                                                                         **
**  This software is released under the terms of the Revised BSD License.  **
**  There is NO WARRANTY. See the file LICENSE for the full text.          **
\*-------------------------------------------------------------------------*/

package org.scalacheck

object Test {

  import util.FreqMap
  import scala.collection.immutable
  import Prop.FM
  import util.CmdLineParser

  /** Test parameters */
  case class Params(
    minSuccessfulTests: Int = 100,
    maxDiscardedTests: Int = 500,
    minSize: Int = 0,
    maxSize: Int = Gen.Params().size,
    rng: java.util.Random = Gen.Params().rng,
    workers: Int = 1,
    testCallback: TestCallback = new TestCallback {}
  )

  /** Test statistics */
  case class Result(status: Status, succeeded: Int, discarded: Int, freqMap: FM) {
    def passed = status match {
      case Passed => true
      case Proved(_) => true
      case _ => false
    }
  }

  /** Test status */
  sealed trait Status

  /** ScalaCheck found enough cases for which the property holds, so the
   *  property is considered correct. (It is not proved correct, though). */
  case object Passed extends Status

  /** ScalaCheck managed to prove the property correct */
  sealed case class Proved(args: Prop.Args) extends Status

  /** The property was proved wrong with the given concrete arguments.  */
  sealed case class Failed(args: Prop.Args, labels: Set[String]) extends Status

  /** The property test was exhausted, it wasn't possible to generate enough
   *  concrete arguments satisfying the preconditions to get enough passing
   *  property evaluations. */
  case object Exhausted extends Status

  /** An exception was raised when trying to evaluate the property with the
   *  given concrete arguments. */
  sealed case class PropException(args: Prop.Args, e: Throwable,
    labels: Set[String]) extends Status

  /** An exception was raised when trying to generate concrete arguments
   *  for evaluating the property. */
  sealed case class GenException(e: Throwable) extends Status

  trait TestCallback { self =>
    /** Called each time a property is evaluated */
    def onPropEval(name: String, threadIdx: Int, succeeded: Int, 
      discarded: Int): Unit = ()

    /** Called whenever a property has finished testing */
    def onTestResult(name: String, result: Result): Unit = ()

    def chain(testCallback: TestCallback) = new TestCallback {
      override def onPropEval(name: String, threadIdx: Int,
        succeeded: Int, discarded: Int
      ): Unit = {
        self.onPropEval(name,threadIdx,succeeded,discarded)
        testCallback.onPropEval(name,threadIdx,succeeded,discarded)
      }

      override def onTestResult(name: String, result: Result): Unit = {
        self.onTestResult(name,result)
        testCallback.onTestResult(name,result)
      }
    }
  }

  private def assertParams(prms: Params) = {
    import prms._
    if(
      minSuccessfulTests <= 0 ||
      maxDiscardedTests < 0 ||
      minSize < 0 ||
      maxSize < minSize ||
      workers <= 0
    ) throw new IllegalArgumentException("Invalid test parameters")
  }

  private def secure[T](x: => T): Either[T,Throwable] =
    try { Left(x) } catch { case e => Right(e) }

  private[scalacheck] lazy val cmdLineParser = new CmdLineParser {
    object OptMinSuccess extends IntOpt {
      val default = Test.Params().minSuccessfulTests
      val names = Set("minSuccessfulTests", "s")
      val help = "Number of tests that must succeed in order to pass a property"
    }
    object OptMaxDiscarded extends IntOpt {
      val default = Test.Params().maxDiscardedTests
      val names = Set("maxDiscardedTests", "d")
      val help =
        "Number of tests that can be discarded before ScalaCheck stops " +
        "testing a property"
    }
    object OptMinSize extends IntOpt {
      val default = Test.Params().minSize
      val names = Set("minSize", "n")
      val help = "Minimum data generation size"
    }
    object OptMaxSize extends IntOpt {
      val default = Test.Params().maxSize
      val names = Set("maxSize", "x")
      val help = "Maximum data generation size"
    }
    object OptWorkers extends IntOpt {
      val default = Test.Params().workers
      val names = Set("workers", "w")
      val help = "Number of threads to execute in parallel for testing"
    }
    object OptVerbosity extends IntOpt {
      val default = 1
      val names = Set("verbosity", "v")
      val help = "Verbosity level"
    }

    val opts = Set[Opt[_]](
      OptMinSuccess, OptMaxDiscarded, OptMinSize,
      OptMaxSize, OptWorkers, OptVerbosity
    )

    def parseParams(args: Array[String]) = parseArgs(args) {
      optMap => Test.Params(
        optMap(OptMinSuccess),
        optMap(OptMaxDiscarded),
        optMap(OptMinSize),
        optMap(OptMaxSize),
        Test.Params().rng,
        optMap(OptWorkers),
        ConsoleReporter(optMap(OptVerbosity))
      )
    }
  }

  /** Tests a property with the given testing parameters, and returns
   *  the test results. */
  def check(prms: Params, p: Prop): Result = {
    import prms._
    import actors.Futures.future
    //import scala.concurrent.ops.future

    assertParams(prms)
    if(workers > 1)
      assert(!p.isInstanceOf[Commands], "Commands cannot be checked multi-threaded")

    val iterations = minSuccessfulTests / workers
    val sizeStep = (maxSize-minSize) / (minSuccessfulTests: Float)
    var stop = false

    def worker(workerdIdx: Int) = future {
      var n = 0
      var d = 0
      var size = workerdIdx*sizeStep
      var res: Result = null
      var fm = FreqMap.empty[immutable.Set[Any]]
      while(!stop && res == null && n < iterations) {
        val propPrms = Prop.Params(Gen.Params(size.round, prms.rng), fm)
        secure(p(propPrms)) match {
          case Right(e) => res =
            Result(GenException(e), n, d, FreqMap.empty[immutable.Set[Any]])
          case Left(propRes) =>
            fm =
              if(propRes.collected.isEmpty) fm
              else fm + propRes.collected
            propRes.status match {
              case Prop.Undecided =>
                d += 1
                testCallback.onPropEval("", workerdIdx, n, d)
                if(d >= maxDiscardedTests) res = Result(Exhausted, n, d, fm)
              case Prop.True =>
                n += 1
                testCallback.onPropEval("", workerdIdx, n, d)
              case Prop.Proof =>
                n += 1
                res = Result(Proved(propRes.args), n, d, fm)
              case Prop.False => res =
                Result(Failed(propRes.args, propRes.labels), n, d, fm)
              case Prop.Exception(e) => res =
                Result(PropException(propRes.args, e, propRes.labels), n, d, fm)
            }
        }
        size += sizeStep
      }
      if(res != null) stop = true
      else res = Result(Passed, n, d, fm)
      res
    }

    def mergeResults(r1: () => Result, r2: () => Result) = r1() match {
      case Result(Passed, s1, d1, fm1) => r2() match {
        case Result(Passed, s2, d2, fm2) if d1+d2 >= maxDiscardedTests =>
          () => Result(Exhausted, s1+s2, d1+d2, fm1++fm2)
        case Result(st, s2, d2, fm2) =>
          () => Result(st, s1+s2, d1+d2, fm1++fm2)
      }
      case r => () => r
    }

    val results = for(i <- 0 until workers) yield worker(i)
    val r = results.reduceLeft(mergeResults)()
    stop = true
    results foreach (_.apply())
    prms.testCallback.onTestResult("", r)
    r
  }

  def checkProperties(prms: Params, ps: Properties): Seq[(String,Result)] =
    ps.properties.map { case (name,p) =>
      val testCallback = new TestCallback {
        override def onPropEval(n: String, t: Int, s: Int, d: Int) = 
          prms.testCallback.onPropEval(name,t,s,d)
        override def onTestResult(n: String, r: Result) = 
          prms.testCallback.onTestResult(name,r)
      }
      val res = check(prms copy (testCallback = testCallback), p)
      (name,res)
    }


  // Deprecated methods //

  /** Default testing parameters
   *  @deprecated Use <code>Test.Params() instead */
  @deprecated("Use Test.Params() instead")
  val defaultParams = Params()

  /** Property evaluation callback. Takes number of passed and
   *  discarded tests, respectively */
  @deprecated("(v1.8)")
  type PropEvalCallback = (Int,Int) => Unit

  /** Property evaluation callback. Takes property name, and number of passed
   *  and discarded tests, respectively */
  @deprecated("(v1.8)")
  type NamedPropEvalCallback = (String,Int,Int) => Unit

  /** Test callback. Takes property name, and test results. */
  @deprecated("(v1.8)")
  type TestResCallback = (String,Result) => Unit

  /** @deprecated (v1.8) Use <code>check(prms.copy(testCallback = myCallback), p) instead. */
  @deprecated("(v1.8) Use check(prms.copy(testCallback = myCallback), p) instead")
  def check(prms: Params, p: Prop, propCallb: PropEvalCallback): Result = {
    val testCallback = new TestCallback {
      override def onPropEval(n: String, t: Int, s: Int, d: Int) = propCallb(s,d) 
    }
    check(prms copy (testCallback = testCallback), p)
  }

  /** Tests a property and prints results to the console. The
   *  <code>maxDiscarded parameter specifies how many
   *  discarded tests that should be allowed before ScalaCheck
   *  @deprecated (v1.8) Use <code>check(Params(maxDiscardedTests = n, testCallback = ConsoleReporter()), p) instead. */
  @deprecated("(v1.8) Use check(Params(maxDiscardedTests = n, testCallback = ConsoleReporter()), p) instead.")
  def check(p: Prop, maxDiscarded: Int): Result =
    check(Params(maxDiscardedTests = maxDiscarded, testCallback = ConsoleReporter()), p)

  /** Tests a property and prints results to the console
   *  @deprecated (v1.8) Use <code>check(Params(testCallback = ConsoleReporter()), p) instead. */
  @deprecated("(v1.8) Use check(Params(testCallback = ConsoleReporter()), p) instead.")
  def check(p: Prop): Result = check(Params(testCallback = ConsoleReporter()), p)

  /** Tests all properties with the given testing parameters, and returns
   *  the test results. <code>f is a function which is called each
   *  time a property is evaluted. <code>g is a function called each
   *  time a property has been fully tested.
   *  @deprecated (v1.8) Use <code>checkProperties(prms.copy(testCallback = myCallback), ps) instead. */
  @deprecated("(v1.8) Use checkProperties(prms.copy(testCallback = myCallback), ps) instead.")
  def checkProperties(ps: Properties, prms: Params,
    propCallb: NamedPropEvalCallback, testCallb: TestResCallback
  ): Seq[(String,Result)] = {
    val testCallback = new TestCallback {
      override def onPropEval(n: String, t: Int, s: Int, d: Int) = propCallb(n,s,d) 
      override def onTestResult(n: String, r: Result) = testCallb(n,r)
    }
    checkProperties(prms copy (testCallback = testCallback), ps)
  }

  /** Tests all properties with the given testing parameters, and returns
   *  the test results.
   *  @deprecated (v1.8) Use checkProperties(prms, ps) instead */
  @deprecated("(v1.8) Use checkProperties(prms, ps) instead")
  def checkProperties(ps: Properties, prms: Params): Seq[(String,Result)] =
    checkProperties(ps, prms, (n,s,d) => (), (n,s) => ())

  /** Tests all properties with default testing parameters, and returns
   *  the test results. The results are also printed on the console during
   *  testing.
   *  @deprecated (v1.8) Use <code>checkProperties(Params(), ps) instead. */
  @deprecated("(v1.8) Use checkProperties(Params(), ps) instead.")
  def checkProperties(ps: Properties): Seq[(String,Result)] =
    checkProperties(Params(), ps)
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala Test.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.