This post announces the new genvalidity-hspec-optics test-suite combinator library. It is a new companion package for genvalidity-hspec and contains test-suite combinators for testing optics.

Background

Lenses, as specified in Control.Lens.Lens have laws. They are specified as follows:

Law 1: You get back what you put in:

view l (set l v s) == v

Law 2: Putting back what you got does not change anything:

set l (view l s) s == s

Law 3: Setting twice is the same as setting once:

set l v' (set l v s) = set l v' s

Contents

The new genvalidity-hspec-optics library has the following test-suite combinators for lenses:

lensSpec: A test suite combinator for the lens laws of a lens, for unchecked values.

lensSpecOnValid: A test suite combinator for the lens laws of a lens, for valid values.

lensSpecOnArbitrary: A test suite combinator for the lens laws of a lens, for arbitrary values.

lensSpecOnGen: A test suite combinator for the lens laws of a lens, for values generated by custom generators.

That means that now you can test whether your lenses follow the lens laws with a single line of code.

Example

Suppose you have a simple record, with two fields and two corresponding lenses:

data MyRecord = MyRecord { myBool :: Bool , myRational :: Rational } myBoolLens :: Lens' MyRecord Bool myRationalLens :: Lens' MyRecord Rational

Now you can write a very simple property test suite using genvalidity-hspec-optics that test whether the lenses follow the lens laws, and are otherwise sensible.

import Test.Validity.Optics spec :: Spec spec = do describe "myBoolLens" $ lensSpec myBoolLens -- For any unchecked value, prefer this version if you can. describe "myRationalLens" $ lensSpecOnValid myRationalLens -- Only for valid values

Running the test suite gets you pretty output as follows: