or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdexecution.mdindex.mdproperty-creation.mdtype-integration.md
tile.json

type-integration.mddocs/

Type Integration

Seamless conversion between specs2 and ScalaCheck types with automatic result interpretation, property wrapping, and support for all specs2 result types. The type integration system enables property-based tests to work naturally within specs2's specification DSL.

Capabilities

Result to Property Conversion

Convert any specs2 AsResult type to ScalaCheck Prop for use in property-based testing.

trait AsResultProp {
  implicit def asResultToProp[R : AsResult](r: R): Prop
}

Usage:

import org.specs2._
import org.specs2.matcher.Matchers
import org.scalacheck._

class ResultConversionSpec extends Specification with ScalaCheck with Matchers { def is = s2"""
  MatchResult to Prop ${
    val prop = Prop.forAll((s: String) => s must not be empty)
    check(prop, defaultParameters, defaultFreqMapPretty)
  }
  
  Boolean to Prop ${
    val prop = Prop.forAll((n: Int) => n + 0 == n)  // Boolean result converted to Prop
    check(prop, defaultParameters, defaultFreqMapPretty)
  }
  
  Custom Result to Prop ${
    def validateData(data: String): Result = 
      if (data.nonEmpty) Success("Valid data") 
      else Failure("Empty data not allowed")
      
    val prop = Prop.forAll(Gen.alphaStr.suchThat(_.nonEmpty))((s: String) => validateData(s))
    check(prop, defaultParameters, defaultFreqMapPretty)
  }
"""
}

Property to Result Conversion

Convert ScalaCheck Prop and Properties to specs2 Result types for integration with specifications.

trait AsResultProp {
  implicit def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
  implicit def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
}

Usage:

class PropToResultSpec extends Specification with ScalaCheck { def is = s2"""
  ScalaCheck Prop as example ${
    Prop.forAll((n: Int) => n * n >= 0)  // Automatically converted to Result
  }
  
  Properties collection as example ${
    val props = new Properties("math") {
      property("addition") = Prop.forAll((a: Int, b: Int) => a + b == b + a)
      property("multiplication") = Prop.forAll((x: Int) => x * 0 == 0)
    }
    props  // Automatically converted to Result
  }
"""
}

ScalaCheck Property Integration

Convert custom ScalaCheck property types to specs2 results with parameter and configuration preservation.

trait AsResultPropLowImplicits {
  implicit def scalaCheckPropertyAsResult[S <: ScalaCheckProperty]: AsResult[S]
}

Usage:

class PropertyIntegrationSpec extends Specification with ScalaCheck { def is = s2"""
  Custom ScalaCheckFunction ${
    prop((data: List[Int]) => data.reverse.reverse == data)
      .setGen(Gen.listOfN(10, Gen.choose(1, 100)))
      .collect  // ScalaCheckFunction1 automatically converted to Result
  }
  
  Configured property ${
    prop((s: String, n: Int) => s.length + n >= n)
      .setGen1(Gen.alphaStr)
      .setGen2(Gen.posNum[Int])
      .verbose  // ScalaCheckFunction2 automatically converted to Result
  }
"""
}

DSL Integration

Enable properties to be used directly in specs2 specifications with automatic conversion and fragment creation.

trait ScalaCheckPropertyDsl extends FragmentsFactory with AsResultProp {
  implicit def propToScalaCheckProperty(prop: Prop)(implicit 
    parameters: Parameters, 
    prettyFreqMap: FreqMap[Set[Any]] => Pretty
  ): ScalaCheckProp
  
  def properties(ps: Properties): Fragments
}

Usage:

class DSLIntegrationSpec extends Specification with ScalaCheck { def is = s2"""
  Property in specification ${prop((x: Int) => x + 0 == x)}
  
  Multiple properties ${
    val mathProps = new Properties("mathematics") {
      property("commutativity") = Prop.forAll((a: Int, b: Int) => a + b == b + a)
      property("associativity") = Prop.forAll((a: Int, b: Int, c: Int) => (a + b) + c == a + (b + c))
      property("identity") = Prop.forAll((n: Int) => n + 0 == n)
    }
    properties(mathProps)  // Creates multiple examples from Properties
  }
"""
}

Property Wrapper Types

Wrap ScalaCheck properties with specs2-specific configuration and behavior.

case class ScalaCheckProp(
  prop: Prop,
  parameters: Parameters,
  prettyFreqMap: FreqMap[Set[Any]] => Pretty
) extends ScalaCheckProperty {
  type SelfType = ScalaCheckProp
  def setParameters(ps: Parameters): ScalaCheckProp
  def setSeed(seed: Seed): ScalaCheckProp
  def setSeed(seed: String): ScalaCheckProp
  def setPrettyFreqMap(f: FreqMap[Set[Any]] => Pretty): ScalaCheckProp
}

Usage:

class PropertyWrapperSpec extends Specification with ScalaCheck { def is = s2"""
  Wrapped property ${
    val baseProp = Prop.forAll((s: String) => s.reverse.reverse == s)
    val wrappedProp = ScalaCheckProp(baseProp, Parameters().verbose, defaultFreqMapPretty)
    wrappedProp.setSeed("test-seed-123")
  }
"""
}

Exception Handling in Conversion

Handle various exception types during type conversion with appropriate error mapping.

// Exception handling during conversion:
// - FailureException -> Failure result
// - DecoratedResultException -> Enhanced failure
// - SkipException -> Skipped result
// - PendingException -> Pending result
// - Other exceptions -> Error results

Usage:

class ExceptionConversionSpec extends Specification with ScalaCheck { def is = s2"""
  Exception in property conversion ${
    prop((n: Int) => {
      if (n == Int.MinValue) failure("Special case failure")
      else success
    })
  }
  
  Skipped property ${
    prop((data: Option[String]) => data match {
      case None => skipped("No data to test")
      case Some(s) => s.length >= 0
    })
  }
"""
}

One Expectation Per Property

Control expectation counting in specifications to treat each property as a single expectation regardless of test count.

trait OneExpectationPerProp extends AsResultProp {
  implicit override def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
  implicit override def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
}

Usage:

class SingleExpectationSpec extends Specification with ScalaCheck with OneExpectationPerProp { def is = s2"""
  Property counts as one expectation ${
    prop((n: Int) => n + 0 == n).set(minTestsOk = 1000)  // Counts as 1 expectation, not 1000
  }
"""
}

Types

// Type conversion trait
trait AsResultProp extends ScalaCheckPropertyCheck with AsResultPropLowImplicits {
  implicit def asResultToProp[R : AsResult](r: R): Prop
  implicit def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
  implicit def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
}

// Low priority implicits
trait AsResultPropLowImplicits extends ScalaCheckPropertyCheck with ScalaCheckParameters {
  implicit def scalaCheckPropertyAsResult[S <: ScalaCheckProperty]: AsResult[S]
}

// DSL integration trait
trait ScalaCheckPropertyDsl extends FragmentsFactory with AsResultProp {
  implicit def propToScalaCheckProperty(prop: Prop)(implicit parameters: Parameters, prettyFreqMap: FreqMap[Set[Any]] => Pretty): ScalaCheckProp
  def properties(ps: Properties): Fragments
}

// Property wrapper
case class ScalaCheckProp(prop: Prop, parameters: Parameters, prettyFreqMap: FreqMap[Set[Any]] => Pretty) extends ScalaCheckProperty {
  type SelfType = ScalaCheckProp
  def setParameters(ps: Parameters): SelfType
  def setSeed(seed: Seed): SelfType  
  def setSeed(seed: String): SelfType
  def setPrettyFreqMap(f: FreqMap[Set[Any]] => Pretty): SelfType
}

// Single expectation trait
trait OneExpectationPerProp extends AsResultProp {
  implicit override def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
  implicit override def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
}

// Utility objects for pretty printing and details handling
object PrettyProduct {
  def toString[P <: Product](p: P): String
  def apply[P <: Product]: P => Pretty
}

object PrettyDetails {
  def collectDetails[T](fq: FreqMap[Set[T]]): execute.Details
  def removeDetails(fq: FreqMap[Set[Any]]): FreqMap[Set[Any]]
}