packages feed

quickcheck-silent 0.11.0.16 → 0.11.0.17

raw patch · 3 files changed

+75/−27 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ Test.QuickCheck.Silent: type Pattern = String
+ Test.QuickCheck.Silent: type Separator = Char
+ Test.QuickCheck.Silent: type Timeout = Int
- Test.QuickCheck.Silent: quickCheckSilent :: [SilentProp] -> IO [Result]
+ Test.QuickCheck.Silent: quickCheckSilent :: Maybe Timeout -> [SilentProp] -> IO [Result]
- Test.QuickCheck.Silent: quickCheckSilentSuite :: Char -> [String] -> Test -> IO [(Label, Result)]
+ Test.QuickCheck.Silent: quickCheckSilentSuite :: Maybe Timeout -> Separator -> [Pattern] -> Test -> IO [(Label, Result)]
- Test.QuickCheck.Silent: quickCheckSilentSuiteJSON :: Char -> [String] -> Test -> IO [JSON]
+ Test.QuickCheck.Silent: quickCheckSilentSuiteJSON :: Maybe Timeout -> Separator -> [Pattern] -> Test -> IO [JSON]

Files

CHANGELOG.md view
@@ -1,5 +1,11 @@ # Revision history for quickcheck-silent +## 0.11.0.17 -- 2026-09-23++* Added a `Timeout` to: `quickCheckSilent`, `quickCheckSilentSuite` and+  `quickCheckSilentSuiteJSON` to provide an upper bound to avoid non-terminating+  computations in test cases.+ ## 0.11.0.16 -- 2026-08-20  * Updated `quickCheckSilentSuiteJSON` documentation.
quickcheck-silent.cabal view
@@ -10,7 +10,7 @@ build-type: Simple                                                name: quickcheck-silent-version: 0.11.0.16+version: 0.11.0.17  synopsis: Testing with QuickCheck in silence description: Testing with QuickCheck in silence. For more info see README.md
src/Test/QuickCheck/Silent.hs view
@@ -5,6 +5,10 @@  {-# LANGUAGE DeriveDataTypeable           #-} +{-# LANGUAGE LambdaCase                   #-}++{-# LANGUAGE NumericUnderscores           #-}+ --------------------------------------------------------------------------------  -- |@@ -27,6 +31,9 @@   , silent   , withNumTests     -- * Running tests+  , Timeout+  , Separator+  , Pattern   , Status(..)   , Result(..)   , JSON@@ -41,6 +48,8 @@  import           Data.Data                            ( Data ) import           Data.List                            ( isPrefixOf )+import           Data.Maybe                           ( fromMaybe )+import           System.Timeout                       ( timeout )  import qualified Test.QuickCheck                      as QC import           Test.QuickCheck@@ -63,18 +72,29 @@  -------------------------------------------------------------------------------- --- | A name or description for a case or a subtree of the @Test@s.+-- | A name or description for a case or a subtree of the 'Test's. type Label = String  -- | The basic structure used to create an annotated tree of test cases. data Test-  -- | A set of @Test@s sharing the same level in the hierarchy.+  -- | A set of 'Test's sharing the same level in the hierarchy.   = Group !Label ![Test]   -- | A single, independent test case composed.   | Case  !Label !SilentProp  -------------------------------------------------------------------------------- +-- | To ensure a computation result is available within @n@ seconds.+type Timeout = Int++-- | A character, for example: @.@ (dot), that separates 'Test' 'Label's for+-- 'Group's and 'Case's.+type Separator = Char++-- | A string containing 'Test' 'Label's for 'Group's and 'Case's as well as the+-- chosen 'Separator' character. For example: @"Test.QuickCheck.Silent"@.+type Pattern = String+ -- | Status represents the outcome of a test data Status   -- | A successful test run@@ -156,25 +176,38 @@  -------------------------------------------------------------------------------- --- | Tests a sequence of silent properties, producing a list of results, without--- printing them to 'System.IO.stdout'.+-- | Tests a sequence of silent properties, producing a list of 'Result's,+-- without printing them to 'System.IO.stdout', in case 'Result's are available+-- before the 'Timeout' (seconds) expires. If no 'Timeout' value is provided, a+-- default value of @60@ seconds will be used. If a computation timed-out, an+-- empty list will be provided. quickCheckSilent-  :: [SilentProp]+  :: Maybe Timeout+  -> [SilentProp]   -> IO [Result]-quickCheckSilent =-  mapM (\ p -> resultAux <$> (aux . property) p)+quickCheckSilent mto sps =+  ( \ case+      Just rs -> rs+      Nothing -> []+  )+  <$> timeout oto (mapM (\ p -> resultAux <$> (aux . property) p) sps)   where+    oto = 1_000_000 * fromMaybe 60 mto     aux =       QC.quickCheckWithResult $ stdArgs { chatty = False } --- | Tests a suite of silent properties, producing a list of results with their--- respective labels and without printing them to 'System.IO.stdout'.+-- | Tests a suite of silent properties, producing a list of 'Result's with+-- their respective 'Label's and without printing them to 'System.IO.stdout', in+-- case 'Result's are available before the 'Timeout' (seconds) expires. If no+-- 'Timeout' value is provided, a default value of @60@ seconds will be used. If+-- a computation timed-out, an empty list will be provided. -- -- For example, -- -- > check =--- >   quickCheckSilentSuite sep pts tcs+-- >   quickCheckSilentSuite oto sep pts tcs -- >   where+-- >     oto = Just 60 -- seconds -- >     sep = '.' -- >     pts = [ "Test.QuickCheck.Silent" ] -- >     tcs =@@ -192,27 +225,35 @@ -- -- will test both @p@ and @q@, but not @r@. ----- The provided @patterns@, will be checked if they are a 'Data.List.isPrefixOf'--- of each @label@:+-- The provided 'Pattern's, will be checked if they are a 'Data.List.isPrefixOf'+-- of each 'Label': -- -- > any (`isPrefixOf` label) [ pattern_0, pattern_1, … pattern_n ] -- -- @NOTE@: To test all cases, just provide a singleton list with an empty string--- element as @pattern@ as it's a prefix for all possible @labels@.+-- element as 'Pattern's as it's a prefix for all possible 'Label's. quickCheckSilentSuite-  :: Char-  -> [String]+  :: Maybe Timeout+  -> Separator+  -> [Pattern]   -> Test   -> IO [(Label, Result)]-quickCheckSilentSuite sep pts suite =-  mapM-    ( \ (l, sp) ->-        (aux . property) sp >>= \ r ->-        pure (l, resultAux r)+quickCheckSilentSuite mto sep pts suite =+  ( \ case+      Just rs -> rs+      Nothing -> []+  )+  <$> timeout oto+    ( mapM+        ( \ (l, sp) ->+            (aux . property) sp >>= \ r ->+            pure (l, resultAux r)+        )+      $ filter ( \(l, _) -> any  (`isPrefixOf` l) pts)+      $ dfs [] suite     )-  $ filter ( \(l, _) -> any  (`isPrefixOf` l) pts)-  $ dfs [] suite   where+    oto = 1_000_000 * fromMaybe 60 mto     dfs [ ] (Group l ts) = concatMap (dfs                  l)  ts     dfs acc (Group l ts) = concatMap (dfs (acc ++ [sep] ++ l)) ts     dfs [ ] (Case  l p)  = [              (                l, p)]@@ -223,16 +264,17 @@ -- | Same behavior as 'quickCheckSilentSuite', but, producing a list of 'JSON' -- data payloads instead. quickCheckSilentSuiteJSON-  :: Char-  -> [String]+  :: Maybe Timeout+  -> Separator+  -> [Pattern]   -> Test   -> IO [JSON]-quickCheckSilentSuiteJSON sep pts suite =+quickCheckSilentSuiteJSON mto sep pts suite =   map   ( \ (l, r) ->       encodeJSON $ LabelResultJSON l r   )-  <$> quickCheckSilentSuite sep pts suite+  <$> quickCheckSilentSuite mto sep pts suite  -- | Check if the test run result was a success isSuccess :: Result -> Bool