Releases: typelift/SwiftCheck
We Gon' Be Alright
- Fixes an issue where 32-bit devices could cause the random number generator to crash with an overflow exception.
- Compile times for the entire framework have been significantly improved (h/t @robrix)
Pines of the Ap'ian way
This release fixes a major issue caused by <*>
not re-jiggering its generators. This could cause tests in the previous release (v0.4.0) that use the same call in the traditional applicative form to generate the same values in many cases (h/t @QF5690 for the report).
As a consequence, generators for all types are now significantly more robust and have instances rewritten and optimized for the new deterministic RNG.
Reproductive Rights
SwiftCheck now has a new in-library pseudo-RNG that enables tests to be replayed argument-for-argument with just two seed values.
For example, given this property:
property("Obviously wrong") <- forAll { (x : Int, y : Int, c : Int) in (x > y) ==> x + c < y + c }
SwiftCheck takes care of printing all the nitty-gritty details.
So all you have to do is feed those values back into the testing loop:
let (seedl, seedr) = (618383975, 8314)
let replayArgs = CheckerArguments(replay: .Some(StdGen(seedl, seedr), 1))
property("Obviously wrong", arguments: replayArgs) <- forAll { (x : Int, y : Int, c : Int) in (x > y) ==> x + c < y + c }.verbose
In addition, this release comes with a number of bug fixes and improvements:
- SwiftCheck now uses the
@exported
attribute withXCTest
so you can justimport SwiftCheck
without needing toimport XCTest
. - Test cases that throw exceptions now also print counterexamples. Whoops!
- The
CheckerArguments
structure is now easier to create and use (h/t @kballard). - The
StdGen
structure is now public.
Exceptionally Gifted
With this release, all functions now catch exceptions thrown inside their respective testing blocks.
Naturally, a thrown exception is treated as an automatic failure of the test case. If you wish to treat it as a passing case, see Property.invert
and Property.expectFailure
.
We've also added support for the existential quantifier exists
in addition to the universal forAll
.
Operational Semantics
- Updates operators to maintain compatibility with popular frameworks.
Check Your Privilege
Good News Everyone!
SwiftCheck now fully supports Swift 2.0. Other changes include:
- The syntax for testing has changed slightly.
property["Numa Numa"] = forAll { //... }
now becomes
property("Numa Numa") <- forAll { //... }
- We have a shiny new tutorial playground where you can explore SwiftCheck to your heart's content.
- Support for tvOS has been added!
- Handling of signs in signed integer generation has been fixed (h/t @brentleyjones).
- SwiftCheck is now fully integrated with XCTest. Failures will display on the properties and lines that caused them.
- You get an
Arbitrary
instance, and you get anArbitrary
instance. Everybody gets anArbitrary
instance! - Those classes and structures that could not be made
Arbitrary
now haveArbitrary
-like extensions for use withforAllShrink
. - The
WitnessedArbitrary
protocol has been added for higher-order types like[Arbitrary]
andSet<Arbitrary>
. - The
IsoOf
modifier has been added. It works likeArrowOf
, but in 2 directions instead of just 1. - Operators have been split into their own package and standardized across TypeLift.
shrink
is now an optional requirement for anArbitrary
instance. If none is provided, SwiftCheck will assume you don't want to shrink at all.conjamb
, the non-deterministic conjunction combinator, has been added.- The
Large
modifier has been added. It allows integers to be generated in their entire range rather than be bounded by their Generator's size. - Arguments that modify the testing loop can now be passed in a
property
call.
// Re-checks all tests with this generator and size.
let args = CheckerArguments( replay: Optional.Some((newStdGen(), 10))
// Doubles the required number of tests to pass
, maxAllowableSuccessfulTests: 200
// We can no longer discard.
, maxAllowableDiscardedTests: 0
// 10x the default size of the test case.
, maxTestCaseSize: 1000
)
property("Discards forbidden", arguments: args) <- forAll { (x : UInt) in
return Discard()
}.expectFailure
Lazy Sunday
- Makes the postcondition for
==>
(Implication) lazy.
The Last Arrow Bender
ArrowOf
now memoizes its arguments and behaves like a proper function.- Many more types have
CoArbitrary
instances so they can be used withArrowOf
.
Recursion: See Recursion
- Adds a new combinator,
Gen.weighted
. It's like frequency but doesn't require so manyGen.pure
calls. - The constraints on
Gen.frequency
andGen.weighted
are now relaxed to allow anySequenceType
- The shrinker loop is thinner, quicker, and much much less memory hungry than before for complex shrinks.
- Fixes a bug in the shrinker where tests would not report the number of shrinks they'd gone through.
- Propagates expected failures and outputs the correct
Result
type for them. - Compile times have been significantly improved for some files (h/t @robrix).
10x Property Testing
- Fixed iOS deployment target [and therefore the Carthage build]
- Introduced 4 new operators to make complex testing possible (
==>
,====
,<?>
,^&&^
,^||^
; Implication, Verbose Equality, Conjunction, Disjunction) - Generator Combinators are now static methods instead of top-level functions.
- Numerous internal fixes to the testing loop
- Removal of extraneous methods and data structures.
- Array shrinks now consume less memory and complete much faster
- Documentation has been added to every user-facing method
forAllShrink(_:_:_:)
has a relaxed generic parameter for easier integration with custom testing- Verbose checks are now possible. Using verbose checks, SwiftCheck will dump all test cases to console with the result of each test.
- When labelling properties, SwiftCheck will output a distribution graph of the percentage of passing test cases a property has gone through.
- Conjunct and Disjunct properties used with labelling will report distribution graphs for each individual property