hspec-hedgehog 0.0.1.0 → 0.0.1.1
raw patch · 5 files changed
+86/−23 lines, 5 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ Test.Hspec.Hedgehog: modifyArgs :: () => (Args -> Args) -> SpecWith a -> SpecWith a
+ Test.Hspec.Hedgehog: modifyMaxDiscardRatio :: () => (Int -> Int) -> SpecWith a -> SpecWith a
+ Test.Hspec.Hedgehog: modifyMaxShrinks :: () => (Int -> Int) -> SpecWith a -> SpecWith a
+ Test.Hspec.Hedgehog: modifyMaxSize :: () => (Int -> Int) -> SpecWith a -> SpecWith a
+ Test.Hspec.Hedgehog: modifyMaxSuccess :: () => (Int -> Int) -> SpecWith a -> SpecWith a
Files
- ChangeLog.md +8/−0
- README.md +19/−0
- hspec-hedgehog.cabal +1/−1
- src/Test/Hspec/Hedgehog.hs +44/−20
- test/Spec.hs +14/−2
ChangeLog.md view
@@ -1,5 +1,13 @@ # Changelog for hspec-hedgehog +## 0.0.1.1++- [#2](https://github.com/parsonsmatt/hspec-hedgehog/pull/2) @lehins+ - Documentation fix+- [#3](https://github.com/parsonsmatt/hspec-hedgehog/pull/3) @parsonsmatt+ - Respect the `maxSuccess`, `maxDiscardRatio`, and `maxShrinks` properties of QuickCheck's `Args` type.+ - Reexport `modifyArgs`, `modifyMaxSuccess`, `modifyMaxDiscardRatio`, `modifyMaxSize`, `modifyMaxShrings`+ ## 0.0.1.0 - Initial Release
README.md view
@@ -49,3 +49,22 @@ wrongLen <- forAll $ Gen.integral (Range.linear 0 3) length str /== wrongLen ```++## How does this differ from [`hw-hspec-hedgehog`](https://hackage.haskell.org/package/hw-hspec-hedgehog)?++Good question!++The `hw-spec-hedgehog` implementation does the easy thing.+It calls Hedgehog's `check` function on the property, and if the property returns `True`, then it passes the test.+If the property fails, then it renders an [uninformative failure message](https://twitter.com/mattoflambda/status/1234879820225400832) - it's hardcoded to be:++> Hedgehog property test failed++And that's all you get!++This library preserves Hedgehog's error message formatting, so you get [rich, insightful error messages](https://twitter.com/mattoflambda/status/1234880271406661633) just like Hedgehog intended.++Furthermore, this library integrates with `hspec`'s support for the `QuickCheck` library.+Any option that works with `QuickCheck` should work with `hedgehog` properties, so you can use `modifyMaxSuccess (\_ -> 10)` to set the total tests to be 10, rather than the default 100.++Because it integrates directly with hspec, it also renders a familiar progress message while the test is running.
hspec-hedgehog.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: hspec-hedgehog-version: 0.0.1.0+version: 0.0.1.1 description: Please see the README on GitHub at <https://github.com/parsonsmatt/hspec-hedgehog#readme> synopsis: Integrate Hedgehog and Hspec! category: Testing
src/Test/Hspec/Hedgehog.hs view
@@ -9,6 +9,8 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ViewPatterns #-} +{-# OPTIONS_GHC -fno-warn-orphans #-}+ -- | This module allows you to easily integrate the "Hedgehog" library with -- "Test.Hspec" test-suites. --@@ -69,7 +71,7 @@ -- -- @ -- 'before' ('pure' \"Hello!\") $ do--- 'it' \"message\" $ \str -> do+-- 'it' \"message\" $ \\str -> do -- 'pure' () :: 'PropertyT' 'IO' () -- wrongLen <- 'forAll' $ 'Gen.integral' ('Range.linear' 0 3) -- 'length' str '/==' wrongLen@@ -77,7 +79,15 @@ -- -- You don't have to remember to put the 'hedgehog' call after the lambda. module Test.Hspec.Hedgehog- ( hedgehog+ ( -- * The Main Function+ hedgehog+ -- * Hspec re-exports+ , modifyArgs+ , modifyMaxSuccess+ , modifyMaxDiscardRatio+ , modifyMaxSize+ , modifyMaxShrinks+ -- * Hedgehog Re-exports , module Hedgehog ) where @@ -85,22 +95,24 @@ import Data.Coerce (coerce) import Data.IORef (newIORef, readIORef, writeIORef) import Hedgehog-import Hedgehog.Internal.Config (UseColor, detectColor)-import Hedgehog.Internal.Property (TerminationCriteria (..),- TestCount (..), TestLimit (..),- propertyConfig,- propertyTerminationCriteria,- propertyTest)+import Hedgehog.Internal.Config (detectColor)+import Hedgehog.Internal.Property (DiscardLimit (..), Property (..),+ PropertyConfig (..),+ ShrinkLimit (..),+ TerminationCriteria (..),+ TestCount (..), TestLimit (..)) import Hedgehog.Internal.Report as Hedge import Hedgehog.Internal.Runner (checkReport) import qualified Hedgehog.Internal.Seed as Seed-import Hedgehog.Internal.Source (HasCallStack) import System.Random.SplitMix (unseedSMGen) import Test.Hspec import Test.Hspec.Core.Spec as Hspec+import Test.Hspec.QuickCheck (modifyArgs, modifyMaxDiscardRatio,+ modifyMaxShrinks, modifyMaxSize,+ modifyMaxSuccess) import Test.HUnit.Base (assertFailure) import Test.QuickCheck.Random (QCGen (..))-import Test.QuickCheck.Test (replay)+import Test.QuickCheck.Test (Args (..)) -- | Embed a "Hedgehog" @'PropertyT' 'IO' ()@ in an @hspec@ test. --@@ -150,15 +162,29 @@ color <- detectColor let size = 0 prop = aprop a- propConfig = propertyConfig prop- maxTests = case propertyTerminationCriteria propConfig of- EarlyTermination _ (TestLimit n) -> n- NoEarlyTermination _ (TestLimit n) -> n- NoConfidenceTermination (TestLimit n) -> n- testCount report = case reportTests report of- TestCount n -> n+ propConfig = useQuickCheckArgs (propertyConfig prop)+ qcArgs = paramsQuickCheckArgs params++ maxTests = maxSuccess qcArgs+ useQuickCheckArgs pc =+ pc+ { propertyTerminationCriteria =+ case propertyTerminationCriteria pc of+ EarlyTermination x (TestLimit _) ->+ EarlyTermination x (TestLimit maxTests)+ NoEarlyTermination x (TestLimit _) ->+ NoEarlyTermination x (TestLimit maxTests)+ NoConfidenceTermination (TestLimit _) ->+ NoConfidenceTermination (TestLimit maxTests)+ , propertyDiscardLimit =+ DiscardLimit $ maxDiscardRatio qcArgs+ , propertyShrinkLimit =+ ShrinkLimit $ maxShrinks qcArgs+ }+ testCount report =+ case reportTests report of+ TestCount n -> n cb progress = do- ppprogress <- renderProgress color Nothing progress case reportStatus progress of Running -> progressCallback (testCount progress, maxTests)@@ -187,5 +213,3 @@ OK -> pure $ Result "" Success readIORef ref- where- mkFail = Result
test/Spec.hs view
@@ -2,9 +2,11 @@ import Control.Monad.IO.Class (liftIO) import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range-import Test.Hspec (before, describe, hspec, it, shouldBe)+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@@ -20,7 +22,7 @@ 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+ diff (x + y) (>=) (x :: Integer) it "renders a progress bit" $ hedgehog $ do x <- forAll $ Gen.integral (Range.linear 0 1000)@@ -39,3 +41,13 @@ 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