or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arbitrary.mdcogen.mdgenerators.mdindex.mdproperties.mdproperty-collections.mdshrinking.mdstateful-testing.mdtest-execution.md

generators.mddocs/

0

# Generator Framework

1

2

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.

3

4

## Capabilities

5

6

### Core Generator Class

7

8

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

9

10

```scala { .api }

11

abstract class Gen[+T] {

12

def map[U](f: T => U): Gen[U]

13

def flatMap[U](f: T => Gen[U]): Gen[U]

14

def filter(p: T => Boolean): Gen[T]

15

def filterNot(p: T => Boolean): Gen[T]

16

def suchThat(f: T => Boolean): Gen[T]

17

def retryUntil(p: T => Boolean, maxTries: Int = 10): Gen[T]

18

def sample: Option[T]

19

def pureApply(p: Gen.Parameters, seed: Seed, retries: Int = 100): T

20

def label(l: String): Gen[T]

21

def :|(l: String): Gen[T]

22

def |:(l: String): Gen[T]

23

}

24

```

25

26

**Usage Example:**

27

```scala

28

val evenInts = Gen.choose(1, 100).filter(_ % 2 == 0)

29

val positiveStrings = Gen.alphaStr.suchThat(_.nonEmpty)

30

val taggedGen = Gen.choose(1, 10).label("small integers")

31

```

32

33

### Basic Generators

34

35

Fundamental generators for constant values, ranges, and selections.

36

37

```scala { .api }

38

object Gen {

39

def const[T](x: T): Gen[T]

40

def fail[T]: Gen[T]

41

def choose[T](min: T, max: T)(implicit num: Choose[T]): Gen[T]

42

def oneOf[T](xs: Iterable[T]): Gen[T]

43

def oneOf[T](t0: T, t1: T, tn: T*): Gen[T]

44

def frequency[T](gs: (Int, Gen[T])*): Gen[T]

45

def prob(chance: Double): Gen[Boolean]

46

}

47

```

48

49

**Usage Examples:**

50

```scala

51

val alwaysTrue = Gen.const(true)

52

val dice = Gen.choose(1, 6)

53

val coin = Gen.oneOf(true, false)

54

val weightedCoin = Gen.frequency(3 -> true, 1 -> false) // 75% true

55

val biasedCoin = Gen.prob(0.7) // 70% true

56

```

57

58

### Optional and Either Generators

59

60

Generators for optional values and Either types.

61

62

```scala { .api }

63

def option[T](g: Gen[T]): Gen[Option[T]]

64

def some[T](g: Gen[T]): Gen[Option[T]]

65

def either[T, U](gt: Gen[T], gu: Gen[U]): Gen[Either[T, U]]

66

```

67

68

**Usage Examples:**

69

```scala

70

val maybeInt = Gen.option(Gen.choose(1, 10))

71

val someInt = Gen.some(Gen.choose(1, 10)) // never generates None

72

val stringOrInt = Gen.either(Gen.alphaStr, Gen.choose(1, 100))

73

```

74

75

### Collection Generators

76

77

Comprehensive collection generation with size control and various collection types.

78

79

```scala { .api }

80

def listOf[T](g: Gen[T]): Gen[List[T]]

81

def listOfN[T](n: Int, g: Gen[T]): Gen[List[T]]

82

def nonEmptyListOf[T](g: Gen[T]): Gen[List[T]]

83

def containerOf[C[_], T](g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]

84

def containerOfN[C[_], T](n: Int, g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]

85

def nonEmptyContainerOf[C[_], T](g: Gen[T])(implicit b: Buildable[T, C[T]]): Gen[C[T]]

86

def mapOf[T, U](g: Gen[(T, U)]): Gen[Map[T, U]]

87

def mapOfN[T, U](n: Int, g: Gen[(T, U)]): Gen[Map[T, U]]

88

def nonEmptyMap[T, U](g: Gen[(T, U)]): Gen[Map[T, U]]

89

```

90

91

**Usage Examples:**

92

```scala

93

val intLists = Gen.listOf(Gen.choose(1, 10))

94

val exactly5Ints = Gen.listOfN(5, Gen.choose(1, 100))

95

val nonEmptyStrings = Gen.nonEmptyListOf(Gen.alphaChar.map(_.toString))

96

val intToStringMap = Gen.mapOf(Gen.zip(Gen.choose(1, 10), Gen.alphaStr))

97

val vectors = Gen.containerOf[Vector, Int](Gen.choose(1, 100))

98

```

99

100

### Subset and Picking Generators

101

102

Generators for selecting subsets and elements from existing collections.

103

104

```scala { .api }

105

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

106

def someOf[T](l: Iterable[T]): Gen[Seq[T]]

107

def atLeastOne[T](l: Iterable[T]): Gen[Seq[T]]

108

```

109

110

**Usage Examples:**

111

```scala

112

val colors = List("red", "green", "blue", "yellow", "purple")

113

val threeColors = Gen.pick(3, colors)

114

val someColors = Gen.someOf(colors)

115

val atLeastOneColor = Gen.atLeastOne(colors)

116

```

117

118

### String and Character Generators

119

120

Specialized generators for characters and strings with various character sets.

121

122

```scala { .api }

123

val numChar: Gen[Char]

124

val alphaUpperChar: Gen[Char]

125

val alphaLowerChar: Gen[Char]

126

val alphaChar: Gen[Char]

127

val alphaNumChar: Gen[Char]

128

val asciiChar: Gen[Char]

129

val asciiPrintableChar: Gen[Char]

130

val hexChar: Gen[Char]

131

132

def stringOf(gc: Gen[Char]): Gen[String]

133

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

134

def nonEmptyStringOf(gc: Gen[Char]): Gen[String]

135

136

val identifier: Gen[String]

137

val numStr: Gen[String]

138

val alphaStr: Gen[String]

139

val alphaNumStr: Gen[String]

140

val asciiStr: Gen[String]

141

val hexStr: Gen[String]

142

```

143

144

**Usage Examples:**

145

```scala

146

val passwords = Gen.stringOfN(8, Gen.alphaNumChar)

147

val identifiers = Gen.identifier

148

val hexStrings = Gen.stringOf(Gen.hexChar)

149

val nonEmptyNames = Gen.nonEmptyStringOf(Gen.alphaChar)

150

```

151

152

### Numeric Generators

153

154

Generators for various numeric types with special values and distributions.

155

156

```scala { .api }

157

val long: Gen[Long]

158

val double: Gen[Double] // [0, 1)

159

def posNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T]

160

def negNum[T](implicit num: Numeric[T], c: Choose[T]): Gen[T]

161

def chooseNum[T](minT: T, maxT: T, specials: T*)(implicit num: Numeric[T], c: Choose[T]): Gen[T]

162

163

// Distribution generators

164

def gaussian(mean: Double, stdDev: Double): Gen[Double]

165

def exponential(rate: Double): Gen[Double]

166

def geometric(mean: Double): Gen[Int]

167

def poisson(rate: Double): Gen[Int]

168

def binomial(test: Gen[Boolean], trials: Int): Gen[Int]

169

```

170

171

**Usage Examples:**

172

```scala

173

val positiveInts = Gen.posNum[Int]

174

val negativeDoubles = Gen.negNum[Double]

175

val specialInts = Gen.chooseNum(1, 100, 42, 13, 7) // includes special values

176

val normalDistrib = Gen.gaussian(0.0, 1.0)

177

val coinFlips = Gen.binomial(Gen.prob(0.5), 10)

178

```

179

180

### Miscellaneous Generators

181

182

Generators for UUIDs, dates, and durations.

183

184

```scala { .api }

185

val uuid: Gen[UUID]

186

val calendar: Gen[Calendar]

187

val finiteDuration: Gen[FiniteDuration]

188

val duration: Gen[Duration] // includes infinite durations

189

```

190

191

**Usage Examples:**

192

```scala

193

val ids = Gen.uuid

194

val timestamps = Gen.calendar

195

val timeouts = Gen.finiteDuration

196

val allDurations = Gen.duration // may include Duration.Inf

197

```

198

199

### Advanced Combinators

200

201

Powerful combinators for complex generator composition and control flow.

202

203

```scala { .api }

204

def sequence[C[_], T](gs: Traversable[Gen[T]])(implicit b: Buildable[T, C[T]]): Gen[C[T]]

205

def tailRecM[A, B](a0: A)(fn: A => Gen[Either[A, B]]): Gen[B]

206

def lzy[T](g: => Gen[T]): Gen[T]

207

def delay[T](g: => Gen[T]): Gen[T]

208

def recursive[A](fn: Gen[A] => Gen[A]): Gen[A]

209

def parameterized[T](f: Gen.Parameters => Gen[T]): Gen[T]

210

def sized[T](f: Int => Gen[T]): Gen[T]

211

val size: Gen[Int]

212

def resize[T](s: Int, g: Gen[T]): Gen[T]

213

```

214

215

**Usage Examples:**

216

```scala

217

// Generate lists of generators into generator of lists

218

val genList = List(Gen.choose(1, 10), Gen.choose(20, 30), Gen.choose(40, 50))

219

val combined = Gen.sequence(genList)

220

221

// Size-dependent generation

222

val sizedLists = Gen.sized(n => Gen.listOfN(n, Gen.choose(1, 100)))

223

224

// Recursive data structures

225

case class Tree(value: Int, children: List[Tree])

226

val treeGen = Gen.recursive[Tree] { recurse =>

227

for {

228

value <- Gen.choose(1, 100)

229

size <- Gen.choose(0, 3)

230

children <- Gen.listOfN(size, recurse)

231

} yield Tree(value, children)

232

}

233

234

// Parameter access

235

val customGen = Gen.parameterized { params =>

236

Gen.listOfN(params.size, Gen.alphaChar)

237

}

238

```

239

240

### Zip Combinators

241

242

Combining multiple generators into tuples.

243

244

```scala { .api }

245

def zip[T, U](gt: Gen[T], gu: Gen[U]): Gen[(T, U)]

246

def zip[A, B, C](ga: Gen[A], gb: Gen[B], gc: Gen[C]): Gen[(A, B, C)]

247

// ... up to 9-tuples

248

```

249

250

**Usage Examples:**

251

```scala

252

val coordinates = Gen.zip(Gen.choose(-100, 100), Gen.choose(-100, 100))

253

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

254

```

255

256

## Types

257

258

### Generator Parameters

259

260

```scala { .api }

261

sealed abstract class Gen.Parameters {

262

val size: Int

263

val initialSeed: Option[Seed]

264

val useLegacyShrinking: Boolean

265

266

def withSize(size: Int): Gen.Parameters

267

def withInitialSeed(seed: Seed): Gen.Parameters

268

def withLegacyShrinking(b: Boolean): Gen.Parameters

269

}

270

271

object Gen.Parameters {

272

val default: Gen.Parameters

273

}

274

```

275

276

### Choose Type Class

277

278

```scala { .api }

279

trait Choose[T] {

280

def choose(min: T, max: T): Gen[T]

281

}

282

283

// Implicit instances for numeric types

284

implicit val chooseInt: Choose[Int]

285

implicit val chooseLong: Choose[Long]

286

implicit val chooseDouble: Choose[Double]

287

implicit val chooseChar: Choose[Char]

288

implicit val chooseBigInt: Choose[BigInt]

289

implicit val chooseBigDecimal: Choose[BigDecimal]

290

implicit val chooseFiniteDuration: Choose[FiniteDuration]

291

```

292

293

## Generator Composition Patterns

294

295

### For-Comprehension Style

296

297

```scala

298

val personGen = for {

299

name <- Gen.alphaStr.suchThat(_.length > 2)

300

age <- Gen.choose(18, 80)

301

email <- Gen.alphaStr.map(_ + "@example.com")

302

} yield Person(name, age, email)

303

```

304

305

### Conditional Generation

306

307

```scala

308

val dataGen = Gen.oneOf(true, false).flatMap { isComplex =>

309

if (isComplex) complexDataGen else simpleDataGen

310

}

311

```

312

313

### Weighted Distribution

314

315

```scala

316

val priorityGen = Gen.frequency(

317

1 -> "LOW",

318

3 -> "MEDIUM",

319

5 -> "HIGH",

320

1 -> "CRITICAL"

321

)

322

```