0
# Type Integration
1
2
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.
3
4
## Capabilities
5
6
### Result to Property Conversion
7
8
Convert any specs2 `AsResult` type to ScalaCheck `Prop` for use in property-based testing.
9
10
```scala { .api }
11
trait AsResultProp {
12
implicit def asResultToProp[R : AsResult](r: R): Prop
13
}
14
```
15
16
**Usage:**
17
```scala
18
import org.specs2._
19
import org.specs2.matcher.Matchers
20
import org.scalacheck._
21
22
class ResultConversionSpec extends Specification with ScalaCheck with Matchers { def is = s2"""
23
MatchResult to Prop ${
24
val prop = Prop.forAll((s: String) => s must not be empty)
25
check(prop, defaultParameters, defaultFreqMapPretty)
26
}
27
28
Boolean to Prop ${
29
val prop = Prop.forAll((n: Int) => n + 0 == n) // Boolean result converted to Prop
30
check(prop, defaultParameters, defaultFreqMapPretty)
31
}
32
33
Custom Result to Prop ${
34
def validateData(data: String): Result =
35
if (data.nonEmpty) Success("Valid data")
36
else Failure("Empty data not allowed")
37
38
val prop = Prop.forAll(Gen.alphaStr.suchThat(_.nonEmpty))((s: String) => validateData(s))
39
check(prop, defaultParameters, defaultFreqMapPretty)
40
}
41
"""
42
}
43
```
44
45
### Property to Result Conversion
46
47
Convert ScalaCheck `Prop` and `Properties` to specs2 `Result` types for integration with specifications.
48
49
```scala { .api }
50
trait AsResultProp {
51
implicit def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
52
implicit def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
53
}
54
```
55
56
**Usage:**
57
```scala
58
class PropToResultSpec extends Specification with ScalaCheck { def is = s2"""
59
ScalaCheck Prop as example ${
60
Prop.forAll((n: Int) => n * n >= 0) // Automatically converted to Result
61
}
62
63
Properties collection as example ${
64
val props = new Properties("math") {
65
property("addition") = Prop.forAll((a: Int, b: Int) => a + b == b + a)
66
property("multiplication") = Prop.forAll((x: Int) => x * 0 == 0)
67
}
68
props // Automatically converted to Result
69
}
70
"""
71
}
72
```
73
74
### ScalaCheck Property Integration
75
76
Convert custom ScalaCheck property types to specs2 results with parameter and configuration preservation.
77
78
```scala { .api }
79
trait AsResultPropLowImplicits {
80
implicit def scalaCheckPropertyAsResult[S <: ScalaCheckProperty]: AsResult[S]
81
}
82
```
83
84
**Usage:**
85
```scala
86
class PropertyIntegrationSpec extends Specification with ScalaCheck { def is = s2"""
87
Custom ScalaCheckFunction ${
88
prop((data: List[Int]) => data.reverse.reverse == data)
89
.setGen(Gen.listOfN(10, Gen.choose(1, 100)))
90
.collect // ScalaCheckFunction1 automatically converted to Result
91
}
92
93
Configured property ${
94
prop((s: String, n: Int) => s.length + n >= n)
95
.setGen1(Gen.alphaStr)
96
.setGen2(Gen.posNum[Int])
97
.verbose // ScalaCheckFunction2 automatically converted to Result
98
}
99
"""
100
}
101
```
102
103
### DSL Integration
104
105
Enable properties to be used directly in specs2 specifications with automatic conversion and fragment creation.
106
107
```scala { .api }
108
trait ScalaCheckPropertyDsl extends FragmentsFactory with AsResultProp {
109
implicit def propToScalaCheckProperty(prop: Prop)(implicit
110
parameters: Parameters,
111
prettyFreqMap: FreqMap[Set[Any]] => Pretty
112
): ScalaCheckProp
113
114
def properties(ps: Properties): Fragments
115
}
116
```
117
118
**Usage:**
119
```scala
120
class DSLIntegrationSpec extends Specification with ScalaCheck { def is = s2"""
121
Property in specification ${prop((x: Int) => x + 0 == x)}
122
123
Multiple properties ${
124
val mathProps = new Properties("mathematics") {
125
property("commutativity") = Prop.forAll((a: Int, b: Int) => a + b == b + a)
126
property("associativity") = Prop.forAll((a: Int, b: Int, c: Int) => (a + b) + c == a + (b + c))
127
property("identity") = Prop.forAll((n: Int) => n + 0 == n)
128
}
129
properties(mathProps) // Creates multiple examples from Properties
130
}
131
"""
132
}
133
```
134
135
### Property Wrapper Types
136
137
Wrap ScalaCheck properties with specs2-specific configuration and behavior.
138
139
```scala { .api }
140
case class ScalaCheckProp(
141
prop: Prop,
142
parameters: Parameters,
143
prettyFreqMap: FreqMap[Set[Any]] => Pretty
144
) extends ScalaCheckProperty {
145
type SelfType = ScalaCheckProp
146
def setParameters(ps: Parameters): ScalaCheckProp
147
def setSeed(seed: Seed): ScalaCheckProp
148
def setSeed(seed: String): ScalaCheckProp
149
def setPrettyFreqMap(f: FreqMap[Set[Any]] => Pretty): ScalaCheckProp
150
}
151
```
152
153
**Usage:**
154
```scala
155
class PropertyWrapperSpec extends Specification with ScalaCheck { def is = s2"""
156
Wrapped property ${
157
val baseProp = Prop.forAll((s: String) => s.reverse.reverse == s)
158
val wrappedProp = ScalaCheckProp(baseProp, Parameters().verbose, defaultFreqMapPretty)
159
wrappedProp.setSeed("test-seed-123")
160
}
161
"""
162
}
163
```
164
165
### Exception Handling in Conversion
166
167
Handle various exception types during type conversion with appropriate error mapping.
168
169
```scala { .api }
170
// Exception handling during conversion:
171
// - FailureException -> Failure result
172
// - DecoratedResultException -> Enhanced failure
173
// - SkipException -> Skipped result
174
// - PendingException -> Pending result
175
// - Other exceptions -> Error results
176
```
177
178
**Usage:**
179
```scala
180
class ExceptionConversionSpec extends Specification with ScalaCheck { def is = s2"""
181
Exception in property conversion ${
182
prop((n: Int) => {
183
if (n == Int.MinValue) failure("Special case failure")
184
else success
185
})
186
}
187
188
Skipped property ${
189
prop((data: Option[String]) => data match {
190
case None => skipped("No data to test")
191
case Some(s) => s.length >= 0
192
})
193
}
194
"""
195
}
196
```
197
198
### One Expectation Per Property
199
200
Control expectation counting in specifications to treat each property as a single expectation regardless of test count.
201
202
```scala { .api }
203
trait OneExpectationPerProp extends AsResultProp {
204
implicit override def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
205
implicit override def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
206
}
207
```
208
209
**Usage:**
210
```scala
211
class SingleExpectationSpec extends Specification with ScalaCheck with OneExpectationPerProp { def is = s2"""
212
Property counts as one expectation ${
213
prop((n: Int) => n + 0 == n).set(minTestsOk = 1000) // Counts as 1 expectation, not 1000
214
}
215
"""
216
}
217
```
218
219
## Types
220
221
```scala { .api }
222
// Type conversion trait
223
trait AsResultProp extends ScalaCheckPropertyCheck with AsResultPropLowImplicits {
224
implicit def asResultToProp[R : AsResult](r: R): Prop
225
implicit def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
226
implicit def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
227
}
228
229
// Low priority implicits
230
trait AsResultPropLowImplicits extends ScalaCheckPropertyCheck with ScalaCheckParameters {
231
implicit def scalaCheckPropertyAsResult[S <: ScalaCheckProperty]: AsResult[S]
232
}
233
234
// DSL integration trait
235
trait ScalaCheckPropertyDsl extends FragmentsFactory with AsResultProp {
236
implicit def propToScalaCheckProperty(prop: Prop)(implicit parameters: Parameters, prettyFreqMap: FreqMap[Set[Any]] => Pretty): ScalaCheckProp
237
def properties(ps: Properties): Fragments
238
}
239
240
// Property wrapper
241
case class ScalaCheckProp(prop: Prop, parameters: Parameters, prettyFreqMap: FreqMap[Set[Any]] => Pretty) extends ScalaCheckProperty {
242
type SelfType = ScalaCheckProp
243
def setParameters(ps: Parameters): SelfType
244
def setSeed(seed: Seed): SelfType
245
def setSeed(seed: String): SelfType
246
def setPrettyFreqMap(f: FreqMap[Set[Any]] => Pretty): SelfType
247
}
248
249
// Single expectation trait
250
trait OneExpectationPerProp extends AsResultProp {
251
implicit override def propAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Prop]
252
implicit override def propertiesAsResult(implicit p: Parameters, pfq: FreqMap[Set[Any]] => Pretty): AsResult[Properties]
253
}
254
255
// Utility objects for pretty printing and details handling
256
object PrettyProduct {
257
def toString[P <: Product](p: P): String
258
def apply[P <: Product]: P => Pretty
259
}
260
261
object PrettyDetails {
262
def collectDetails[T](fq: FreqMap[Set[T]]): execute.Details
263
def removeDetails(fq: FreqMap[Set[Any]]): FreqMap[Set[Any]]
264
}
265
```