0
# Property Checking
1
2
Core property checking functionality that executes ScalaCheck properties and converts results to specs2 format. The `ScalaCheckPropertyCheck` trait provides the execution engine for running properties and formatting comprehensive result reports.
3
4
## Capabilities
5
6
### Property Execution
7
8
Executes individual ScalaCheck properties with full result formatting and error handling.
9
10
```scala { .api }
11
trait ScalaCheckPropertyCheck {
12
/**
13
* Execute a ScalaCheck property and return specs2 Result
14
* @param prop - The ScalaCheck property to execute
15
* @param parameters - Test configuration parameters
16
* @param prettyFreqMap - Formatter for frequency/collector data
17
* @return specs2 Result (Success, Failure, or Error)
18
*/
19
def check(
20
prop: Prop,
21
parameters: Parameters,
22
prettyFreqMap: FreqMap[Set[Any]] => Pretty
23
): Result
24
25
/**
26
* Execute multiple related properties as a group
27
* @param properties - ScalaCheck Properties object with named properties
28
* @param parameters - Test configuration parameters
29
* @param prettyFreqMap - Formatter for frequency/collector data
30
* @return Combined specs2 Result
31
*/
32
def checkProperties(
33
properties: Properties,
34
parameters: Parameters,
35
prettyFreqMap: FreqMap[Set[Any]] => Pretty
36
): Result
37
}
38
```
39
40
**Usage Examples:**
41
42
```scala
43
import org.specs2.scalacheck.{ScalaCheckPropertyCheck, Parameters}
44
import org.scalacheck.{Prop, Properties}
45
46
class PropertyChecker extends ScalaCheckPropertyCheck {
47
48
// Execute single property
49
def runSingleProperty = {
50
val prop = Prop.forAll { (x: Int) => x + 0 == x }
51
val params = Parameters().verbose
52
val result = check(prop, params, defaultFreqMapPretty)
53
result must beSuccessful
54
}
55
56
// Execute multiple properties
57
def runMultipleProperties = {
58
val properties = new Properties("MathProps") {
59
property("addition") = Prop.forAll { (x: Int, y: Int) => x + y == y + x }
60
property("identity") = Prop.forAll { (x: Int) => x + 0 == x }
61
}
62
63
val result = checkProperties(properties, Parameters(), defaultFreqMapPretty)
64
result must beSuccessful
65
}
66
}
67
```
68
69
### Result Processing and Formatting
70
71
Comprehensive result processing that converts ScalaCheck test results into specs2 Results with proper error formatting.
72
73
```scala { .api }
74
/**
75
* Format ScalaCheck test results with custom frequency map formatting
76
* @param res - Raw ScalaCheck test result
77
* @param freqMapPretty - Formatter for frequency data
78
* @return Formatted Pretty result
79
*/
80
def prettyResult(
81
res: Test.Result,
82
freqMapPretty: FreqMap[Set[Any]] => Pretty
83
): Pretty
84
85
/**
86
* Extract and format frequency/collector information
87
* @param fq - Frequency map from test execution
88
* @param parameters - Test parameters (used for verbosity)
89
* @param prettyFreqMap - Formatter for frequency data
90
* @return Formatted frequency information string
91
*/
92
def frequencies(
93
fq: FreqMap[Set[Any]],
94
parameters: Parameters,
95
prettyFreqMap: FreqMap[Set[Any]] => Pretty
96
): String
97
98
/**
99
* Format exception cause chain for error reporting
100
* @param t - Exception to format
101
* @return Formatted cause chain string
102
*/
103
def showCause(t: Throwable): String
104
```
105
106
### Result Type Conversion
107
108
The checking process converts ScalaCheck's `Test.Result` into specs2's `Result` types with comprehensive error handling:
109
110
```scala { .api }
111
// ScalaCheck result types that are handled:
112
sealed trait Test.Status
113
case object Test.Passed // Property passed all tests
114
case class Test.Proved(args: List[Arg[Any]]) // Property was proved (not just tested)
115
case object Test.Exhausted // Too many tests were discarded
116
case class Test.Failed(args: List[Arg[Any]], labels: Set[String]) // Property failed with counterexample
117
case class Test.PropException(args: List[Arg[Any]], e: Throwable, labels: Set[String]) // Exception during testing
118
119
// Converted to specs2 result types:
120
case class Success(message: String, details: String, successCount: Int) // From Passed/Proved
121
case class Failure(message: String, details: Details = NoDetails, stackTrace: List[StackTraceElement] = Nil) // From Failed/Exhausted
122
case class Error(message: String, exception: Throwable) // From PropException with non-recoverable errors
123
case class Skipped(reason: String) // From SkipException
124
case class Pending(reason: String) // From PendingException
125
```
126
127
**Result Processing Examples:**
128
129
```scala
130
// The check method handles all ScalaCheck result types:
131
val result = check(property, parameters, prettyFreqMap)
132
133
result match {
134
case Success(msg, details, count) =>
135
println(s"Property passed $count tests: $msg")
136
137
case Failure(msg, details, trace) =>
138
println(s"Property failed: $msg")
139
if (details != NoDetails) println(s"Details: $details")
140
141
case Error(msg, exception) =>
142
println(s"Property error: $msg")
143
exception.printStackTrace()
144
145
case Skipped(reason) =>
146
println(s"Property skipped: $reason")
147
148
case Pending(reason) =>
149
println(s"Property pending: $reason")
150
}
151
```
152
153
### Exception Handling
154
155
Sophisticated exception handling that preserves specs2 test semantics while integrating ScalaCheck execution:
156
157
```scala { .api }
158
// Exception types handled specially:
159
case class FailureException(failure: execute.Failure) // specs2 test failures
160
case class DecoratedResultException(result: DecoratedResult[execute.Result]) // Enhanced results
161
case class SkipException(skipped: execute.Skipped) // Skipped tests
162
case class PendingException(pending: execute.Pending) // Pending tests
163
case class AssertionError(message: String) // JUnit-style assertions
164
case object NonFatal // Other recoverable exceptions
165
```
166
167
**Exception Handling Examples:**
168
169
```scala
170
// Property that throws specs2 failure
171
def failingProperty = prop { (x: Int) =>
172
if (x > 100) failure("Value too large")
173
else x must be_<=(100)
174
}
175
176
// Property that throws exception
177
def errorProperty = prop { (x: String) =>
178
if (x.isEmpty) throw new IllegalArgumentException("Empty string")
179
else x.length must be_>(0)
180
}
181
182
// Property that skips conditionally
183
def skippingProperty = prop { (x: Double) =>
184
if (x.isNaN) skipped("NaN values not supported")
185
else x + 0.0 must_== x
186
}
187
```
188
189
### Frequency Map and Collector Support
190
191
Integration with ScalaCheck's collector system for gathering and displaying test data distributions:
192
193
```scala { .api }
194
/**
195
* Default frequency map formatter that removes failure details
196
* and formats collected values for display
197
*/
198
def defaultFreqMapPretty: FreqMap[Set[Any]] => Pretty = (fq: FreqMap[Set[Any]]) =>
199
Pretty.prettyFreqMap(removeDetails(fq))
200
201
// Example collector usage in properties:
202
def collectorProperty = prop { (x: Int) =>
203
x + 0 == x
204
}.collectArg(x => if (x >= 0) "positive" else "negative")
205
.set(minTestsOk = 200)
206
.verbose // Enable display of frequency information
207
```
208
209
**Collector Output Example:**
210
211
```
212
OK, passed 200 tests.
213
> Collected test data:
214
positive: 62% (124/200)
215
negative: 38% (76/200)
216
```
217
218
### Property Grouping and Organization
219
220
Support for organizing related properties using ScalaCheck's `Properties` class:
221
222
```scala { .api }
223
// Creating grouped properties
224
class MathProperties extends Properties("Math") {
225
property("commutative addition") = Prop.forAll { (x: Int, y: Int) =>
226
x + y == y + x
227
}
228
229
property("associative addition") = Prop.forAll { (x: Int, y: Int, z: Int) =>
230
(x + y) + z == x + (y + z)
231
}
232
233
property("additive identity") = Prop.forAll { (x: Int) =>
234
x + 0 == x && 0 + x == x
235
}
236
}
237
238
// Executing grouped properties
239
def testMathProperties = {
240
val mathProps = new MathProperties
241
checkProperties(mathProps, Parameters().verbose, defaultFreqMapPretty)
242
}
243
```
244
245
This produces organized output showing results for each named property within the group, making it easier to identify which specific properties pass or fail within a larger test suite.