diff --git a/registry-hedgehog.cabal b/registry-hedgehog.cabal
--- a/registry-hedgehog.cabal
+++ b/registry-hedgehog.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.2.
+-- This file has been generated from package.yaml by hpack version 0.33.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 8e9ef405c71b1f7fffa4735a082d31c503420e8345fd885ef0408becd6689cc4
+-- hash: 5172e9a2dee2ae8064a8ddd51dbad2923b92ace8e8141381ba7b40be413c7bdb
 
 name:           registry-hedgehog
-version:        0.2.1.1
+version:        0.3.0.0
 synopsis:       utilities to work with Hedgehog generators and `registry`
 description:    This library provides some functions to extract generators from a "Registry" and make stateful modifications of that Registry to precisely control the generation of data
 category:       Control
@@ -26,6 +26,7 @@
       Data.Registry.Hedgehog.TH
       Data.Registry.Internal.Hedgehog
       Data.Registry.Internal.TH
+      Test.Tasty.HedgehogTest
       Test.Tasty.Hedgehogx
   other-modules:
       Paths_registry_hedgehog
diff --git a/src/Data/Registry/Hedgehog.hs b/src/Data/Registry/Hedgehog.hs
--- a/src/Data/Registry/Hedgehog.hs
+++ b/src/Data/Registry/Hedgehog.hs
@@ -1,167 +1,163 @@
-{-# LANGUAGE AllowAmbiguousTypes   #-}
-{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE PartialTypeSignatures #-}
-{-# LANGUAGE UndecidableInstances  #-}
-
-module Data.Registry.Hedgehog (
-  -- creation / tweaking functions
-  GenIO
-, Chooser (..)
-, forallS
-, forAllT -- re-export of forAllT for convenience purpose since we are working in GenIO
-, filterGenS
-, genFun
-, genVal
-, genWith
-, modifyGenS
-, setGen
-, setGenIO
-, setGenS
-, specializeGen
-, specializeGenIO
-, specializeGenS
-, tweakGen
-, tweakGenS
-, makeNonEmpty
-, makeNonEmptyS
-
--- combinators to compose different types of generators
-, eitherOf
-, hashMapOf
-, listOf
-, listOfMinMax
-, mapOf
-, maybeOf
-, nonEmptyMapOf
-, nonEmptyOf
-, pairOf
-, setOf
-, tripleOf
-
--- cycling values
-, choiceChooser
-, chooseOne
-, setCycleChooser
-, setCycleChooserS
-
--- making distinct values
-, distinct
-, setDistinct
-, setDistinctFor
-, setDistinctForS
-, setDistinctS
+{-# LANGUAGE UndecidableInstances #-}
 
--- sampling for GenIO generators
-, sampleIO
-) where
+module Data.Registry.Hedgehog
+  ( -- creation / tweaking functions
+    GenIO,
+    Chooser (..),
+    forallS,
+    forAllT, -- re-export of forAllT for convenience purpose since we are working in GenIO
+    filterGenS,
+    genFun,
+    genVal,
+    genWith,
+    modifyGenS,
+    setGen,
+    setGenIO,
+    setGenS,
+    specializeGen,
+    specializeGenIO,
+    specializeGenS,
+    tweakGen,
+    tweakGenS,
+    makeNonEmpty,
+    makeNonEmptyS,
+    -- combinators to compose different types of generators
+    eitherOf,
+    hashMapOf,
+    listOf,
+    listOfMinMax,
+    mapOf,
+    maybeOf,
+    nonEmptyMapOf,
+    nonEmptyOf,
+    pairOf,
+    setOf,
+    tripleOf,
+    -- cycling values
+    choiceChooser,
+    chooseOne,
+    setCycleChooser,
+    setCycleChooserS,
+    -- making distinct values
+    distinct,
+    setDistinct,
+    setDistinctFor,
+    setDistinctForS,
+    setDistinctS,
+    -- sampling for GenIO generators
+    sampleIO,
+  )
+where
 
-import           Control.Monad.Morph
-import           Data.HashMap.Strict             as HashMap (HashMap, fromList)
-import           Data.IORef
-import           Data.List.NonEmpty              hiding (cycle, nonEmpty, (!!))
-import           Data.Map                        as Map (fromList)
-import           Data.Maybe                      as Maybe
-import           Data.Registry
-import           Data.Registry.Internal.Hedgehog
-import           Data.Registry.Internal.Types
-import           Data.Set                        as Set (fromList)
-import           Hedgehog
-import           Hedgehog.Gen                    as Gen
-import           Hedgehog.Internal.Gen           as Gen
-import           Hedgehog.Internal.Property      (forAllT)
-import           Hedgehog.Range
-import           Protolude                       as P
-import           System.IO.Unsafe
+import Control.Monad.Morph
+import Data.HashMap.Strict as HashMap (HashMap, fromList)
+import Data.IORef
+import Data.List.NonEmpty hiding (cycle, nonEmpty, (!!))
+import Data.Map as Map (fromList)
+import Data.Maybe as Maybe
+import Data.Registry
+import Data.Registry.Internal.Hedgehog
+import Data.Registry.Internal.Types
+import Data.Set as Set (fromList)
+import Hedgehog
+import Hedgehog.Gen as Gen
+import Hedgehog.Internal.Property (forAllT)
+import Hedgehog.Range
+import Protolude as P
+import System.IO.Unsafe
 
 -- * CREATION / TWEAKING OF REGISTRY GENERATORS
 
 -- | Create a GenIO a for a given constructor of type a
-genFun :: forall a b . (ApplyVariadic GenIO a b, Typeable a, Typeable b) => a -> Typed b
+genFun :: forall a b. (ApplyVariadic GenIO a b, Typeable a, Typeable b) => a -> Typed b
 genFun = funTo @GenIO
 
 -- | Lift a Gen a into GenIO a to be added to a registry
-genVal :: forall a . (Typeable a) => Gen a -> Typed (GenIO a)
+genVal :: forall a. (Typeable a) => Gen a -> Typed (GenIO a)
 genVal g = fun (liftGen g)
 
 -- | Extract a generator from a registry
 --   We use makeUnsafe assuming that the registry has been checked before
-genWith :: forall a ins out . (Typeable a) => Registry ins out -> GenIO a
+genWith :: forall a ins out. (Typeable a) => Registry ins out -> GenIO a
 genWith = makeUnsafe @(GenIO a)
 
 -- | Modify the value of a generator in a given registry
-tweakGen :: forall a ins out . (Typeable a) => (a -> a) -> Registry ins out -> Registry ins out
+tweakGen :: forall a ins out. (Typeable a) => (a -> a) -> Registry ins out -> Registry ins out
 tweakGen f = tweakUnsafe @(GenIO a) (\genA -> f <$> genA)
 
 -- | Modify the registry for a given generator in a State monad
-tweakGenS :: forall a m ins out . (Typeable a, MonadState (Registry ins out) m) => (a -> a) -> m ()
+tweakGenS :: forall a m ins out. (Typeable a, MonadState (Registry ins out) m) => (a -> a) -> m ()
 tweakGenS f = modify (tweakGen f)
 
 -- | Set a specific generator on the registry the value of a generator in a given registry
-setGen :: forall a ins out . (Typeable a) => Gen a -> Registry ins out -> Registry ins out
+setGen :: forall a ins out. (Typeable a) => Gen a -> Registry ins out -> Registry ins out
 setGen = setGenIO . liftGen
 
-setGenIO :: forall a ins out . (Typeable a) => GenIO a -> Registry ins out -> Registry ins out
+setGenIO :: forall a ins out. (Typeable a) => GenIO a -> Registry ins out -> Registry ins out
 setGenIO genA = tweakUnsafe @(GenIO a) (const genA)
 
 -- | Set a specific generator on the registry the value of a generator in a given registry in a State monad
-setGenS :: forall a m ins out . (Typeable a, MonadState (Registry ins out) m) => Gen a -> m ()
+setGenS :: forall a m ins out. (Typeable a, MonadState (Registry ins out) m) => Gen a -> m ()
 setGenS genA = modify (setGen genA)
 
 -- | Specialize a generator in a given context
-specializeGen :: forall a b ins out . (Typeable a, Typeable b, Contains (GenIO a) out) => Gen b -> Registry ins out -> Registry ins out
+specializeGen :: forall a b ins out. (Typeable a, Typeable b, Contains (GenIO a) out) => Gen b -> Registry ins out -> Registry ins out
 specializeGen g = specializeGenIO @a (liftGen g)
 
 -- | Specialize a generator in a given context
-specializeGenIO :: forall a b ins out . (Typeable a, Typeable b, Contains (GenIO a) out) => GenIO b -> Registry ins out -> Registry ins out
+specializeGenIO :: forall a b ins out. (Typeable a, Typeable b, Contains (GenIO a) out) => GenIO b -> Registry ins out -> Registry ins out
 specializeGenIO = specialize @(GenIO a)
 
 -- | Specialize a generator in a given context
-specializeGenS :: forall a b m ins out . (Typeable a, Typeable b, Contains (GenIO a) out, MonadState (Registry ins out) m) => Gen b -> m ()
+specializeGenS :: forall a b m ins out. (Typeable a, Typeable b, Contains (GenIO a) out, MonadState (Registry ins out) m) => Gen b -> m ()
 specializeGenS g = modify (specializeGen @a @b g)
 
 -- | Modify a generator
-modifyGenS :: forall a ins out . (Typeable a) => (GenIO a -> GenIO a) -> PropertyT (StateT (Registry ins out) IO) ()
+modifyGenS :: forall a ins out. (Typeable a) => (GenIO a -> GenIO a) -> PropertyT (StateT (Registry ins out) IO) ()
 modifyGenS f = modify (tweakUnsafe @(GenIO a) f)
 
 -- | Filter a generator
-filterGenS :: forall a ins out . (Typeable a) => (a -> Bool) -> PropertyT (StateT (Registry ins out) IO) ()
+filterGenS :: forall a ins out. (Typeable a) => (a -> Bool) -> PropertyT (StateT (Registry ins out) IO) ()
 filterGenS = modifyGenS . Gen.filterT
 
 -- | Get a value generated from one of the generators in the registry and modify the registry
 --   using a state monad
-forallS :: forall a m out . (Typeable a, Show a, MonadIO m) => PropertyT (StateT (Registry _ out) m) a
+forallS :: forall a m out. (Typeable a, Show a, MonadIO m) => PropertyT (StateT (Registry _ out) m) a
 forallS = do
   r <- P.lift $ get
   withFrozenCallStack $ hoist liftIO $ forAllT (genWith @a r)
 
 -- | Make sure there is always one element of a given type in a list of elements
-makeNonEmpty :: forall a ins out . (Typeable a) => Registry ins out -> Registry ins out
+makeNonEmpty :: forall a ins out. (Typeable a) => Registry ins out -> Registry ins out
 makeNonEmpty r =
   -- extract a generator for one element only
   let genA = genWith @a r
-  -- add that element in front of a list of generated elements
-  in  tweakUnsafe @(GenIO [a]) (\genAs -> (:) <$> genA <*> genAs) r
+   in -- add that element in front of a list of generated elements
+      tweakUnsafe @(GenIO [a]) (\genAs -> (:) <$> genA <*> genAs) r
 
 -- | Make sure there is always one element of a given type in a list of elements in a State monad
-makeNonEmptyS :: forall a m ins out . (Typeable a, MonadState (Registry ins out) m) => m ()
+makeNonEmptyS :: forall a m ins out. (Typeable a, MonadState (Registry ins out) m) => m ()
 makeNonEmptyS = modify (makeNonEmpty @a)
 
 -- * CONTAINERS COMBINATORS
 
 -- | Create a generator for a pair
-pairOf :: forall a b . GenIO a -> GenIO b -> GenIO (a, b)
+pairOf :: forall a b. GenIO a -> GenIO b -> GenIO (a, b)
 pairOf ga gb = (,) <$> ga <*> gb
 
 -- | Create a generator for a triple
-tripleOf :: forall a b c . GenIO a -> GenIO b -> GenIO c -> GenIO (a, b, c)
+tripleOf :: forall a b c. GenIO a -> GenIO b -> GenIO c -> GenIO (a, b, c)
 tripleOf ga gb gc = (,,) <$> ga <*> gb <*> gc
 
 -- | Create a default generator for a small list of elements
-listOf :: forall a . GenIO a -> GenIO [a]
+listOf :: forall a. GenIO a -> GenIO [a]
 listOf = Gen.list (linear 0 10)
 
 -- | Create a default generator for a list of elements of min elements and max elements
-listOfMinMax :: forall a . Int -> Int -> GenIO a -> GenIO [a]
+listOfMinMax :: forall a. Int -> Int -> GenIO a -> GenIO [a]
 listOfMinMax min' max' = Gen.list (linear min' max')
 
 -- | Create a default generator for a small non-empty list of elements
@@ -169,27 +165,27 @@
 nonEmptyOf = Gen.nonEmpty (linear 1 10)
 
 -- | Create a default generator for a Maybe, choosing evenly between Nothing and Just
-maybeOf :: forall a . GenIO a -> GenIO (Maybe a)
+maybeOf :: forall a. GenIO a -> GenIO (Maybe a)
 maybeOf genA = choice [pure Nothing, Just <$> genA]
 
 -- | Create a default generator for a Either, choosing evenly between Left and Right
-eitherOf :: forall a b . GenIO a -> GenIO b -> GenIO (Either a b)
+eitherOf :: forall a b. GenIO a -> GenIO b -> GenIO (Either a b)
 eitherOf genA genB = choice [Left <$> genA, Right <$> genB]
 
 -- | Create a default generator for a small set of elements
-setOf :: forall a . (Ord a) => GenIO a -> GenIO (Set a)
+setOf :: forall a. (Ord a) => GenIO a -> GenIO (Set a)
 setOf = fmap Set.fromList . listOf
 
 -- | Create a default generator for map of key/values
-mapOf :: forall k v . (Ord k) => GenIO k -> GenIO v -> GenIO (Map k v)
+mapOf :: forall k v. (Ord k) => GenIO k -> GenIO v -> GenIO (Map k v)
 mapOf gk gv = Map.fromList <$> listOf (pairOf gk gv)
 
 -- | Create a default generator for HashMap of key/values
-hashMapOf :: forall k v . (Ord k, Hashable k) => GenIO k -> GenIO v -> GenIO (HashMap k v)
+hashMapOf :: forall k v. (Ord k, Hashable k) => GenIO k -> GenIO v -> GenIO (HashMap k v)
 hashMapOf gk gv = HashMap.fromList <$> listOf (pairOf gk gv)
 
 -- | Create a default generator for a small non-empty map of elements
-nonEmptyMapOf :: forall k v . (Ord k) => GenIO k -> GenIO v -> GenIO (Map k v)
+nonEmptyMapOf :: forall k v. (Ord k) => GenIO k -> GenIO v -> GenIO (Map k v)
 nonEmptyMapOf gk gv = do
   h <- pairOf gk gv
   t <- listOf (pairOf gk gv)
@@ -201,17 +197,18 @@
 
 -- | Set a cycling chooser for a specific data type
 {-# NOINLINE setCycleChooser #-}
-setCycleChooser :: forall a ins out . (Typeable a, Contains (GenIO a) out) => Registry ins out -> Registry ins out
+setCycleChooser :: forall a ins out. (Typeable a, Contains (GenIO a) out) => Registry ins out -> Registry ins out
 setCycleChooser r = unsafePerformIO $ do
   c <- cycleChooser
   pure $ specializeValTo @GenIO @(GenIO a) c r
 
 -- | Set a cycling chooser for a specific data type
 {-# NOINLINE setCycleChooserS #-}
-setCycleChooserS :: forall a m ins out . (Typeable a, Contains (GenIO a) out, MonadState (Registry ins out) m, MonadIO m) => m ()
+setCycleChooserS :: forall a m ins out. (Typeable a, Contains (GenIO a) out, MonadState (Registry ins out) m, MonadIO m) => m ()
 setCycleChooserS =
   let c = unsafePerformIO cycleChooser
-  in do r <- get
+   in do
+        r <- get
         let r' = specializeValTo @GenIO @(GenIO a) c r
         put r'
 
@@ -219,30 +216,30 @@
 
 -- | Generate distinct values for a specific data type
 {-# NOINLINE setDistinct #-}
-setDistinct :: forall a ins out . (Eq a, Typeable a, Contains (GenIO a) out) => Registry ins out -> Registry ins out
+setDistinct :: forall a ins out. (Eq a, Typeable a, Contains (GenIO a) out) => Registry ins out -> Registry ins out
 setDistinct = setDistinctWithRef @a (unsafePerformIO $ newIORef [])
 
-setDistinctWithRef :: forall a ins out . (Eq a, Typeable a, Contains (GenIO a) out) => IORef [a] -> Registry ins out -> Registry ins out
+setDistinctWithRef :: forall a ins out. (Eq a, Typeable a, Contains (GenIO a) out) => IORef [a] -> Registry ins out -> Registry ins out
 setDistinctWithRef ref r = setGenIO (distinctWith ref (makeFast @(GenIO a) r)) r
 
 -- | Generate distinct values for a specific data type
 {-# NOINLINE setDistinctS #-}
-setDistinctS :: forall a m ins out . (Eq a, Typeable a, Contains (GenIO a) out, MonadState (Registry ins out) m, MonadIO m) => m ()
+setDistinctS :: forall a m ins out. (Eq a, Typeable a, Contains (GenIO a) out, MonadState (Registry ins out) m, MonadIO m) => m ()
 setDistinctS =
   let ref = unsafePerformIO $ newIORef []
-  in  modify (setDistinctWithRef @a ref)
+   in modify (setDistinctWithRef @a ref)
 
 -- | Generate distinct values for a specific data type, when used inside another data type
 {-# NOINLINE setDistinctFor #-}
-setDistinctFor :: forall a b ins out . (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out) => Registry ins out -> Registry ins out
+setDistinctFor :: forall a b ins out. (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out) => Registry ins out -> Registry ins out
 setDistinctFor = setDistinctForWithRef @a @b (unsafePerformIO $ newIORef [])
 
-setDistinctForWithRef :: forall a b ins out . (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out) => IORef [b] -> Registry ins out -> Registry ins out
+setDistinctForWithRef :: forall a b ins out. (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out) => IORef [b] -> Registry ins out -> Registry ins out
 setDistinctForWithRef ref r = specializeGenIO @a (distinctWith ref (makeFast @(GenIO b) r)) r
 
 -- | Generate distinct values for a specific data type, when used inside another data type
 {-# NOINLINE setDistinctForS #-}
-setDistinctForS :: forall a b m ins out . (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out, MonadState (Registry ins out) m, MonadIO m) => m ()
+setDistinctForS :: forall a b m ins out. (Typeable a, Contains (GenIO a) out, Eq b, Typeable b, Contains (GenIO b) out, MonadState (Registry ins out) m, MonadIO m) => m ()
 setDistinctForS =
   let ref = unsafePerformIO $ newIORef []
-  in  modify (setDistinctForWithRef @a @b ref)
+   in modify (setDistinctForWithRef @a @b ref)
diff --git a/src/Data/Registry/Hedgehog/TH.hs b/src/Data/Registry/Hedgehog/TH.hs
--- a/src/Data/Registry/Hedgehog/TH.hs
+++ b/src/Data/Registry/Hedgehog/TH.hs
@@ -1,14 +1,14 @@
-{-# LANGUAGE DataKinds       #-}
-{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
 
 module Data.Registry.Hedgehog.TH where
 
-import           Control.Monad.Fail              (fail)
-import           Data.Registry.Internal.TH
-import           Language.Haskell.TH
-import           Language.Haskell.TH.Syntax
-import           Protolude
+import Control.Monad.Fail (fail)
+import Data.Registry.Internal.TH
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax
+import Protolude
 
 -- | Make a registry containing generators for an ADT
 --   We  want to generate the following
@@ -19,7 +19,6 @@
 --
 -- genEmployeeStatus :: GenIO Chooser -> GenIO (Tag "permanent" EmployeeStatus) -> GenIO (Tag "temporary" EmployeeStatus) -> GenIO EmployeeStatus
 -- genEmployeeStatus chooser g1 g2 = chooseOne chooser [fmap unTagg1, fmap unTag g2]
---
 makeGenerators :: Name -> ExpQ
 makeGenerators genType = do
   info <- reify genType
@@ -28,7 +27,6 @@
       selector <- makeSelectGenerator name constructors
       generators <- traverse makeConstructorGenerator constructors
       assembleGeneratorsToRegistry selector generators
-
     other -> do
       qReport True ("can only create generators for an ADT, got: " <> show other)
       fail "generators creation failed"
diff --git a/src/Data/Registry/Internal/Hedgehog.hs b/src/Data/Registry/Internal/Hedgehog.hs
--- a/src/Data/Registry/Internal/Hedgehog.hs
+++ b/src/Data/Registry/Internal/Hedgehog.hs
@@ -1,35 +1,33 @@
-{-# LANGUAGE AllowAmbiguousTypes   #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE PartialTypeSignatures #-}
 
-module Data.Registry.Internal.Hedgehog (
-  GenIO
-, Chooser (..)
-
--- cycling values
-, cycleWith
-, chooseOne
-, choiceChooser
-, cycleChooser
-
--- making distinct values
-, distinct
-, distinctWith
-
--- utilities
-, liftGen
-, sampleIO
-) where
+module Data.Registry.Internal.Hedgehog
+  ( GenIO,
+    Chooser (..),
+    -- cycling values
+    cycleWith,
+    chooseOne,
+    choiceChooser,
+    cycleChooser,
+    -- making distinct values
+    distinct,
+    distinctWith,
+    -- utilities
+    liftGen,
+    sampleIO,
+  )
+where
 
-import           Control.Monad.Morph
-import           Data.IORef
-import           Data.Maybe             as Maybe
-import           Hedgehog
-import           Hedgehog.Gen           as Gen
-import           Hedgehog.Internal.Gen  as Gen
-import           Hedgehog.Internal.Seed as Seed (random)
-import           Hedgehog.Internal.Tree as Tree (NodeT (..), runTreeT)
-import           Prelude                (show, (!!))
-import           Protolude              as P
+import Control.Monad.Morph
+import Data.IORef
+import Data.Maybe as Maybe
+import Hedgehog
+import Hedgehog.Gen as Gen
+import Hedgehog.Internal.Gen as Gen
+import Hedgehog.Internal.Seed as Seed (random)
+import Hedgehog.Internal.Tree as Tree (NodeT (..), runTreeT)
+import Protolude as P
+import Prelude (show, (!!))
 
 -- | All the generators we use are lifted into GenIO to allow some generators to be stateful
 type GenIO = GenT IO
@@ -49,21 +47,21 @@
 
 -- | Chooser for randomly selecting a generator
 choiceChooser :: Chooser
-choiceChooser = Chooser { chooserType = "choice", pickOne = pure . Gen.choice }
+choiceChooser = Chooser {chooserType = "choice", pickOne = pure . Gen.choice}
 
 -- | Chooser for deterministically choosing elements in a list
 --   by cycling over them, which requires to maintain some state about the last position
 cycleChooser :: IO Chooser
 cycleChooser = do
   ref <- newIORef 0
-  pure $ Chooser { chooserType = "cycle", pickOne = cycleWith ref }
+  pure $ Chooser {chooserType = "cycle", pickOne = cycleWith ref}
 
 -- | A "chooser" strategy
 --   The type can be used to debug specializations
-data Chooser = Chooser {
-  chooserType :: Text
-, pickOne     :: forall a . [GenIO a] -> IO (GenIO a)
-}
+data Chooser = Chooser
+  { chooserType :: Text,
+    pickOne :: forall a. [GenIO a] -> IO (GenIO a)
+  }
 
 instance Show Chooser where
   show c = toS (chooserType c)
@@ -74,8 +72,8 @@
   n <- readIORef ref
   modifyIORef ref increment
   pure (gs !! n)
-
-  where increment i = if i == P.length gs - 1 then 0 else i + 1
+  where
+    increment i = if i == P.length gs - 1 then 0 else i + 1
 
 -- * MAKING DISTINCT VALUES
 
@@ -91,7 +89,7 @@
 distinctWith ref g = GenT $ \size seed -> do
   as <- liftIO $ readIORef ref
   a <- runGenT size seed $ (Gen.filterT (not . flip elem as)) g
-  liftIO $ writeIORef ref (a:as)
+  liftIO $ writeIORef ref (a : as)
   pure a
 
 -- * UTILITIES
@@ -99,17 +97,15 @@
 -- | Sample GenIO values
 sampleIO :: GenIO a -> IO a
 sampleIO gen =
-    let
-      loop n =
-        if n <= 0 then
-          panic "Hedgehog.Gen.sample: too many discards, could not generate a sample"
-        else do
-          seed <- Seed.random
-          NodeT r _  <- runTreeT $ evalGenT 30 seed gen
-          case r of
-            Nothing ->
-              loop (n - 1)
-            Just a ->
-              pure a
-    in
-      loop (100 :: Int)
+  let loop n =
+        if n <= 0
+          then panic "Hedgehog.Gen.sample: too many discards, could not generate a sample"
+          else do
+            seed <- Seed.random
+            NodeT r _ <- runTreeT $ evalGenT 30 seed gen
+            case r of
+              Nothing ->
+                loop (n - 1)
+              Just a ->
+                pure a
+   in loop (100 :: Int)
diff --git a/src/Data/Registry/Internal/TH.hs b/src/Data/Registry/Internal/TH.hs
--- a/src/Data/Registry/Internal/TH.hs
+++ b/src/Data/Registry/Internal/TH.hs
@@ -1,30 +1,28 @@
-{-# LANGUAGE DataKinds       #-}
-{-# LANGUAGE QuasiQuotes     #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE TemplateHaskell #-}
 
 module Data.Registry.Internal.TH where
 
-import           Control.Monad.Fail              (fail)
-import           Data.Registry.Internal.Hedgehog
-import           Data.Text                       (splitOn, toLower)
-import           Language.Haskell.TH
-import           Language.Haskell.TH.Syntax
-import           Prelude                         (last)
-import           Protolude                       hiding (Type)
+import Control.Monad.Fail (fail)
+import Data.Registry.Internal.Hedgehog
+import Data.Text (splitOn, toLower)
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax
+import Protolude hiding (Type)
+import Prelude (last)
 
 -- | Create a generator for selecting between constructors of an ADT
 --   One parameter is a GenIO Chooser in order to be able to later on
 --   switch the selection strategy
 makeSelectGenerator :: Name -> [Con] -> ExpQ
 makeSelectGenerator name constructors = do
-  chooserParam <- [p| (chooser :: GenIO Chooser) |]
+  chooserParam <- [p|(chooser :: GenIO Chooser)|]
   otherParams <- traverse (parameterFor name) constructors
   untaggedGenerators <- traverse untagGenerator constructors
   expression <- appE (appE (varE (mkName "chooseOne")) (varE (mkName "chooser"))) (pure $ ListE untaggedGenerators)
   pure $ LamE (chooserParam : otherParams) expression
-
   where
-    -- | Create a parameters for the selection function
     parameterFor :: Name -> Con -> Q Pat
     parameterFor typeName constructor = do
       constructorParam <- constructorParameterName constructor
@@ -36,7 +34,7 @@
 -- AppE (AppTypeE (VarE Data.Registry.Lift.tag) (LitT (StrTyLit "permanent"))) (ConE Test.Data.Registry.Generators.Permanent)
 makeConstructorGenerator :: Con -> ExpQ
 makeConstructorGenerator constructor = do
-  constructorTag  <- tagName constructor
+  constructorTag <- tagName constructor
   constructorType <- nameOf constructor
   appE (appTypeE (varE (mkName "tag")) (litT (strTyLit (show constructorTag)))) (conE constructorType)
 
@@ -67,7 +65,7 @@
 -- | The name of a given constructor
 nameOf :: Con -> Q Name
 nameOf (NormalC n _) = pure n
-nameOf (RecC n _)    = pure n
+nameOf (RecC n _) = pure n
 nameOf other = do
   qReport True ("we can only create generators for normal constructors and records, got: " <> show other)
   fail "generators creation failed"
@@ -75,7 +73,7 @@
 -- | The list of types necessary to create a given constructor
 typesOf :: Con -> Q [Type]
 typesOf (NormalC _ types) = pure (snd <$> types)
-typesOf (RecC _ types)    = pure $ (\(_,_,t) -> t)  <$> types
+typesOf (RecC _ types) = pure $ (\(_, _, t) -> t) <$> types
 typesOf other = do
   qReport True ("we can only create generators for normal constructors and records, got: " <> show other)
   fail "generators creation failed"
@@ -86,12 +84,10 @@
 assembleGeneratorsToRegistry :: Exp -> [Exp] -> ExpQ
 assembleGeneratorsToRegistry _ [] =
   fail "generators creation failed"
-
 assembleGeneratorsToRegistry selectorGenerator [g] =
   let r = appendExpressions (genFunOf (pure g)) (funOf (pure selectorGenerator))
-  in  appendExpressions r (genFunOf (varE (mkName "choiceChooser")))
-
-assembleGeneratorsToRegistry selectorGenerator (g:gs) =
+   in appendExpressions r (genFunOf (varE (mkName "choiceChooser")))
+assembleGeneratorsToRegistry selectorGenerator (g : gs) =
   appendExpressions (genFunOf (pure g)) (assembleGeneratorsToRegistry selectorGenerator gs)
 
 appendExpressions :: ExpQ -> ExpQ -> ExpQ
diff --git a/src/Test/Tasty/HedgehogTest.hs b/src/Test/Tasty/HedgehogTest.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/HedgehogTest.hs
@@ -0,0 +1,290 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE IncoherentInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+-- |
+--
+-- This redefines the HedgehogTest from tasty-hedgehog to display
+-- color during the reporting
+module Test.Tasty.HedgehogTest
+  ( HedgehogTest (..),
+    HedgehogTestLimit (..),
+    HedgehogDiscardLimit (..),
+    HedgehogShrinkLimit (..),
+    HedgehogShrinkRetries (..),
+    HedgehogReplay (..),
+    HedgehogShowReplay (..),
+    ModuleName (..),
+    testProperty,
+    groupByModuleName,
+    getModuleName,
+  )
+where
+
+import Data.MultiMap hiding (foldr, size)
+import GHC.Stack
+import Hedgehog hiding (test, (===))
+import Hedgehog.Internal.Config (UseColor, detectColor)
+import Hedgehog.Internal.Property
+import Hedgehog.Internal.Report as Hedgehog
+import Hedgehog.Internal.Runner as Hedgehog
+import Hedgehog.Internal.Seed as Seed
+import Protolude as P hiding (empty, toList, unwords, words)
+import qualified Protolude as P
+import Test.Tasty as Tasty
+import Test.Tasty.Options as Tasty
+import Test.Tasty.Providers as Tasty
+import Test.Tasty.Runners as Tasty
+  ( TestTree (..),
+    foldSingle,
+    foldTestTree,
+    trivialFold,
+  )
+import Prelude (String, unwords, words)
+
+-- | Hedgehog Property as a Tasty Test
+data HedgehogTest = HedgehogTest Tasty.TestName Property
+  deriving (Typeable)
+
+-- | Create a 'Test' from a Hedgehog property
+testProperty :: Tasty.TestName -> Property -> Tasty.TestTree
+testProperty name prop = singleTest name (HedgehogTest name prop)
+
+instance Tasty.IsTest HedgehogTest where
+  testOptions =
+    return
+      [ Tasty.Option (Proxy :: Proxy HedgehogReplay),
+        Tasty.Option (Proxy :: Proxy HedgehogShowReplay),
+        Tasty.Option (Proxy :: Proxy HedgehogTestLimit),
+        Tasty.Option (Proxy :: Proxy HedgehogDiscardLimit),
+        Tasty.Option (Proxy :: Proxy HedgehogShrinkLimit),
+        Tasty.Option (Proxy :: Proxy HedgehogShrinkRetries)
+      ]
+
+  run opts (HedgehogTest name (Property pConfig pTest)) yieldProgress = do
+    useColor <- detectColor
+    let HedgehogReplay replay = lookupOption opts
+        HedgehogTestLimit mTests = lookupOption opts
+        HedgehogDiscardLimit mDiscards = lookupOption opts
+        HedgehogShrinkLimit mShrinks = lookupOption opts
+        HedgehogShrinkRetries mRetries = lookupOption opts
+        showReplay = lookupOption opts
+        config =
+          PropertyConfig
+            (fromMaybe (propertyDiscardLimit pConfig) mDiscards)
+            (fromMaybe (propertyShrinkLimit pConfig) mShrinks)
+            (fromMaybe (propertyShrinkRetries pConfig) mRetries)
+            (NoConfidenceTermination $ fromMaybe (propertyTestLimit pConfig) mTests)
+    randSeed <- Seed.random
+    -- if we just run one test we choose a high size (knowing that the max size is 99)
+    -- if the test fails we can turn it to a prop and let the shrinking process find a
+    -- smaller counter-example
+    let minSize = if propertyTestLimit config == 1 then 50 else 0
+    let size = P.maybe minSize fst replay
+        seed = P.maybe randSeed snd replay
+    report <- checkReport config size seed pTest (yieldProgress . reportToProgress config)
+    let resultFn =
+          if reportStatus report == OK
+            then testPassed
+            else testFailed
+    out <- reportOutput showReplay useColor name report
+    return $ resultFn out
+
+reportToProgress ::
+  PropertyConfig ->
+  Report Hedgehog.Progress ->
+  Tasty.Progress
+reportToProgress config (Report testsDone _ _ status) =
+  let TestLimit testLimit = propertyTestLimit config
+      ShrinkLimit shrinkLimit = propertyShrinkLimit config
+      ratio x y = 1.0 * fromIntegral x / fromIntegral y
+   in -- TODO add details for tests run / discarded / shrunk
+      case status of
+        Running ->
+          Tasty.Progress "Running" (ratio testsDone testLimit)
+        Shrinking fr ->
+          Tasty.Progress "Shrinking" (ratio (failureShrinks fr) shrinkLimit)
+
+reportOutput ::
+  HedgehogShowReplay ->
+  UseColor ->
+  String ->
+  Report Hedgehog.Result ->
+  IO String
+reportOutput (HedgehogShowReplay showReplay) useColor name report = do
+  s <- renderResult useColor (Just (PropertyName name)) report
+  pure $ case reportStatus report of
+    Failed fr ->
+      let size = failureSize fr
+          seed = failureSeed fr
+          replayStr =
+            if showReplay
+              then
+                "  --hedgehog-replay \""
+                  ++ show size
+                  ++ " "
+                  ++ show seed
+                  ++ "\""
+              else ""
+       in s ++ replayStr ++ "\n"
+    GaveUp ->
+      s
+    OK ->
+      -- do not report hedgehog successes because they are redundant with the Tasty report
+      -- except if there is coverage information
+      if not . P.null . P.toList . coverageLabels . reportCoverage $ report
+        then s
+        else ""
+
+propertyTestLimit :: PropertyConfig -> TestLimit
+propertyTestLimit =
+  let getTestLimit (EarlyTermination _ tests) = tests
+      getTestLimit (NoEarlyTermination _ tests) = tests
+      getTestLimit (NoConfidenceTermination tests) = tests
+   in getTestLimit . propertyTerminationCriteria
+
+-- * OPTIONS DEFINITIONS
+
+-- | The replay token to use for replaying a previous test run
+newtype HedgehogReplay = HedgehogReplay (Maybe (Size, Seed))
+  deriving (Typeable)
+
+instance IsOption HedgehogReplay where
+  defaultValue = HedgehogReplay Nothing
+
+  parseValue v = HedgehogReplay . Just <$> replay
+    where
+      -- Reads a replay token in the form "{size} {seed}"
+      replay = (,) <$> safeRead (unwords size) <*> safeRead (unwords seed)
+      (size, seed) = splitAt 2 $ words v
+
+  optionName = return "hedgehog-replay"
+
+  optionHelp = return "Replay token to use for replaying a previous test run"
+
+-- | If a test case fails, show a replay token for replaying tests
+newtype HedgehogShowReplay = HedgehogShowReplay Bool
+  deriving (Typeable)
+
+instance IsOption HedgehogShowReplay where
+  defaultValue = HedgehogShowReplay True
+
+  parseValue = fmap HedgehogShowReplay . safeRead
+
+  optionName = return "hedgehog-show-replay"
+
+  optionHelp = return "Show a replay token for replaying tests"
+
+-- | The number of successful test cases required before Hedgehog will pass a test
+newtype HedgehogTestLimit = HedgehogTestLimit (Maybe TestLimit)
+  deriving (Eq, Ord, Show, Typeable)
+
+instance IsOption HedgehogTestLimit where
+  defaultValue = HedgehogTestLimit Nothing
+
+  parseValue = fmap (HedgehogTestLimit . Just . TestLimit) . safeRead
+
+  optionName = return "hedgehog-tests"
+
+  optionHelp = return "Number of successful test cases required before Hedgehog will pass a test"
+
+-- | The number of discarded cases allowed before Hedgehog will fail a test
+newtype HedgehogDiscardLimit = HedgehogDiscardLimit (Maybe DiscardLimit)
+  deriving (Eq, Ord, Show, Typeable)
+
+instance IsOption HedgehogDiscardLimit where
+  defaultValue = HedgehogDiscardLimit Nothing
+
+  parseValue = fmap (HedgehogDiscardLimit . Just . DiscardLimit) . safeRead
+
+  optionName = return "hedgehog-discards"
+
+  optionHelp = return "Number of discarded cases allowed before Hedgehog will fail a test"
+
+-- | The number of shrinks allowed before Hedgehog will fail a test
+newtype HedgehogShrinkLimit = HedgehogShrinkLimit (Maybe ShrinkLimit)
+  deriving (Eq, Ord, Show, Typeable)
+
+instance IsOption HedgehogShrinkLimit where
+  defaultValue = HedgehogShrinkLimit Nothing
+
+  parseValue = fmap (HedgehogShrinkLimit . Just . ShrinkLimit) . safeRead
+
+  optionName = return "hedgehog-shrinks"
+
+  optionHelp = return "Number of shrinks allowed before Hedgehog will fail a test"
+
+-- | The number of times to re-run a test during shrinking
+newtype HedgehogShrinkRetries = HedgehogShrinkRetries (Maybe ShrinkRetries)
+  deriving (Eq, Ord, Show, Typeable)
+
+instance IsOption HedgehogShrinkRetries where
+  defaultValue = HedgehogShrinkRetries Nothing
+
+  parseValue = fmap (HedgehogShrinkRetries . Just . ShrinkRetries) . safeRead
+
+  optionName = return "hedgehog-retries"
+
+  optionHelp = return "Number of times to re-run a test during shrinking"
+
+-- * GROUPING
+
+-- | This allows the discovery of Hedgehog properties and their grouping by module name
+--   in the test report.
+--   Extract the ModuleName option value for a given test and
+--   group all the tests with that option into the same test group
+groupByModuleName :: TestTree -> TestTree
+groupByModuleName testTree =
+  let grouped =
+        assocs $
+          foldTestTree
+            ( trivialFold
+                { foldSingle = \os n t ->
+                    let (ModuleName aModuleName) = lookupOption os :: ModuleName
+                     in insert (toS aModuleName) (setOptionSet os $ singleTest n t) empty
+                }
+            )
+            mempty
+            testTree
+   in TestGroup "All" (uncurry TestGroup <$> grouped)
+
+-- | Option describing the current module name
+newtype ModuleName = ModuleName Text deriving (Eq, Show)
+
+-- | This option is not used on the command line, it is just used to annotate test groups
+instance IsOption ModuleName where
+  defaultValue = ModuleName "root"
+  parseValue = fmap ModuleName . safeRead
+  optionName = pure "module-name"
+  optionHelp = pure "internal option used to group tests into the same module"
+  optionCLParser = mkFlagCLParser mempty (ModuleName "root")
+
+instance (Ord k) => Semigroup (MultiMap k v) where
+  (<>) m1 m2 = fromList (toList m1 <> toList m2)
+
+instance (Ord k) => Monoid (MultiMap k v) where
+  mempty = empty
+  mappend = (<>)
+
+-- | This is unfortunate. Due to the API for `foldTestTree` in Tasty
+--   giving back the current `OptionSet` applicable to a single test
+--   it is not possible to re-set those option values on that test
+--   without listing them exhaustively. This means
+--   that if other options are set on tests in that file, they need to be
+--   added in that function
+setOptionSet :: OptionSet -> TestTree -> TestTree
+setOptionSet os =
+  localOption (lookupOption os :: HedgehogTestLimit)
+    . localOption (lookupOption os :: HedgehogShrinkLimit)
+    . localOption (lookupOption os :: HedgehogReplay)
+
+-- | Return the module name of the current callstack
+getModuleName :: HasCallStack => Prelude.String
+getModuleName =
+  case getCallStack callStack of
+    ((_, loc) : _) -> srcLocModule loc
+    _ -> "root"
diff --git a/src/Test/Tasty/Hedgehogx.hs b/src/Test/Tasty/Hedgehogx.hs
--- a/src/Test/Tasty/Hedgehogx.hs
+++ b/src/Test/Tasty/Hedgehogx.hs
@@ -1,47 +1,58 @@
-{-# LANGUAGE AllowAmbiguousTypes   #-}
-{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE RecordWildCards       #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 
 {-
 
 This module unifies property based testing with Hedgehog and one-off tests.
 
 -}
-module Test.Tasty.Hedgehogx (
-  module Hedgehog
-, module Tasty
-, gotException
-, groupByModuleName
-, minTestsOk
-, mustBe
-, noShrink
-, prop
-, run
-, runOnly
-, test
-, withSeed
-, (===)
-) where
+module Test.Tasty.Hedgehogx
+  ( module Hedgehog,
+    module Tasty,
+    module Test.Tasty.HedgehogTest,
+    -- * Tests definition
+    prop,
+    test,
+    -- * Tests settings
+    minTestsOk,
+    noShrink,
+    withSeed,
+    -- * Running tests
+    run,
+    runOnly,
+    -- * Assertions
+    gotException,
+    -- * Display
+    printDifference,
+    display,
+  )
+where
 
-import           Data.Maybe           (fromJust)
-import           Data.MultiMap        hiding (foldr)
-import           GHC.Stack
-import           Hedgehog             as Hedgehog hiding (test, (===))
-import qualified Hedgehog             as Hedgehog ((===))
-import           Hedgehog.Gen         as Hedgehog hiding (discard, print)
-import           Prelude              (String)
-import           Protolude            hiding (SrcLoc, empty, toList, (.&.))
-import           System.Environment
-import           Test.Tasty           as Tasty
-import           Test.Tasty.Hedgehog  as Tasty
-import           Test.Tasty.Options   as Tasty
-import           Test.Tasty.Providers as Tasty (singleTest)
-import           Test.Tasty.Runners   as Tasty (TestTree (..), foldSingle,
-                                                foldTestTree, trivialFold)
+import qualified Data.Text as T
+import GHC.Stack
+import Hedgehog hiding (test)
+import Hedgehog.Gen as Hedgehog hiding (discard, print)
+import Hedgehog.Internal.Config (UseColor (EnableColor))
+import Hedgehog.Internal.Property (Coverage (..), Diff (..), DiscardCount (..), ShrinkCount (..), TestCount (..))
+import Hedgehog.Internal.Report
+import Hedgehog.Internal.Show (mkValue, valueDiff)
+import Protolude hiding (SrcLoc, empty, toList, (.&.))
+import System.Environment
+import Test.Tasty as Tasty
+import Test.Tasty.HedgehogTest
+import Test.Tasty.Options as Tasty
+import Test.Tasty.Providers as Tasty (singleTest)
+import Test.Tasty.Runners as Tasty
+  ( TestTree (..),
+    foldSingle,
+    foldTestTree,
+    trivialFold,
+  )
+import Prelude (String)
 
 -- * TESTS AND PROPERTIES
 
@@ -49,141 +60,59 @@
 prop :: HasCallStack => TestName -> PropertyT IO () -> TestTree
 prop name p =
   let aModuleName = getModuleName
-  in  withFrozenCallStack . localOption (ModuleName (toS aModuleName)) $
-      testProperty name (Hedgehog.property p)
+   in withFrozenCallStack . localOption (ModuleName (toS aModuleName)) $
+        testProperty name (Hedgehog.property p)
 
 -- | Create a Tasty test from a Hedgehog property called only once
 test :: HasCallStack => TestName -> PropertyT IO () -> TestTree
 test name p = withFrozenCallStack (minTestsOk 1 . noShrink $ prop name p)
 
--- * ASSERTIONS
-
--- | Assert that an exception is thrown
-gotException :: forall a . (HasCallStack, Show a) => a -> PropertyT IO ()
-gotException a = withFrozenCallStack $ do
-  res <- liftIO (try (evaluate a) :: IO (Either SomeException a))
-  case res of
-    Left _  -> assert True
-    Right _ -> annotateShow ("excepted an exception" :: Text) >> assert False
-
-
--- | Redefinition of Hedgehog's === operator to add better source file information
---
---   It adds a link to the source file which is conforms to
---   output of GHC.Exception. See makeSourceLink
---   It also displays the actual and expected values in a compact form before
---   the pretty-printed form provided by Hedgehog
-infix 4 ===
-(===) :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m ()
-actual === expected = withFrozenCallStack $ do
-  displayActualAndExpectedValues actual expected
-  actual Hedgehog.=== expected
-
--- | An equality assertion which does not try to do a smart diffs for cases
---   where the output is too large.
-mustBe :: (MonadTest m, Eq a, Show a, HasCallStack) => a -> a -> m ()
-actual `mustBe` expected = do
-  ok <- eval (actual == expected)
-  if ok then
-    success
-  else withFrozenCallStack $ do
-    displayActualAndExpectedValues actual expected
-    failure
-
--- | Display actual and expected values as a footnote, using the Show a instance
-displayActualAndExpectedValues :: (Show a, MonadTest m, HasCallStack) => a -> a -> m ()
-displayActualAndExpectedValues actual expected =
-  withFrozenCallStack $ do
-    footnote makeSourceLink
-    footnote "\n"
-    footnote $ "Expected\n" <> (show expected)
-    footnote "\n"
-    footnote $ "Actual\n" <> (show actual)
-
--- | This function creates a link to the source file which is conforms to
---   the output of GHC.Exception and thus can be navigated to with some text editors (like emacs)
---   by specifying a regular expression like
---   (".*error, called at \\(.*\\.hs\\):\\([0-9]+\\):\\([0-9]+\\) in .*" 1 2 3 2 1)
---      (" +\\(.*\\.hs\\):\\([0-9]+\\):$" 1 2 nil 2 1)
-makeSourceLink :: (HasCallStack) => String
-makeSourceLink =
-  case getCallStack callStack of
-    [] -> "FAIL!"
-    (f, SrcLoc {..}) : _ ->
-      f ++ " error, called at " ++
-      foldr (++) ""
-      [ srcLocFile, ":"
-      , show srcLocStartLine, ":"
-      , show srcLocStartCol, " in "
-      , srcLocPackage, ":", srcLocModule
-      ]
-
-
--- * SETTINGS
+-- * SETTING TEST OPTIONS
 
--- | Set a mininum number of tests to be successful on a property
+-- | Set the minimum number of tests which must be successful for a property to pass
 minTestsOk :: Int -> TestTree -> TestTree
 minTestsOk n = localOption (HedgehogTestLimit (Just (toEnum n :: TestLimit)))
 
--- | Don't shrink failures
+-- | Do not shrink failures
 noShrink :: TestTree -> TestTree
 noShrink = localOption (HedgehogShrinkLimit (Just (0 :: ShrinkLimit)))
 
--- | Run a property with a specify seed. You can copy and paste the exact string
---   which Hedgehog outputs when there is a failure
+-- | Execute a property with a specific seed
 withSeed :: Prelude.String -> TestTree -> TestTree
-withSeed seed = localOption (fromJust (parseValue seed :: Maybe HedgehogReplay))
-
--- * GROUPING
-
--- | This allows the discovery of Hedgehog properties and their grouping by module name
---   in the test report.
---   Extract the ModuleName option value for a given test and
---   group all the tests with that option into the same test group
-groupByModuleName :: TestTree -> TestTree
-groupByModuleName testTree =
-  let grouped = assocs $ foldTestTree (trivialFold { foldSingle = \os n t ->
-        let (ModuleName aModuleName) = lookupOption os :: ModuleName
-        in insert (toS aModuleName) (setOptionSet os $ singleTest n t) empty
-        }) mempty testTree
-  in  TestGroup "All" (uncurry TestGroup <$> grouped)
+withSeed seed tree =
+  case parseValue seed of
+    Nothing -> prop ("cannot parse seed " <> seed) failure
+    Just (s :: HedgehogReplay) -> localOption s tree
 
-instance (Ord k) => Semigroup (MultiMap k v) where
-  (<>) m1 m2 = fromList (toList m1 <> toList m2)
+-- * ASSERTIONS
 
-instance (Ord k) => Monoid (MultiMap k v) where
-  mempty = empty
-  mappend = (<>)
+-- | Assert that an exception is thrown
+gotException :: forall a. (HasCallStack, Show a) => a -> PropertyT IO ()
+gotException a = withFrozenCallStack $ do
+  res <- liftIO (try (evaluate a) :: IO (Either SomeException a))
+  case res of
+    Left _ -> assert True
+    Right _ -> annotateShow ("excepted an exception" :: Text) >> assert False
 
--- | This is unfortunate. Due to the API for `foldTestTree` in Tasty
---   giving back the current `OptionSet` applicable to a single test
---   it is not possible to re-set those option values on that test
---   without listing them exhaustively. This means
---   that if other options are set on tests in that file, they need to be
---   added in that function
-setOptionSet :: OptionSet -> TestTree -> TestTree
-setOptionSet os =
-  localOption (lookupOption os :: HedgehogTestLimit) .
-  localOption (lookupOption os :: HedgehogShrinkLimit) .
-  localOption (lookupOption os :: HedgehogReplay)
+-- * REPORTING
 
--- | Return the module name of the current callstack
-getModuleName :: HasCallStack => Prelude.String
-getModuleName =
-  case getCallStack  callStack of
-    ((_, loc):_) -> srcLocModule loc
-    _            -> "root"
+printDifference :: (MonadIO m, Show a, Show b, HasCallStack) => a -> b -> m ()
+printDifference actual expected = withFrozenCallStack $ do
+  let failureReport = mkFailure (Size 0) (Seed 0 0) (ShrinkCount 0) Nothing Nothing "" (failureDifference actual expected) []
+  report <- renderResult EnableColor Nothing (Report (TestCount 0) (DiscardCount 0) (Coverage mempty) (Failed failureReport))
+  putText (T.unlines . drop 3 . T.lines . toS $ report)
 
--- | Option describing the current module name
-newtype ModuleName = ModuleName Text deriving (Eq, Show)
+failureDifference :: (Show a, Show b, HasCallStack) => a -> b -> Maybe Diff
+failureDifference x y = withFrozenCallStack $
+  case valueDiff <$> mkValue x <*> mkValue y of
+    Nothing ->
+      Nothing
+    Just d ->
+      withFrozenCallStack $
+        Just $ Diff "━━━ Failed (" "- lhs" ") (" "+ rhs" ") ━━━" d
 
--- | This option is not used on the command line, it is just used to annotate test groups
-instance IsOption ModuleName where
-  defaultValue = ModuleName "root"
-  parseValue = fmap ModuleName . safeRead
-  optionName = pure "module-name"
-  optionHelp = pure "internal option used to group tests into the same module"
-  optionCLParser = mkFlagCLParser mempty (ModuleName "root")
+display :: (Show a, Monad m, HasCallStack) => a -> PropertyT m a
+display a = withFrozenCallStack (annotateShow a $> a)
 
 -- * GHCi run functions
 
diff --git a/test/Test/Data/Registry/Company.hs b/test/Test/Data/Registry/Company.hs
--- a/test/Test/Data/Registry/Company.hs
+++ b/test/Test/Data/Registry/Company.hs
@@ -1,27 +1,30 @@
 module Test.Data.Registry.Company where
 
-import           Protolude
+import Protolude
 
 -- Some complex nested data
-data Company = Company {
-  companyName :: Text
-, departments :: [Department]
-} deriving (Eq, Show)
+data Company = Company
+  { companyName :: Text,
+    departments :: [Department]
+  }
+  deriving (Eq, Show)
 
-data Department = Department {
-  departmentName :: Text
-, employees      :: [Employee]
-} deriving (Eq, Show)
+data Department = Department
+  { departmentName :: Text,
+    employees :: [Employee]
+  }
+  deriving (Eq, Show)
 
-data Employee = Employee {
-  employeeName   :: Text
-, employeeStatus :: EmployeeStatus
-, salary         :: Int
-, bonus          :: Maybe Int
-} deriving (Eq, Show)
+data Employee = Employee
+  { employeeName :: Text,
+    employeeStatus :: EmployeeStatus,
+    salary :: Int,
+    bonus :: Maybe Int
+  }
+  deriving (Eq, Show)
 
 -- | Note that this is an ADT with several constructors
-data EmployeeStatus =
-   Permanent
- | Temporary Int -- number of days
- deriving (Eq, Show)
+data EmployeeStatus
+  = Permanent
+  | Temporary Int -- number of days
+  deriving (Eq, Show)
diff --git a/test/Test/Data/Registry/Generators.hs b/test/Test/Data/Registry/Generators.hs
--- a/test/Test/Data/Registry/Generators.hs
+++ b/test/Test/Data/Registry/Generators.hs
@@ -1,35 +1,35 @@
-{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE PartialTypeSignatures #-}
-{-# LANGUAGE TemplateHaskell       #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Data.Registry.Generators where
 
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Data.Registry.Hedgehog.TH
-import           Data.Registry.TH
-import           Hedgehog.Gen               as Gen hiding (print)
-import           Hedgehog.Internal.Gen      hiding (print)
-import           Hedgehog.Range
-import           Protolude                  hiding (list)
-import           Test.Data.Registry.Company
-import           Test.Tasty.Hedgehogx
+import Data.Registry
+import Data.Registry.Hedgehog
+import Data.Registry.Hedgehog.TH
+import Data.Registry.TH
+import Hedgehog.Gen as Gen hiding (print)
+import Hedgehog.Internal.Gen hiding (print)
+import Hedgehog.Range
+import Protolude hiding (list)
+import Test.Data.Registry.Company
+import Test.Tasty.Hedgehogx
 
 registry =
-    genFun Company
- <: genFun Department
- <: genFun Employee
- -- we can generate data for different constructors in an ADT with some Template Haskell
- <: $(makeGenerators ''EmployeeStatus)
- -- we can generate Lists or Maybe of elements
- <: fun (listOf @Department)
- <: fun (listOf @Employee)
- <: fun (maybeOf @Int)
- <: genVal genInt
- <: genVal genText
+  genFun Company
+    <: genFun Department
+    <: genFun Employee
+    -- we can generate data for different constructors in an ADT with some Template Haskell
+    <: $(makeGenerators ''EmployeeStatus)
+    -- we can generate Lists or Maybe of elements
+    <: fun (listOf @Department)
+    <: fun (listOf @Employee)
+    <: fun (maybeOf @Int)
+    <: genVal genInt
+    <: genVal genText
 
 genInt :: Gen Int
 genInt = integral (linear 1 3)
@@ -46,5 +46,5 @@
 generators = $(checkRegistry 'registry)
 
 -- | We create a forall function using all the generators
-forall :: forall a . _ => PropertyT IO a
+forall :: forall a. _ => PropertyT IO a
 forall = withFrozenCallStack $ forAllT (genWith @a generators)
diff --git a/test/Test/Data/Registry/HedgehogSpec.hs b/test/Test/Data/Registry/HedgehogSpec.hs
--- a/test/Test/Data/Registry/HedgehogSpec.hs
+++ b/test/Test/Data/Registry/HedgehogSpec.hs
@@ -1,29 +1,54 @@
-{-# LANGUAGE DataKinds                  #-}
-{-# LANGUAGE PartialTypeSignatures      #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PartialTypeSignatures #-}
 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Data.Registry.HedgehogSpec where
 
-import           Control.Monad.Morph (hoist)
-import           Data.IORef
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Hedgehog.Internal.Gen         hiding (print)
-import           Hedgehog.Range
-import           Hedgehog.Gen as Gen
-import           Protolude                     hiding (list)
-import           System.IO.Unsafe
-import           Test.Data.Registry.Company
-import           Test.Data.Registry.Generators
-import           Test.Tasty.Hedgehogx
-import           Hedgehog.Internal.Seed as Seed (random)
-import           Hedgehog.Internal.Tree as Tree (NodeT (..), runTreeT)
-
+import Control.Monad.Morph (hoist)
+import Data.IORef
+import Data.Registry
+import Data.Registry.Hedgehog
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
+import Hedgehog.Gen as Gen
+import Hedgehog.Internal.Gen hiding (print)
+import Hedgehog.Internal.Seed as Seed (random)
+import Hedgehog.Internal.Tree as Tree (NodeT (..), runTreeT)
+import Hedgehog.Range
+import Protolude
+  ( Applicative (pure),
+    Bool (True),
+    Eq,
+    Foldable (length),
+    IO,
+    Int,
+    Maybe (Just, Nothing),
+    Monad ((>>)),
+    MonadIO (..),
+    MonadState (get, put),
+    Num ((+), (-)),
+    Ord ((<=), (>=)),
+    Show,
+    State,
+    Text,
+    evalState,
+    flip,
+    head,
+    lift,
+    panic,
+    ($),
+    (.),
+    (<$>),
+  )
+import System.IO.Unsafe
+import Test.Data.Registry.Company
+import Test.Data.Registry.Generators
+import Test.Tasty.Hedgehogx
+
 -- * This specification shows the usage of several features of this library
+
 --   First of all you will notice that if you run `stack test`
 --   all the properties of this file will be grouped under the Test.Data.Registry.HedgehogSpec test group
 
@@ -68,59 +93,67 @@
 
 -- Let's create some registry modifiers to constrain the generation
 setOneDepartment = addFunS $ listOfMinMax @Department 1 1
-setOneEmployee   = addFunS $ listOfMinMax @Employee 1 1
+
+setOneEmployee = addFunS $ listOfMinMax @Employee 1 1
+
 setSmallCompany = setOneEmployee >> setOneDepartment
 
 test_small_company =
-  prop "a small company has just one department and one employee" $ runS generators $ do
-    setSmallCompany
-    company <- forallS @Company
-    length (departments company) === 1
-    let Just d = head $ departments company
-    length (employees d) === 1
+  prop "a small company has just one department and one employee" $
+    runS generators $ do
+      setSmallCompany
+      company <- forallS @Company
+      length (departments company) === 1
+      let Just d = head $ departments company
+      length (employees d) === 1
 
 -- * We can also specialize some generators in a given context
+
 --   For example we might want to generate shorter department names even
 --   if Department is using Text values. To do this we specialize the Text
 --   generator in the context of a Gen Department
 
 genDepartmentName = T.take 5 . T.toUpper <$> genText
+
 setDepartmentName = specializeGenS @Department genDepartmentName
 
 test_with_better_department_name = noShrink $
-  prop "a department must have a short capitalized name" $ runS generators $ do
-    setSmallCompany
-    setDepartmentName
-    company <- forallS @Company
+  prop "a department must have a short capitalized name" $
+    runS generators $ do
+      setSmallCompany
+      setDepartmentName
+      company <- forallS @Company
 
-    -- uncomment to print the department names and inspect them
-    -- print company
-    let Just d = head $ departments company
-    (T.length (departmentName d) <= 5) === True
+      -- uncomment to print the department names and inspect them
+      -- print company
+      let Just d = head $ departments company
+      (T.length (departmentName d) <= 5) === True
 
 -- * It would be also very nice to have stateful generation where we can cycle
+
 --   across different constructors for a given data type
 
 test_cycle_constructors =
-  prop "we can cycle deterministically across all the constructors of a data type" $ runS generators $ do
-    setCycleChooserS @EmployeeStatus
-    -- uncomment to check
-    -- collect =<< forallS @EmployeeStatus
-    success
+  prop "we can cycle deterministically across all the constructors of a data type" $
+    runS generators $ do
+      setCycleChooserS @EmployeeStatus
+      -- uncomment to check
+      -- collect =<< forallS @EmployeeStatus
+      success
 
 -- We can also make sure we generate distinct values for a given type
 test_distinct_values =
-  prop "we can generate distinct values for a given data type when used in a specific context" $ runS generators $ do
-   setDistinctForS @Department @Text
-   -- uncomment to check
-   -- collect =<< departmentName <$> forallS @Department
-   success
-
+  prop "we can generate distinct values for a given data type when used in a specific context" $
+    runS generators $ do
+      setDistinctForS @Department @Text
+      -- uncomment to check
+      -- collect =<< departmentName <$> forallS @Department
+      success
 
 test_ints_generator =
   prop "we can generate ints" $ do
-   n <- forAllT distinctInt
-   n === n -- collect n
+    n <- forAllT distinctInt
+    n === n -- collect n
 
 test_fresh = minTestsOk 10000 $
   prop "we can generate terms with fresh ids" $ do
@@ -140,8 +173,8 @@
   t <- g
   makeValue t
 
-data Term =
-    Value Int Text
+data Term
+  = Value Int Text
   | Exp Int Term Term
   deriving (Eq, Show)
 
@@ -162,7 +195,7 @@
 runFresh = forAll . runStateGen
 
 runStateGen :: (Show a) => GenT (State Int) a -> Gen a
-runStateGen = hoist (pure . flip evalState 0  )
+runStateGen = hoist (pure . flip evalState 0)
 
 instance Fresh (GenT (State Int)) where
   fresh = do
@@ -173,20 +206,18 @@
 -- | Sample GenT IO values
 sampleGenIO :: GenT IO a -> IO a
 sampleGenIO gen =
-    let
-      loop n =
-        if n <= 0 then
-          panic "Hedgehog.Gen.sample: too many discards, could not generate a sample"
-        else do
-          seed <- Seed.random
-          NodeT r _  <- runTreeT $ evalGenT 30 seed gen
-          case r of
-            Nothing ->
-              loop (n - 1)
-            Just a ->
-              pure a
-    in
-      loop (100 :: Int)
+  let loop n =
+        if n <= 0
+          then panic "Hedgehog.Gen.sample: too many discards, could not generate a sample"
+          else do
+            seed <- Seed.random
+            NodeT r _ <- runTreeT $ evalGenT 30 seed gen
+            case r of
+              Nothing ->
+                loop (n - 1)
+              Just a ->
+                pure a
+   in loop (100 :: Int)
 
 {-# NOINLINE distinctInt #-}
 distinctInt :: GenIO Int
diff --git a/test/Test/Tutorial/DataModel.hs b/test/Test/Tutorial/DataModel.hs
--- a/test/Test/Tutorial/DataModel.hs
+++ b/test/Test/Tutorial/DataModel.hs
@@ -1,25 +1,28 @@
 module Test.Tutorial.DataModel where
 
-import           Protolude
+import Protolude
 
-data Company = Company {
-  companyName :: Text
-, departments :: [Department]
-} deriving (Eq, Show)
+data Company = Company
+  { companyName :: Text,
+    departments :: [Department]
+  }
+  deriving (Eq, Show)
 
-data Department = Department {
-  departmentName :: Text
-, employees      :: [Employee]
-} deriving (Eq, Show)
+data Department = Department
+  { departmentName :: Text,
+    employees :: [Employee]
+  }
+  deriving (Eq, Show)
 
-data Employee = Employee {
-  employeeName   :: Text
-, employeeStatus :: EmployeeStatus
-, salary         :: Int
-, bonus          :: Maybe Int
-} deriving (Eq, Show)
+data Employee = Employee
+  { employeeName :: Text,
+    employeeStatus :: EmployeeStatus,
+    salary :: Int,
+    bonus :: Maybe Int
+  }
+  deriving (Eq, Show)
 
-data EmployeeStatus =
-   Permanent
- | Temporary Int -- number of days
- deriving (Eq, Show)
+data EmployeeStatus
+  = Permanent
+  | Temporary Int -- number of days
+  deriving (Eq, Show)
diff --git a/test/Test/Tutorial/Exercise1.hs b/test/Test/Tutorial/Exercise1.hs
--- a/test/Test/Tutorial/Exercise1.hs
+++ b/test/Test/Tutorial/Exercise1.hs
@@ -1,26 +1,26 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise1 where
 
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Hedgehog                hiding (test)
-import           Hedgehog.Gen
-import           Hedgehog.Range
-import           Protolude
-import           Test.Tutorial.DataModel
+import Data.Registry
+import Data.Registry.Hedgehog
+import Hedgehog hiding (test)
+import Hedgehog.Gen
+import Hedgehog.Range
+import Protolude
+import Test.Tutorial.DataModel
 
 registry :: Registry _ _
 registry =
-     genFun Company
-  <: genFun Department
-  <: genFun Employee
-  <: genVal genEmployeeStatus
-  <: genVal genInt
-  <: genVal genText
+  genFun Company
+    <: genFun Department
+    <: genFun Employee
+    <: genVal genEmployeeStatus
+    <: genVal genInt
+    <: genVal genText
 
 genInt :: Gen Int
 genInt = integral (linear 1 3)
diff --git a/test/Test/Tutorial/Exercise2.hs b/test/Test/Tutorial/Exercise2.hs
--- a/test/Test/Tutorial/Exercise2.hs
+++ b/test/Test/Tutorial/Exercise2.hs
@@ -1,30 +1,30 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise2 where
 
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Hedgehog                hiding (test)
-import           Hedgehog.Gen
-import           Hedgehog.Range
-import           Protolude
-import           Test.Tasty.Hedgehogx
-import           Test.Tutorial.DataModel
+import Data.Registry
+import Data.Registry.Hedgehog
+import Hedgehog hiding (test, (===))
+import Hedgehog.Gen
+import Hedgehog.Range
+import Protolude
+import Test.Tasty.Hedgehogx
+import Test.Tutorial.DataModel
 
 registry :: Registry _ _
 registry =
-     genFun Company
-  <: genFun Department
-  <: genFun Employee
-  <: fun    (listOf @Employee)
-  <: fun    (listOf @Department)
-  <: fun    (maybeOf @Int)
-  <: genVal genEmployeeStatus
-  <: genVal genInt
-  <: genVal genText
+  genFun Company
+    <: genFun Department
+    <: genFun Employee
+    <: fun (listOf @Employee)
+    <: fun (listOf @Department)
+    <: fun (maybeOf @Int)
+    <: genVal genEmployeeStatus
+    <: genVal genInt
+    <: genVal genText
 
 genInt :: Gen Int
 genInt = integral (linear 1 3)
@@ -39,8 +39,8 @@
 makeCompanyGen :: GenIO Company
 makeCompanyGen = make @(GenIO Company) registry
 
-forall :: forall a . (Typeable a, Show a) => PropertyT IO a
-forall = forAllT $ genWith @a registry
+forall :: forall a. (Typeable a, Show a) => PropertyT IO a
+forall = withFrozenCallStack $ forAllT $ genWith @a registry
 
 test_company = test "make a company" $ do
   _ <- forall @Company
diff --git a/test/Test/Tutorial/Exercise3.hs b/test/Test/Tutorial/Exercise3.hs
--- a/test/Test/Tutorial/Exercise3.hs
+++ b/test/Test/Tutorial/Exercise3.hs
@@ -1,25 +1,25 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
-{-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise3 where
 
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Data.Registry.Hedgehog.TH
-import           Hedgehog                hiding (test)
-import           Protolude
-import           Test.Tasty.Hedgehogx
-import           Test.Tutorial.DataModel
-import           Test.Tutorial.Exercise2 (registry)
+import Data.Registry
+import Data.Registry.Hedgehog
+import Data.Registry.Hedgehog.TH
+import Hedgehog hiding (test)
+import Protolude
+import Test.Tasty.Hedgehogx
+import Test.Tutorial.DataModel
+import Test.Tutorial.Exercise2 (registry)
 
 registry3 :: Registry _ _
 registry3 = $(makeGenerators ''EmployeeStatus) <: registry
 
-forall :: forall a . (Typeable a, Show a) => PropertyT IO a
-forall = forAllT $ genWith @a registry3
+forall :: forall a. (Typeable a, Show a) => PropertyT IO a
+forall = withFrozenCallStack $ forAllT $ genWith @a registry3
 
 test_employee_status = prop "make an employee status" $ do
   status <- forall @EmployeeStatus
diff --git a/test/Test/Tutorial/Exercise4.hs b/test/Test/Tutorial/Exercise4.hs
--- a/test/Test/Tutorial/Exercise4.hs
+++ b/test/Test/Tutorial/Exercise4.hs
@@ -1,19 +1,19 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise4 where
 
-import           Data.Registry
-import           Data.Registry.Hedgehog
-import           Data.Text                as T
-import           Hedgehog                 hiding (test)
-import           Protolude
-import           Test.Tasty.Hedgehogx
-import           Test.Tutorial.DataModel
-import           Test.Tutorial.Exercise2 (genText)
-import           Test.Tutorial.Exercise3 (registry3)
+import Data.Registry
+import Data.Registry.Hedgehog
+import Data.Text as T
+import Hedgehog hiding (test)
+import Protolude
+import Test.Tasty.Hedgehogx
+import Test.Tutorial.DataModel
+import Test.Tutorial.Exercise2 (genText)
+import Test.Tutorial.Exercise3 (registry3)
 
 registry12 :: Registry _ _
 registry12 = specializeGen @Department genDepartmentName $ registry3
@@ -21,8 +21,8 @@
 genDepartmentName :: Gen Text
 genDepartmentName = T.take 5 . T.toUpper <$> genText
 
-forall :: forall a . (Typeable a, Show a) => PropertyT IO a
-forall = forAllT $ genWith @a registry12
+forall :: forall a. (Typeable a, Show a) => PropertyT IO a
+forall = withFrozenCallStack $ forAllT $ genWith @a registry12
 
 test_deparment_name = prop "make a department" $ do
   department <- forall @Department
diff --git a/test/Test/Tutorial/Exercise5.hs b/test/Test/Tutorial/Exercise5.hs
--- a/test/Test/Tutorial/Exercise5.hs
+++ b/test/Test/Tutorial/Exercise5.hs
@@ -1,20 +1,20 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise5 where
 
-import           Data.Registry
-import           Data.Text as T
-import           Data.Registry.Hedgehog
-import           Hedgehog                 hiding (test)
-import           Protolude
-import           Test.Tasty.Hedgehogx
-import           Test.Tutorial.DataModel
-import           Test.Tutorial.Exercise2 (genText)
-import           Test.Tutorial.Exercise3 (registry3)
-import           Test.Tutorial.Exercise4 (genDepartmentName)
+import Data.Registry
+import Data.Registry.Hedgehog
+import Data.Text as T
+import Hedgehog hiding (test)
+import Protolude
+import Test.Tasty.Hedgehogx
+import Test.Tutorial.DataModel
+import Test.Tutorial.Exercise2 (genText)
+import Test.Tutorial.Exercise3 (registry3)
+import Test.Tutorial.Exercise4 (genDepartmentName)
 
 runGens = runS registry3
 
@@ -22,14 +22,18 @@
 genEmployeeName = T.take 10 . T.toLower <$> genText
 
 setDepartmentName = specializeGenS @Department genDepartmentName
-setEmployeeName   = specializeGenS @Employee genEmployeeName
 
+setEmployeeName = specializeGenS @Employee genEmployeeName
+
 setOneDepartment = addFunS $ listOfMinMax @Department 1 1
-setOneEmployee   = addFunS $ listOfMinMax @Employee 1 1
+
+setOneEmployee = addFunS $ listOfMinMax @Employee 1 1
+
 setSmallCompany = setOneEmployee >> setOneDepartment
 
-test_small_company = prop "make a small company" $ runGens $ do
-  setSmallCompany
-  setEmployeeName
-  setDepartmentName
-  collect =<< forallS @Company
+test_small_company = prop "make a small company" $
+  runGens $ do
+    setSmallCompany
+    setEmployeeName
+    setDepartmentName
+    collect =<< forallS @Company
diff --git a/test/Test/Tutorial/Exercise6.hs b/test/Test/Tutorial/Exercise6.hs
--- a/test/Test/Tutorial/Exercise6.hs
+++ b/test/Test/Tutorial/Exercise6.hs
@@ -1,27 +1,28 @@
-{-# LANGUAGE DataKinds             #-}
-{-# LANGUAGE KindSignatures        #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE PartialTypeSignatures #-}
-{-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
 
 module Test.Tutorial.Exercise6 where
 
-import           Data.Registry.Hedgehog
-import           Data.Text                 as T
-import           Hedgehog                  hiding (test)
-import           Protolude
-import           Test.Tasty.Hedgehogx
-import           Test.Tutorial.DataModel
-import           Test.Tutorial.Exercise5
+import Data.Registry.Hedgehog
+import Data.Text as T
+import Hedgehog hiding (test)
+import Protolude
+import Test.Tasty.Hedgehogx
+import Test.Tutorial.DataModel
+import Test.Tutorial.Exercise5
 
-test_another_small_company = prop "make a small company" $ runGens $ do
-  setSmallCompany
-  setEmployeeName
-  setDepartmentName
-  setGenS @Int (pure 1)
-  setDistinctForS @Department @Text
+test_another_small_company = prop "make a small company" $
+  runGens $ do
+    setSmallCompany
+    setEmployeeName
+    setDepartmentName
+    setGenS @Int (pure 1)
+    setDistinctForS @Department @Text
 
-  collect =<< forallS @Company
+    collect =<< forallS @Company
 
-  setCycleChooserS @EmployeeStatus
-  collect =<< forallS @EmployeeStatus
+    setCycleChooserS @EmployeeStatus
+    collect =<< forallS @EmployeeStatus
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -1,5 +1,5 @@
-import           AutoDiscoveredSpecs   (tests)
-import           Protolude
-import           Test.Tasty.Hedgehogx
+import AutoDiscoveredSpecs (tests)
+import Protolude
+import Test.Tasty.Hedgehogx
 
 main = tests >>= defaultMain . groupByModuleName
