packages feed

quickcheck-property-comb 0.1.0.0 → 0.1.0.1

raw patch · 3 files changed

+89/−36 lines, 3 filesdep ~QuickCheck

Dependency ranges changed: QuickCheck

Files

README.md view
@@ -1,16 +1,16 @@ quickcheck-property-comb ---------This is collection of combinators built on the Reader and Writer-Monads to allow for fast and painless Quickcheck property/invariant construction.+These are combinators, based on the Reader and Writer Monads, to allow for fast+and painless Quickcheck property/invariant construction.  Why? ---- [Quickcheck](http://hackage.haskell.org/package/QuickCheck) is a tool used to-test cases based on constructed Properties,or essentially functions taking a+test cases based on constructed Properties, or essentially functions taking a data structure and returning a boolean True or False.   However when running tests, the only way to document their failing case-is through is through labeling them after binding, e.g.: +is through labeling them after binding, e.g.:   ```haskell inv1, inv2, inv3 :: Foo -> Bool @@ -25,8 +25,7 @@  This gets unwieldy fast as the complexity of the data-structure increases, so quickcheck-property-comb provides the following:-  - A clean separation of composition of invariants and the creation -    and documenting of those invariants for determining cause of failure.+  - Monadically unifies composition of invariants and the documenting of those invariants for determining cause of failure.   - Effective diagnostics for invariants with changing post-conditions,     leading to <b>faster cause-of-failure diagnosis</b>. 
Test/QuickCheck/Property/Comb.hs view
@@ -1,41 +1,43 @@ -- TODO in some cases it may be useful to indent  messages--- based on an invariant category above them+-- based on a documented "context" above them  {-# LANGUAGE TupleSections,  ScopedTypeVariables, GeneralizedNewtypeDeriving #-}-module Test.QuickCheck.Property.Comb where+module Test.QuickCheck.Property.Comb (+  cause, Inv, Invariants, doc, sat, satcomp, runInv, runInvariants+  ) where import Test.QuickCheck import Control.Monad.Writer import Control.Monad.Reader ---A Monad which collects related invariants on the input-type InvM i r = ReaderT i (Writer String) r-type Inv i = InvM i Bool+-- A Monad which collects related invariants on the input+type InvM c r = ReaderT c (Writer String) r+type Inv c = InvM c Bool -cause :: (Monad m) => ReaderT i m i+cause :: (Monad m) => ReaderT c m c cause = ask ---A Monad which collects distinct invariants on the input-type Invariants i = ReaderT i (Writer [Inv i]) ()+-- A Monad which collects invariants on the input+type Invariants c = ReaderT c (Writer [Inv c]) ()  doc :: String -> InvM r () doc = lift . tell -sat :: Inv i -> Invariants i-sat p = lift . tell $ (p:[])+sat :: Inv c -> Invariants c+sat p = lift . tell $ [p] -satcomp :: forall i i'. (i' -> i) -> Invariants i -> Invariants i'+satcomp :: forall c c'. (c' -> c) -> Invariants c -> Invariants c' satcomp f = mapReaderT toWriter . withReaderT f where-  toWriter :: Writer [Inv i] () -> Writer [Inv i'] ()-  toWriter orig = mapWriter (((),) . map toPredicate . snd) orig-  toPredicate :: Inv i -> Inv i'-  toPredicate orig = withReaderT f orig+  toWriter :: Writer [Inv c] () -> Writer [Inv c'] ()+  toWriter = mapWriter (((),) . map toPredicate . snd)+  toPredicate :: Inv c -> Inv c'+  toPredicate = withReaderT f -runInv :: (Show i) => i -> Inv i -> Property-runInv cause' rdr =-  let (effect, msg) = runWriter . (runReaderT rdr) $ cause' in-    printTestCase ("inv: " ++ if null msg then "unknown" else msg)+runInv :: (Show c) => c -> Inv c -> Property+runInv checked rdr =+  let (effect, msg) = runWriter . runReaderT rdr $ checked in+    printTestCase ("invariant: " ++ if null msg then "unknown" else msg)       . property $ effect -runInvariants :: forall i. (Show i) => i -> Invariants i -> Property-runInvariants cause' preds =-  conjoin . map (runInv cause') . execWriter . runReaderT preds $ cause'+runInvariants :: (Show c) => c -> Invariants c -> Property+runInvariants checked preds =+  conjoin . map (runInv checked) . execWriter . runReaderT preds $ checked
quickcheck-property-comb.cabal view
@@ -2,13 +2,65 @@ -- further documentation, see http://haskell.org/cabal/users-guide/  name:                quickcheck-property-comb-version:             0.1.0.0-synopsis:            Combinators for Quickcheck Property construction and Property diagnostics-description:         This project aims to reduce the pain of composing-                     invariants/properties, and the documenting of those invariants for determining the cause-                     of failure. Additionally, it intends to provide effective diagnostics for-                     invariants with changing post-conditions, leading to faster cause-of-failure-                     diagnosis.+version:             0.1.0.1+synopsis:            Combinators for Quickcheck Property construction and diagnostics+description:         +  These are simple monads that aim to reduce the pain of composing+  invariants/properties, and the documenting of those+  invariants for determining the cause of failure.+  Specifically, they provide a tool for effective diagnostic+  for invariants with changing post-conditions, leading to a+  faster cause-of-failure diagnosis.+  .+  Example case for invariants on a data structure "Consumers".+  .+  > data (Ord l) => Consumers l =+  >   Consumers {+  >     introduced :: S.Set l,+  >     met :: M.Map (S.Set l) Bool,+  >     disjoints :: Disjoints l+  >   }+  >+  > introduced_in_disjoint :: Inv (Consumers l)+  > introduced_in_disjoint = do+  >   doc "all at quantity are a singleton subset in disjoints"+  >   subsets       <- (map S.singleton) . S.toList . introduced <$> cause+  >   disjoint_sets <- disjoints <$> cause+  >   return . and . map ((flip S.member) disjoint_sets) $ subsets+  > +  > disjoint_sizes ::  Inv (Disjoints l)+  > disjoint_sizes = do+  >  doc . unlines $+  >    [ "the intersection of introduced and disjoints are the only allowed",+  >     "singleton sets in disjoints"+  >      ]+  >  disjoints' <- cause +  >  -- Do the checking+  >  return False+  >+  > disjoints_eq :: Inv (Disjoints l)+  > disjoints_eq = do+  >   doc "disjoint sets are equal in size"+  >   -- ..+  >   return True+  >+  > disjoints_inv :: Invariants (Disjoints l)+  > disjoints_inv= do+  >   sat disjoints_eq+  >   sat disjoints_sizes+  > +  > inv_consumers :: Invariants (Consumers l)+  > inv_consumers = do+  >   satcomp disjoints disjoints_inv+  >   satcomp met met_inv+  >   sat introduced_in_disjoint+  . +  And to run the Consumer invariant on generated cases: +  .+  > prop_testedFunction :: Arg -> Property+  > prop_testedFunction arg = +  >  let consumers = testedFunction arg in+  >    runInvariants consumers inv_consumers  homepage:            http://www.github.com/jfeltz/quickcheck-property-comb license:             PublicDomain@@ -23,6 +75,6 @@   exposed-modules:     Test.QuickCheck.Property.Comb   -- other-modules:          other-extensions:    TupleSections, ScopedTypeVariables, GeneralizedNewtypeDeriving-  build-depends:       base >=4.5 && <4.6, QuickCheck >=2.5 && <2.6, mtl >=2.1 && <2.2+  build-depends:       base >=4.5 && <4.6, QuickCheck >=2.5 && <=2.6, mtl >=2.1 && <2.2   hs-source-dirs:      ./    default-language:    Haskell2010