Unlock This Episode
Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.
Introduction
So what we are seeing is that we put in a lot of upfront work with Decodable
, and got some impressive results out it because we can effortlessly generate a random value from pretty much any data type we define. However, the system is very rigid and will mostly create invalid values for your domain, like email addresses and positive user ids.
Maybe there’s another way. We saw last time that our Gen
type was able to do things that the Swift 4.2 randomness APIs were not capable of, so maybe it can help us out again?
Subscribe to Point-Free
Access this episode, plus all past and future episodes when you become a subscriber.
Already a subscriber? Log in
Exercises
Redefine
Gen
‘s base unit of randomness,random
, which is aGen<UInt32>
to work with Swift 4.2’s base unit of randomness, theRandomNumberGenerator
protocol. The base random type should should change toUInt64
.Swift 4.2’s protocol-oriented solution allows us to define custom types that conform to
RandomNumberGenerator
. UpdateGen
to evaluate given anyRandomNumberGenerator
by changingrun
’s signature.Use a custom random number generator that can be configured with a stable seed to allow for the
Gen
type to predictably generate the same random value for a given seed.You can look to Nate Cook’s playground, shared on the Swift forums, or (for bonus points), you can define your own linear congruential generator (or LCG).
Write a helper that runs a property test for
XCTest
! A property test, given a generator and a block of code, will evaluate the block of code with a configurable number of random runs. If the block returnstrue
, the property test passes. It it returnsfalse
, it fails. The signature should be the following.func forAll<A>(_ a: Gen<A>, propertyShouldHold: (A) -> Bool)
It should, internally, call an
XCTAssert
function. Upon failure, print out the seed so that it can be reproduced.Enhance the
forAll
API to takefile: StaticString = #file, line: UInt = #line
, which can be passed to XCTest in order to highlight the correct line on failure.