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
= do
spec "myBoolLens" $
describe -- For any unchecked value, prefer this version if you can.
lensSpec myBoolLens "myRationalLens" $
describe -- Only for valid values lensSpecOnValid myRationalLens
Running the test suite gets you pretty output as follows:
myBoolLens satisfies the first lens law for unchecked values and unchecked values satisfies the second lens law for unchecked values satisfies the third lens law for unchecked values and unchecked values gets valid values from unchecked values values produces valid values when it is used to set unchecked values values on unchecked values values myRationalLens satisfies the first lens law for valid values and valid values satisfies the second lens law for valid values satisfies the third lens law for valid values and valid values gets valid values from unchecked values values produces valid values when it is used to set unchecked values values on unchecked values values