Combining properties

Until now, we were talking about single, isolated properties. Sometimes, it is useful, or even required, to make sure that some combination of properties holds. For instance, we might want to define a property which holds if and only if all other properties hold. Or we might want to have a property which is true if at least one property from a set of properties is true. There are combination methods defined on Prop exactly for such use cases. The result is just another property which can be checked the same way we already did:

    forAll { (a: Int, b: Int, c: Int, d: String) =>
val multiplicationLaws = all(
"Commutativity" |: (a * b ?= b * a),
"Associativity" |: ((a * b) * c ?= a * (b * c)),
"Identity" |: all(a * 1 ?= a, 1 * a ?= a)
) :| "Multiplication laws"
val stringProps = atLeastOne(d.isEmpty, d.nonEmpty)
all(multiplicationLaws, stringProps)
}.check()

+ OK, passed 100 tests.

This is a nested combination of properties. The topmost one holds if both multiplicationLaws and stringProps hold. The stringProps verifies that any String is either empty or non-empty; only one of these properties can be true at the same time. For multiplicationLaws, all nested properties must hold.

There are also more specific combinators, for example someFailing and noneFailing which hold in the case if some underlying properties are failing or none are failing respectively. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.227.4