or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dsl-integration.mdindex.mdproperty-checking.mdproperty-configuration.mdproperty-creation.mdresult-conversion.mdutilities.md

property-creation.mddocs/

0

# Property Creation

1

2

Core functionality for creating ScalaCheck properties from test functions. The `ScalaCheckPropertyCreation` trait provides `prop` methods that convert regular Scala functions into executable ScalaCheck properties with full typeclass customization.

3

4

## Capabilities

5

6

### Property Creation from Functions

7

8

Creates ScalaCheck properties from functions with 1-8 parameters, automatically handling generator, shrinking, and pretty-printing typeclass requirements.

9

10

```scala { .api }

11

trait ScalaCheckPropertyCreation {

12

/** Create a ScalaCheck property from a function of 1 argument */

13

def prop[T, R](result: T => R)(implicit

14

arbitrary: Arbitrary[T],

15

shrink: Shrink[T],

16

pretty: T => Pretty,

17

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

18

asResult: AsResult[R],

19

parameters: Parameters

20

): ScalaCheckFunction1[T, R]

21

22

/** Create a ScalaCheck property from a function of 2 arguments */

23

def prop[T1, T2, R](result: (T1, T2) => R)(implicit

24

arbitrary1: Arbitrary[T1], shrink1: Shrink[T1], pretty1: T1 => Pretty,

25

arbitrary2: Arbitrary[T2], shrink2: Shrink[T2], pretty2: T2 => Pretty,

26

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

27

asResult: AsResult[R],

28

parameters: Parameters

29

): ScalaCheckFunction2[T1, T2, R]

30

31

/** Create a ScalaCheck property from a function of 3 arguments */

32

def prop[T1, T2, T3, R](result: (T1, T2, T3) => R)(implicit

33

arbitrary1: Arbitrary[T1], shrink1: Shrink[T1], pretty1: T1 => Pretty,

34

arbitrary2: Arbitrary[T2], shrink2: Shrink[T2], pretty2: T2 => Pretty,

35

arbitrary3: Arbitrary[T3], shrink3: Shrink[T3], pretty3: T3 => Pretty,

36

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

37

asResult: AsResult[R],

38

parameters: Parameters

39

): ScalaCheckFunction3[T1, T2, T3, R]

40

41

/** Similar methods exist for 4-8 arguments following the same pattern */

42

}

43

```

44

45

**Usage Examples:**

46

47

```scala

48

import org.specs2.ScalaCheck

49

import org.scalacheck.{Arbitrary, Gen}

50

51

class MySpec extends Specification with ScalaCheck { def is = s2"""

52

Property examples

53

simple property $simpleProp

54

two argument property $twoArgProp

55

custom generator property $customGenProp

56

"""

57

58

// Basic property with default generators

59

def simpleProp = prop { (x: Int) =>

60

x + 0 must_== x

61

}

62

63

// Property with two arguments

64

def twoArgProp = prop { (x: Int, y: Int) =>

65

(x + y) - y must_== x

66

}

67

68

// Property with custom generator

69

def customGenProp = {

70

implicit val customArb: Arbitrary[Int] = Arbitrary(Gen.choose(1, 100))

71

prop { (x: Int) =>

72

x must be_>(0)

73

}

74

}

75

}

76

```

77

78

### Property Function Types

79

80

The `prop` methods return strongly-typed property function objects that provide extensive customization capabilities.

81

82

```scala { .api }

83

/** Property function for single argument */

84

case class ScalaCheckFunction1[T, R](

85

execute: T => R,

86

arbitrary: Arbitrary[T],

87

shrink: Option[Shrink[T]],

88

collectors: List[T => Any],

89

pretty: T => Pretty,

90

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

91

asResult: AsResult[R],

92

context: Option[Context],

93

parameters: Parameters

94

) extends ScalaCheckFunction {

95

96

/** Disable shrinking for this property */

97

def noShrink: ScalaCheckFunction1[T, R]

98

99

/** Set custom arbitrary generator */

100

def setArbitrary(arbitrary: Arbitrary[T]): ScalaCheckFunction1[T, R]

101

102

/** Set custom generator */

103

def setGen(gen: Gen[T]): ScalaCheckFunction1[T, R]

104

105

/** Set custom shrinking strategy */

106

def setShrink(shrink: Shrink[T]): ScalaCheckFunction1[T, R]

107

108

/** Set custom pretty printer */

109

def setPretty(pretty: T => Pretty): ScalaCheckFunction1[T, R]

110

111

/** Set custom pretty printer from string function */

112

def pretty(pretty: T => String): ScalaCheckFunction1[T, R]

113

114

/** Add value collector for frequency reporting */

115

def collectArg(f: T => Any): ScalaCheckFunction1[T, R]

116

117

/** Add default toString collector */

118

def collect: ScalaCheckFunction1[T, R]

119

120

/** Transform input parameters before execution */

121

def prepare(action: T => T): ScalaCheckFunction1[T, R]

122

}

123

124

/** Property functions for 2-8 arguments follow similar patterns with numbered methods */

125

126

// ScalaCheckFunction4 through ScalaCheckFunction8 provide parameter-specific methods:

127

case class ScalaCheckFunction4[T1, T2, T3, T4, R](

128

execute: (T1, T2, T3, T4) => R,

129

argInstances1: ScalaCheckArgInstances[T1],

130

argInstances2: ScalaCheckArgInstances[T2],

131

argInstances3: ScalaCheckArgInstances[T3],

132

argInstances4: ScalaCheckArgInstances[T4],

133

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

134

asResult: AsResult[R],

135

context: Option[Context],

136

parameters: Parameters

137

) extends ScalaCheckFunction

138

139

// Similar patterns exist for ScalaCheckFunction5, ScalaCheckFunction6, ScalaCheckFunction7, ScalaCheckFunction8

140

case class ScalaCheckFunction2[T1, T2, R](

141

execute: (T1, T2) => R,

142

argInstances1: ScalaCheckArgInstances[T1],

143

argInstances2: ScalaCheckArgInstances[T2],

144

prettyFreqMap: FreqMap[Set[Any]] => Pretty,

145

asResult: AsResult[R],

146

context: Option[Context],

147

parameters: Parameters

148

) extends ScalaCheckFunction {

149

150

/** Disable shrinking for all parameters */

151

def noShrink: ScalaCheckFunction2[T1, T2, R]

152

153

/** Set arbitrary for first parameter */

154

def setArbitrary1(a1: Arbitrary[T1]): ScalaCheckFunction2[T1, T2, R]

155

156

/** Set arbitrary for second parameter */

157

def setArbitrary2(a2: Arbitrary[T2]): ScalaCheckFunction2[T1, T2, R]

158

159

/** Set arbitraries for both parameters */

160

def setArbitraries(a1: Arbitrary[T1], a2: Arbitrary[T2]): ScalaCheckFunction2[T1, T2, R]

161

162

/** Set generators for both parameters */

163

def setGens(g1: Gen[T1], g2: Gen[T2]): ScalaCheckFunction2[T1, T2, R]

164

165

/** Set shrinks for both parameters */

166

def setShrinks(s1: Shrink[T1], s2: Shrink[T2]): ScalaCheckFunction2[T1, T2, R]

167

168

/** Set pretty printers for both parameters */

169

def setPretties(p1: T1 => Pretty, p2: T2 => Pretty): ScalaCheckFunction2[T1, T2, R]

170

171

/** Set pretty printers from string functions for both parameters */

172

def pretties(p1: T1 => String, p2: T2 => String): ScalaCheckFunction2[T1, T2, R]

173

174

/** Add collector for first parameter */

175

def collectArg1(f: T1 => Any): ScalaCheckFunction2[T1, T2, R]

176

177

/** Add collector for second parameter */

178

def collectArg2(f: T2 => Any): ScalaCheckFunction2[T1, T2, R]

179

180

/** Add collectors for all parameters */

181

def collectAllArgs(f1: T1 => Any, f2: T2 => Any): ScalaCheckFunction2[T1, T2, R]

182

183

/** Add default toString collectors for all parameters */

184

def collectAll: ScalaCheckFunction2[T1, T2, R]

185

186

/** Transform input parameters before execution */

187

def prepare(action: (T1, T2) => (T1, T2)): ScalaCheckFunction2[T1, T2, R]

188

189

/** Set execution context */

190

def setContext(context: Context): ScalaCheckFunction2[T1, T2, R]

191

192

/** Set before action */

193

def before(action: =>Any): ScalaCheckFunction2[T1, T2, R]

194

195

/** Set after action */

196

def after(action: =>Any): ScalaCheckFunction2[T1, T2, R]

197

198

/** Set both before and after actions */

199

def beforeAfter(beforeAction: =>Any, afterAction: =>Any): ScalaCheckFunction2[T1, T2, R]

200

201

/** Set around action */

202

def around(action: Result => Result): ScalaCheckFunction2[T1, T2, R]

203

}

204

```

205

206

**Advanced Usage Examples:**

207

208

```scala

209

// Property with custom configuration

210

def customProperty = {

211

prop { (x: Int) =>

212

x > 0

213

}.setGen(Gen.choose(1, 1000))

214

.pretty(x => s"positive number: $x")

215

.collect

216

.verbose

217

.set(minTestsOk = 200)

218

}

219

220

// Property with setup/teardown

221

def contextProperty = {

222

var setupCount = 0

223

224

prop { (x: String) =>

225

x.length >= 0

226

}.before {

227

setupCount += 1

228

}.after {

229

println(s"Ran $setupCount tests")

230

}

231

}

232

233

// Property with before/after actions combined

234

def beforeAfterProperty = {

235

prop { (x: Int, y: Int) =>

236

x + y == y + x

237

}.beforeAfter(

238

beforeAction = println("Starting test"),

239

afterAction = println("Test completed")

240

)

241

}

242

243

// Property with data preparation

244

def dataPreparationProperty = {

245

prop { (x: Int, y: Int) =>

246

x >= 0 && y >= 0 && x + y >= 0

247

}.prepare { (x, y) =>

248

(math.abs(x), math.abs(y)) // Ensure positive inputs

249

}.verbose

250

}

251

252

// Property with collectors and custom parameters

253

def collectorProperty = {

254

prop { (x: Int, y: Int) =>

255

(x * y) % 2 == (x % 2) * (y % 2)

256

}.collectArg1(x => if (x % 2 == 0) "even" else "odd")

257

.collectArg2(y => if (y % 2 == 0) "even" else "odd")

258

.set(minTestsOk = 100, maxSize = 50)

259

}

260

```

261

262

### Multi-Parameter Property Support

263

264

The library provides property creation methods for functions with up to 8 parameters, each with independent typeclass customization:

265

266

```scala { .api }

267

// Each ScalaCheckFunctionN provides parameter-specific methods:

268

trait ScalaCheckFunction3[T1, T2, T3, R] extends ScalaCheckFunction {

269

def setArbitrary1(a1: Arbitrary[T1]): ScalaCheckFunction3[T1, T2, T3, R]

270

def setArbitrary2(a2: Arbitrary[T2]): ScalaCheckFunction3[T1, T2, T3, R]

271

def setArbitrary3(a3: Arbitrary[T3]): ScalaCheckFunction3[T1, T2, T3, R]

272

def setArbitraries(a1: Arbitrary[T1], a2: Arbitrary[T2], a3: Arbitrary[T3]): ScalaCheckFunction3[T1, T2, T3, R]

273

274

def setGen1(g1: Gen[T1]): ScalaCheckFunction3[T1, T2, T3, R]

275

def setGen2(g2: Gen[T2]): ScalaCheckFunction3[T1, T2, T3, R]

276

def setGen3(g3: Gen[T3]): ScalaCheckFunction3[T1, T2, T3, R]

277

def setGens(g1: Gen[T1], g2: Gen[T2], g3: Gen[T3]): ScalaCheckFunction3[T1, T2, T3, R]

278

279

def collectArg1(f: T1 => Any): ScalaCheckFunction3[T1, T2, T3, R]

280

def collectArg2(f: T2 => Any): ScalaCheckFunction3[T1, T2, T3, R]

281

def collectArg3(f: T3 => Any): ScalaCheckFunction3[T1, T2, T3, R]

282

def collectAllArgs(f1: T1 => Any, f2: T2 => Any, f3: T3 => Any): ScalaCheckFunction3[T1, T2, T3, R]

283

}

284

```

285

286

### Typeclass Requirements

287

288

Each property creation method requires several Scala typeclasses to be in implicit scope:

289

290

```scala { .api }

291

// Required for each parameter type T

292

implicit val arbitrary: Arbitrary[T] // Generates random values

293

implicit val shrink: Shrink[T] // Shrinks failing cases

294

implicit val pretty: T => Pretty // Pretty prints values

295

296

// Required for the property function

297

implicit val prettyFreqMap: FreqMap[Set[Any]] => Pretty // Formats frequency data

298

implicit val asResult: AsResult[R] // Converts result to specs2 Result

299

implicit val parameters: Parameters // Test configuration

300

```

301

302

These typeclasses enable:

303

- **Arbitrary**: Random value generation for property inputs

304

- **Shrink**: Minimizing failing test cases to simpler counterexamples

305

- **Pretty**: Formatted display of values in test output

306

- **AsResult**: Integration with specs2's result system

307

- **Parameters**: Configuration of test execution parameters