@hackage quickcheck-property-comb0.1.0.1

Combinators for Quickcheck Property construction and diagnostics

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