@@ -32,10 +32,22 @@ import Test.QuickCheck
3232import Test.QuickCheck.DynamicLogic.CanGenerate
3333import Test.QuickCheck.StateModel
3434
35- -- | A `Quantification` over a type @a@ is a generator that can be used with
36- -- `Plutus.Contract.Test.ContractModel.forAllQ` to generate random values in
37- -- DL scenarios. In addition to a QuickCheck generator a `Quantification` contains a shrinking
38- -- strategy that ensures that shrunk values stay in the range of the generator.
35+ -- | A `Quantification` over a type @a@ is a generator that can be used to generate random values in
36+ -- DL scenarios.
37+ --
38+ -- A `Quantification` is similar to a `Test.QuickCheck.Arbitrary`, it groups together:
39+ --
40+ -- * A standard QuickCheck _generator_ in the `Gen` monad, which can be "empty",
41+ -- * A _shrinking_ strategy for generated values in the case of a
42+ -- failures ensuring they stay within the domain,
43+ -- * A _predicate_ allowing finer grained control on generation
44+ -- and shrinking process, e.g in the case the range of the generator
45+ -- depends on trace context.
46+ --
47+ -- NOTE: Leaving the possibility of generating `Nothing` is useful to simplify the generation
48+ -- process for `elements` or `frequency` which may normally crash when the list to select
49+ -- elements from is empty. This makes writing `DL` formulas cleaner, removing the need to
50+ -- handle non-existence cases explicitly.
3951data Quantification a = Quantification
4052 { genQ :: Maybe (Gen a )
4153 , isaQ :: a -> Bool
@@ -51,10 +63,11 @@ generateQ q = fromJust (genQ q) `suchThat` isaQ q
5163shrinkQ :: Quantification a -> a -> [a ]
5264shrinkQ q a = filter (isaQ q) (shrQ q a)
5365
54- -- | Wrap a `Gen a` generator in a `Quantification a`.
55- -- Uses given shrinker.
56- withGenQ :: Gen a -> (a -> [a ]) -> Quantification a
57- withGenQ gen = Quantification (Just gen) (const True )
66+ -- | Construct a `Quantification a` from its constituents.
67+ -- Note the predicate provided is used to restrict both the range of values
68+ -- generated and the list of possible shrinked values.
69+ withGenQ :: Gen a -> (a -> Bool ) -> (a -> [a ]) -> Quantification a
70+ withGenQ gen isA = Quantification (Just $ gen `suchThat` isA) isA
5871
5972-- | Pack up an `Arbitrary` instance as a `Quantification`. Treats all values as being in range.
6073arbitraryQ :: Arbitrary a => Quantification a
@@ -228,6 +241,8 @@ instance Quantifiable a => Quantifiable [a] where
228241 from (x : xs) = (x, xs)
229242 from [] = error " quantify: impossible"
230243
244+ -- | Turns a `Quantification` into a `Property` to enable QuickChecking its
245+ -- validity.
231246validQuantification :: Show a => Quantification a -> Property
232247validQuantification q =
233248 forAllShrink (fromJust $ genQ q) (shrinkQ q) $ isaQ q
0 commit comments