import Control.Concurrent (threadDelay) import Control.Monad.IO.Class (liftIO) import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range import Test.Hspec (before, beforeAll, describe, hspec, it, shouldBe) import Test.Hspec.Hedgehog (PropertyT, diff, forAll, hedgehog, (/==), (===)) import Data.IORef import Test.Hspec.QuickCheck (modifyMaxSuccess) main :: IO () main = hspec $ do describe "regular tests" $ do it "works" $ do True `shouldBe` True describe "hedgehog" $ do it "is useful if you get an ambiguous error" $ hedgehog $ do "no ambiguity" === "no ambiguity" describe "hedgehog tests" $ do it "lets you use PropertyT directly" $ hedgehog $ do x <- forAll $ Gen.integral (Range.linear 0 1000) y <- forAll $ Gen.integral (Range.linear 0 5000) diff (x + y) (>=) (x :: Integer) it "renders a progress bit" $ hedgehog $ do x <- forAll $ Gen.integral (Range.linear 0 1000) y <- forAll $ Gen.integral (Range.linear 1 5000) liftIO $ threadDelay (100 * x + y) describe "with hooks" $ do before (pure "Hello!") $ do it "has functions" $ \str -> hedgehog $ str === "Hello!" it "goes before or after" $ \str -> do pure () :: PropertyT IO () str === "Hello!" it "generates" $ \str -> hedgehog $ do wrongLen <- forAll $ Gen.integral (Range.linear 0 3) length str /== wrongLen describe "modifyMaxSuccess" $ do modifyMaxSuccess (\_ -> 10) $ do beforeAll (newIORef (0 :: Integer)) $ do it "counts to 10" $ \ref -> hedgehog $ do liftIO $ atomicModifyIORef' ref (\a -> (a + 1, ())) True === True it "works" $ \ref -> do val <- readIORef ref val `shouldBe` 10