CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scalacheck--scalacheck-2-12

A comprehensive property-based testing library for Scala and Java applications that enables developers to specify program properties as testable assertions and automatically generates test cases to verify these properties.

Pending
Overview
Eval results
Files

generators.mddocs/

Generator Framework

The ScalaCheck generator framework provides comprehensive data generation capabilities for property-based testing. Generators create test values with configurable size parameters, deterministic seeds, and powerful combinators for building complex test data.

Capabilities

Core Generator Class

The fundamental generator abstraction with transformation, filtering, and sampling capabilities.

abstract class Gen[+T] {
  def map[U](f: T => U): Gen[U]
  def flatMap[U](f: T => Gen[U]): Gen[U]
  def filter(p: T => Boolean): Gen[T]
  def filterNot(p: T => Boolean): Gen[T]
  def suchThat(f: T => Boolean): Gen[T]
  def retryUntil(p: T => Boolean, maxTries: Int = 10): Gen[T]
  def sample: Option[T]
  def pureApply(p: Gen.Parameters, seed: Seed, retries: Int = 100): T
  def label(l: String): Gen[T]
  def :|(l: String): Gen[T]
  def |:(l: String): Gen[T]
}

Usage Example:

val evenInts = Gen.choose(1, 100).filter(_ % 2 == 0)
val positiveStrings = Gen.alphaStr.suchThat(_.nonEmpty)
val taggedGen = Gen.choose(1, 10).label("small integers")

Basic Generators

Fundamental generators for constant values, ranges, and selections.

object Gen {
  def const[T](x: T): Gen[T]
  def fail[T]: Gen[T]
  def choose[T](min: T, max: T)(implicit num: Choose[T]): Gen[T]
  def oneOf[T](xs: Iterable[T]): Gen[T]
  def oneOf[T](t0: T, t1: T, tn: T*): Gen[T]
  def frequency[T](gs: (Int, Gen[T])*): Gen[T]
  def prob(chance: Double): Gen[Boolean]
}

Usage Examples:

val alwaysTrue = Gen.const(true)
val dice = Gen.choose(1, 6)
val coin = Gen.oneOf(true, false)
val weightedCoin = Gen.frequency(3 -> true, 1 -> false) // 75% true
val biasedCoin = Gen.prob(0.7) // 70% true

Optional and Either Generators

Generators for optional values and Either types.

def option[T](g: Gen[T]): Gen[Option[T]]
def some[T](g: Gen[T]): Gen[Option[T]]
def either[T, U](gt: Gen[T], gu: Gen[U]): Gen[Either[T, U]]

Usage Examples:

val maybeInt = Gen.option(Gen.choose(1, 10))
val someInt = Gen.some(Gen.choose(1, 10)) // never generates None
val stringOrInt = Gen.either(Gen.alphaStr, Gen.choose(1, 100))

Collection Generators

Comprehensive collection generation with size control and various collection types.

def listOf[T](g: Gen[T]): Gen[List[T]]
def listOfN[T](n: Int, g: Gen[T]): Gen[List[T]]
def nonEmptyListOf[T](g: Gen[T]): Gen[List[T]]
def containerOf[C[_], T](g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]
def containerOfN[C[_], T](n: Int, g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]
def nonEmptyContainerOf[C[_], T](g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]
def mapOf[T, U](g: Gen[(T, U)]): Gen[Map[T, U]]
def mapOfN[T, U](n: Int, g: Gen[(T, U)]): Gen[Map[T, U]]
def nonEmptyMap[T, U](g: Gen[(T, U)]): Gen[Map[T, U]]

Usage Examples:

val intLists = Gen.listOf(Gen.choose(1, 10))
val exactly5Ints = Gen.listOfN(5, Gen.choose(1, 100))
val nonEmptyStrings = Gen.nonEmptyListOf(Gen.alphaChar.map(_.toString))
val intToStringMap = Gen.mapOf(Gen.zip(Gen.choose(1, 10), Gen.alphaStr))
val vectors = Gen.containerOf[Vector, Int](Gen.choose(1, 100))

Subset and Picking Generators

Generators for selecting subsets and elements from existing collections.

def pick[T](n: Int, l: Iterable[T]): Gen[Seq[T]]
def someOf[T](l: Iterable[T]): Gen[Seq[T]]
def atLeastOne[T](l: Iterable[T]): Gen[Seq[T]]

Usage Examples:

val colors = List("red", "green", "blue", "yellow", "purple")
val threeColors = Gen.pick(3, colors)
val someColors = Gen.someOf(colors)
val atLeastOneColor = Gen.atLeastOne(colors)

String and Character Generators

Specialized generators for characters and strings with various character sets.

val numChar: Gen[Char]
val alphaUpperChar: Gen[Char]
val alphaLowerChar: Gen[Char]
val alphaChar: Gen[Char]
val alphaNumChar: Gen[Char]
val asciiChar: Gen[Char]
val asciiPrintableChar: Gen[Char]
val hexChar: Gen[Char]

def stringOf(gc: Gen[Char]): Gen[String]
def stringOfN(n: Int, gc: Gen[Char]): Gen[String]
def nonEmptyStringOf(gc: Gen[Char]): Gen[String]

val identifier: Gen[String]
val numStr: Gen[String]
val alphaStr: Gen[String]
val alphaNumStr: Gen[String]
val asciiStr: Gen[String]
val hexStr: Gen[String]

Usage Examples:

val passwords = Gen.stringOfN(8, Gen.alphaNumChar)
val identifiers = Gen.identifier
val hexStrings = Gen.stringOf(Gen.hexChar)
val nonEmptyNames = Gen.nonEmptyStringOf(Gen.alphaChar)

Numeric Generators

Generators for various numeric types with special values and distributions.

val long: Gen[Long]
val double: Gen[Double] // [0, 1)
def posNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T]
def negNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T]
def chooseNum[T](minT: T, maxT: T, specials: T*)(implicit num: Numeric[T], c: Choose[T]): Gen[T]

// Distribution generators
def gaussian(mean: Double, stdDev: Double): Gen[Double]
def exponential(rate: Double): Gen[Double]
def geometric(mean: Double): Gen[Int]
def poisson(rate: Double): Gen[Int]
def binomial(test: Gen[Boolean], trials: Int): Gen[Int]

Usage Examples:

val positiveInts = Gen.posNum[Int]
val negativeDoubles = Gen.negNum[Double]
val specialInts = Gen.chooseNum(1, 100, 42, 13, 7) // includes special values
val normalDistrib = Gen.gaussian(0.0, 1.0)
val coinFlips = Gen.binomial(Gen.prob(0.5), 10)

Miscellaneous Generators

Generators for UUIDs, dates, and durations.

val uuid: Gen[UUID]
val calendar: Gen[Calendar]
val finiteDuration: Gen[FiniteDuration]
val duration: Gen[Duration] // includes infinite durations

Usage Examples:

val ids = Gen.uuid
val timestamps = Gen.calendar
val timeouts = Gen.finiteDuration
val allDurations = Gen.duration // may include Duration.Inf

Advanced Combinators

Powerful combinators for complex generator composition and control flow.

def sequence[C[_], T](gs: Traversable[Gen[T]])(implicit b: Buildable[T, C[T]]): Gen[C[T]]
def tailRecM[A, B](a0: A)(fn: A => Gen[Either[A, B]]): Gen[B]
def lzy[T](g: => Gen[T]): Gen[T]
def delay[T](g: => Gen[T]): Gen[T]
def recursive[A](fn: Gen[A] => Gen[A]): Gen[A]
def parameterized[T](f: Gen.Parameters => Gen[T]): Gen[T]
def sized[T](f: Int => Gen[T]): Gen[T]
val size: Gen[Int]
def resize[T](s: Int, g: Gen[T]): Gen[T]

Usage Examples:

// Generate lists of generators into generator of lists
val genList = List(Gen.choose(1, 10), Gen.choose(20, 30), Gen.choose(40, 50))
val combined = Gen.sequence(genList)

// Size-dependent generation
val sizedLists = Gen.sized(n => Gen.listOfN(n, Gen.choose(1, 100)))

// Recursive data structures
case class Tree(value: Int, children: List[Tree])
val treeGen = Gen.recursive[Tree] { recurse =>
  for {
    value <- Gen.choose(1, 100)
    size <- Gen.choose(0, 3)
    children <- Gen.listOfN(size, recurse)
  } yield Tree(value, children)
}

// Parameter access
val customGen = Gen.parameterized { params =>
  Gen.listOfN(params.size, Gen.alphaChar)
}

Zip Combinators

Combining multiple generators into tuples.

def zip[T, U](gt: Gen[T], gu: Gen[U]): Gen[(T, U)]
def zip[A, B, C](ga: Gen[A], gb: Gen[B], gc: Gen[C]): Gen[(A, B, C)]
// ... up to 9-tuples

Usage Examples:

val coordinates = Gen.zip(Gen.choose(-100, 100), Gen.choose(-100, 100))
val person = Gen.zip(Gen.alphaStr, Gen.choose(18, 80), Gen.oneOf("M", "F"))

Types

Generator Parameters

sealed abstract class Gen.Parameters {
  val size: Int
  val initialSeed: Option[Seed]
  val useLegacyShrinking: Boolean
  
  def withSize(size: Int): Gen.Parameters
  def withInitialSeed(seed: Seed): Gen.Parameters
  def withLegacyShrinking(b: Boolean): Gen.Parameters
}

object Gen.Parameters {
  val default: Gen.Parameters
}

Choose Type Class

trait Choose[T] {
  def choose(min: T, max: T): Gen[T]
}

// Implicit instances for numeric types
implicit val chooseInt: Choose[Int]
implicit val chooseLong: Choose[Long]
implicit val chooseDouble: Choose[Double]
implicit val chooseChar: Choose[Char]
implicit val chooseBigInt: Choose[BigInt]
implicit val chooseBigDecimal: Choose[BigDecimal]
implicit val chooseFiniteDuration: Choose[FiniteDuration]

Generator Composition Patterns

For-Comprehension Style

val personGen = for {
  name <- Gen.alphaStr.suchThat(_.length > 2)
  age <- Gen.choose(18, 80)
  email <- Gen.alphaStr.map(_ + "@example.com")
} yield Person(name, age, email)

Conditional Generation

val dataGen = Gen.oneOf(true, false).flatMap { isComplex =>
  if (isComplex) complexDataGen else simpleDataGen
}

Weighted Distribution

val priorityGen = Gen.frequency(
  1 -> "LOW",
  3 -> "MEDIUM", 
  5 -> "HIGH",
  1 -> "CRITICAL"
)

Install with Tessl CLI

npx tessl i tessl/maven-org-scalacheck--scalacheck-2-12

docs

arbitrary.md

cogen.md

generators.md

index.md

properties.md

property-collections.md

shrinking.md

stateful-testing.md

test-execution.md

tile.json