0
# Result Conversion
1
2
Bidirectional conversion system between ScalaCheck Prop/Properties and specs2 AsResult types for seamless integration. The `AsResultProp` trait provides implicit conversions that enable ScalaCheck properties to work directly within specs2 specifications.
3
4
## Capabilities
5
6
### AsResult to Prop Conversion
7
8
Converts any specs2 AsResult type to a ScalaCheck Prop, enabling property-based testing of existing specs2 matchers and test results.
9
10
```scala { .api }
11
trait AsResultProp {
12
/**
13
* Convert any AsResult type to a ScalaCheck Prop
14
* Handles all specs2 result types: Success, Failure, Error, Skipped, Pending
15
* @param r - Value with AsResult typeclass instance
16
* @return ScalaCheck Prop that can be executed
17
*/
18
implicit def asResultToProp[R : AsResult](r: R): Prop
19
}
20
```
21
22
**Usage Examples:**
23
24
```scala
25
import org.specs2.{Specification, ScalaCheck}
26
import org.specs2.matcher.MatchResult
27
28
class ConversionSpec extends Specification with ScalaCheck { def is = s2"""
29
AsResult to Prop conversion examples
30
matcher results convert to props $matcherToProp
31
custom results convert to props $customToProp
32
exception handling $exceptionToProp
33
"""
34
35
// specs2 matcher results automatically convert to Prop
36
def matcherToProp = prop { (x: Int) =>
37
// This matcher result is automatically converted to Prop
38
x + 1 must be_>(x)
39
}
40
41
// Custom AsResult implementations
42
case class CustomResult(success: Boolean, message: String)
43
44
implicit val customAsResult: AsResult[CustomResult] = new AsResult[CustomResult] {
45
def asResult(c: =>CustomResult) = {
46
lazy val result = c
47
if (result.success) Success(result.message)
48
else Failure(result.message)
49
}
50
}
51
52
def customToProp = prop { (x: String) =>
53
// Custom result type converts to Prop via AsResult
54
CustomResult(x.nonEmpty, s"String '$x' non-empty check")
55
}
56
57
// Exception handling in conversion
58
def exceptionToProp = prop { (x: Int) =>
59
if (x == 0) throw new IllegalArgumentException("Zero not allowed")
60
else Success(s"Value $x is valid")
61
}
62
}
63
```
64
65
### Prop to AsResult Conversion
66
67
Converts ScalaCheck Prop objects to specs2 AsResult, enabling direct use of ScalaCheck properties as specs2 examples.
68
69
```scala { .api }
70
/**
71
* Convert ScalaCheck Prop to specs2 AsResult
72
* Executes the property with provided parameters and formats results
73
* @param p - Test parameters for property execution
74
* @param pfq - Pretty formatter for frequency/collector data
75
* @return AsResult instance for Prop
76
*/
77
implicit def propAsResult(
78
implicit p: Parameters,
79
pfq: FreqMap[Set[Any]] => Pretty
80
): AsResult[Prop]
81
```
82
83
**Usage Examples:**
84
85
```scala
86
import org.scalacheck.{Prop, Gen}
87
88
class PropToResultSpec extends Specification with ScalaCheck { def is = s2"""
89
Prop to AsResult conversion examples
90
raw props work as examples $rawPropExample
91
generated props work as examples $generatedPropExample
92
props with custom config $configuredPropExample
93
"""
94
95
// Raw ScalaCheck Prop works directly as specs2 example
96
def rawPropExample = {
97
val prop = Prop.forAll { (x: Int) => x + 0 == x }
98
prop // Automatically converted to specs2 Result
99
}
100
101
// Generated Prop with custom generators
102
def generatedPropExample = {
103
val stringGen = Gen.alphaNumStr.suchThat(_.nonEmpty)
104
val prop = Prop.forAll(stringGen) { s =>
105
s.reverse.reverse == s
106
}
107
prop
108
}
109
110
// Prop with custom parameters
111
def configuredPropExample = {
112
implicit val params = Parameters(minTestsOk = 500).verbose
113
114
val prop = Prop.forAll { (list: List[Int]) =>
115
list.sorted.length == list.length
116
}
117
prop
118
}
119
}
120
```
121
122
### Properties to AsResult Conversion
123
124
Converts ScalaCheck Properties objects (collections of named properties) to specs2 AsResult for batch execution.
125
126
```scala { .api }
127
/**
128
* Convert ScalaCheck Properties to specs2 AsResult
129
* Executes all properties in the collection and aggregates results
130
* @param p - Test parameters for property execution
131
* @param pfq - Pretty formatter for frequency/collector data
132
* @return AsResult instance for Properties
133
*/
134
implicit def propertiesAsResult(
135
implicit p: Parameters,
136
pfq: FreqMap[Set[Any]] => Pretty
137
): AsResult[Properties]
138
```
139
140
**Usage Examples:**
141
142
```scala
143
import org.scalacheck.Properties
144
145
class PropertiesToResultSpec extends Specification with ScalaCheck { def is = s2"""
146
Properties to AsResult conversion examples
147
math properties $mathProperties
148
string properties $stringProperties
149
list properties $listProperties
150
"""
151
152
// Math properties as specs2 example
153
def mathProperties = new Properties("Math") {
154
property("addition commutative") = Prop.forAll { (x: Int, y: Int) =>
155
x + y == y + x
156
}
157
158
property("multiplication associative") = Prop.forAll { (x: Int, y: Int, z: Int) =>
159
(x * y) * z == x * (y * z)
160
}
161
162
property("distributive") = Prop.forAll { (x: Int, y: Int, z: Int) =>
163
x * (y + z) == (x * y) + (x * z)
164
}
165
}
166
167
// String properties with custom parameters
168
def stringProperties = {
169
implicit val params = Parameters(minTestsOk = 200).verbose
170
171
new Properties("Strings") {
172
property("reverse twice") = Prop.forAll { (s: String) =>
173
s.reverse.reverse == s
174
}
175
176
property("length preserved") = Prop.forAll { (s: String) =>
177
s.reverse.length == s.length
178
}
179
}
180
}
181
182
// List properties with collectors
183
def listProperties = {
184
implicit val params = Parameters().verbose
185
186
new Properties("Lists") {
187
property("append length") = Prop.forAll { (l1: List[Int], l2: List[Int]) =>
188
Prop.collect(l1.length, l2.length) {
189
(l1 ++ l2).length == l1.length + l2.length
190
}
191
}
192
193
property("reverse append") = Prop.forAll { (l1: List[Int], l2: List[Int]) =>
194
(l1 ++ l2).reverse == l2.reverse ++ l1.reverse
195
}
196
}
197
}
198
}
199
```
200
201
### ScalaCheckProperty to AsResult Conversion
202
203
Lower-priority implicit conversion for ScalaCheckProperty types (property wrappers created by specs2-scalacheck).
204
205
```scala { .api }
206
trait AsResultPropLowImplicits {
207
/**
208
* Convert any ScalaCheckProperty subtype to specs2 AsResult
209
* Handles property execution with exception safety
210
* @return AsResult instance for ScalaCheckProperty
211
*/
212
implicit def scalaCheckPropertyAsResult[S <: ScalaCheckProperty]: AsResult[S]
213
}
214
```
215
216
**Usage Examples:**
217
218
```scala
219
class PropertyWrapperSpec extends Specification with ScalaCheck { def is = s2"""
220
ScalaCheckProperty conversion examples
221
configured property $configuredProperty
222
contextualized property $contextProperty
223
collected property $collectedProperty
224
"""
225
226
// Property with fluent configuration
227
def configuredProperty = {
228
prop { (x: Int) =>
229
x + 1 > x
230
}.set(minTestsOk = 300)
231
.verbose
232
// ScalaCheckFunction1 automatically converts to Result
233
}
234
235
// Property with execution context
236
def contextProperty = {
237
var counter = 0
238
239
prop { (s: String) =>
240
s.length >= 0
241
}.before {
242
counter += 1
243
}.after {
244
println(s"Executed $counter tests")
245
}
246
// Property with context converts to Result
247
}
248
249
// Property with collectors
250
def collectedProperty = {
251
prop { (x: Int, y: Int) =>
252
x + y == y + x
253
}.collectArg1(x => if (x >= 0) "non-negative" else "negative")
254
.collectArg2(y => if (y % 2 == 0) "even" else "odd")
255
.set(minTestsOk = 100)
256
.verbose
257
// ScalaCheckFunction2 with collectors converts to Result
258
}
259
}
260
```
261
262
### Exception Safety and Error Handling
263
264
The conversion system provides comprehensive exception handling to preserve specs2's test semantics:
265
266
```scala { .api }
267
// Exception types handled during conversion:
268
case class FailureException(failure: execute.Failure) // specs2 failures -> ScalaCheck failures
269
case class SkipException(skipped: execute.Skipped) // specs2 skips -> ScalaCheck exceptions
270
case class PendingException(pending: execute.Pending) // specs2 pending -> ScalaCheck exceptions
271
case class DecoratedResultException(result: DecoratedResult[execute.Result]) // Enhanced results
272
273
// Error recovery in property execution:
274
try {
275
lazy val p = prop // Lazy evaluation prevents premature errors
276
check(p.prop, p.parameters, p.prettyFreqMap)
277
} catch {
278
case t: Throwable =>
279
// Fallback to default parameters if property access fails
280
AsResultProp.propAsResult(defaultParameters, defaultFreqMapPretty)
281
.asResult(Prop.exception(t))
282
}
283
```
284
285
### Integration with specs2 Result Types
286
287
The conversion system seamlessly maps between ScalaCheck and specs2 result types:
288
289
```scala { .api }
290
// ScalaCheck -> specs2 result mapping:
291
Test.Passed -> Success(message, details, testCount)
292
Test.Proved(args) -> Success(message with proof info, details, testCount)
293
Test.Failed(args, labels) -> Failure(message with counterexample, details, stackTrace)
294
Test.Exhausted -> Failure(message about discarded tests)
295
Test.PropException(args, ex, labels) -> Error(message, exception)
296
297
// specs2 -> ScalaCheck result mapping:
298
Success(msg, details) -> Prop.passed
299
Failure(msg, details) -> Prop.exception(FailureException(failure))
300
Error(msg, ex) -> Prop.exception(ex)
301
Skipped(reason) -> Prop.exception(SkipException(skipped))
302
Pending(reason) -> Prop.exception(PendingException(pending))
303
```
304
305
This bidirectional mapping ensures that all specs2 and ScalaCheck result semantics are preserved when converting between the two systems, allowing seamless integration in mixed testing scenarios.