packages feed

property-matchers 0.2.0.0 → 0.3.0.0

raw patch · 3 files changed

+94/−16 lines, 3 filesdep +semialigndep +thesePVP ok

version bump matches the API change (PVP)

Dependencies added: semialign, these

API changes (from Hackage documentation)

- PropertyMatchers: propful :: (HasCallStack, Eq (f ()), Functor f, Foldable f) => f (Prop a) -> Prop (f a)
+ PropertyMatchers: alignExact :: (HasCallStack, Traversable f, Semialign f) => f (Prop a) -> Prop (f a)
+ PropertyMatchers: alignLax :: (Traversable f, Semialign f) => Prop a -> f (Prop (Maybe a)) -> Prop (f a)
+ PropertyMatchers: elem :: (HasCallStack, Traversable f) => Prop a -> Prop (f a)
+ PropertyMatchers: fails :: Exception e => Prop e -> Prop (IO a)
+ PropertyMatchers: gt :: (HasCallStack, Ord a) => a -> Prop a
+ PropertyMatchers: gte :: (HasCallStack, Ord a) => a -> Prop a
+ PropertyMatchers: infixr 7 :=>
+ PropertyMatchers: lt :: (HasCallStack, Ord a) => a -> Prop a
+ PropertyMatchers: lte :: (HasCallStack, Ord a) => a -> Prop a

Files

CHANGELOG.md view
@@ -1,7 +1,16 @@ # Revision history for property-matchers -## 0.2.0.0+## 0.3+* Add `fails` function, for asserting that an exception is thrown+* Replace `propful` with `alignExact`+* Add `alignLax` generalizing `alignExact`+* Add `elem`+* Add fixity for `:=>` to be compatible with `?`+* Add comparisons other than `equals` ++## 0.2+ * Add `bool` function * Add hspec + smallcheck test suite * Add `branch` for non-backtracking disjunction of properties@@ -12,7 +21,7 @@ * Reorder `PropertyMatchers` module for intelligibility  -## 0.1.0.0+## 0.1  * Rename to property-matchers * Rename kth to atIndex
property-matchers.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4  name: property-matchers-version: 0.2.0.0+version: 0.3.0.0 synopsis: A library for tests, based on transforming and writing properties description:   This package provides ways to write properties for testing such that they compose nicely and are easy to debug.@@ -25,7 +25,9 @@    ,recover-rtti >= 0.3 && < 0.6    ,pretty-simple >= 1.1 && < 4.2    ,prettyprinter >= 1.6 && < 2.0+   ,semialign >= 1 && < 2    ,text >= 1.0 && < 2.2+   ,these >= 1 && < 2   if !impl(ghc >= 8.0)     build-depends:       semigroups >= 0.8.4 && < 1
src/PropertyMatchers.hs view
@@ -38,30 +38,38 @@   , match   , atIndex   , list-  , propful+  , alignExact+  , alignLax+  , elem   , compose   , allTrue   , allOf1   , pair   , fun+  , fails   , traced   , tracedShow   , traceFailShow   , traceFail   , forced   , equals+  , lt+  , lte+  , gt+  , gte   , bool   , pattern (:=>)   , (?)   )   where -import Prelude hiding (and, fail, or)+import Prelude hiding (and, elem, fail, or) import Control.Concurrent (myThreadId) import Control.Exception-import Control.Monad hiding (fail)+import qualified Data.Align as Align import Data.Foldable (toList) import Data.Functor.Const+import Data.These import Data.Typeable import Debug.Trace import GHC.Stack@@ -255,20 +263,53 @@   where   psl = length ps --- | Given a functor-full of properties, and a functor-full of values, ensure--- that the structures of the two functors match and apply all of the properties--- to all of the values.+-- | Given a functor-full of properties, and a functor-full of values, align+-- the two together and apply all of the properties to the values pointwise.+-- If there is any misalignment between the two, fail. -- Generalized version of `list`.-propful ::-  (HasCallStack, Eq (f ()), Functor f, Foldable f) =>+alignExact+  :: (HasCallStack, Traversable f, Align.Semialign f) =>   f (Prop a) ->   Prop (f a)-propful props values-  | void props == void values =-    list (toList props) (toList values)-  | otherwise =-    fail ("shape equal to that of" <> PP.pretty (anythingToTextPretty props)) values+alignExact props values =+  sequence_ $ Align.alignWith+    (\case+      This _extraProp -> fail ("no extra elements relative to " <> PP.pretty (anythingToTextPretty props)) values+      That _extraValue -> fail ("no missing elements relative to " <> PP.pretty (anythingToTextPretty props)) values+      These prop value -> prop value+      )+    props values +-- | Given a functor-full of properties and a functor-full of values+-- (and a property for excess values) align the properties and values and apply+-- them to each other pointwise. If there is any misalignment between the two:+--   * if there's an excess value, apply the excess property to it+--   * if there's a missing value, pass the corresponding property `Nothing`+-- Examples:+-- alignLax (Map.fromList ["k" :=> P.lt 3, "g" :=> P.match P.gt 4]) (Map.fromList )+alignLax+  :: (Traversable f, Align.Semialign f) =>+  Prop a ->+  f (Prop (Maybe a)) ->+  Prop (f a)+alignLax excess props values = sequence_ $ Align.alignWith+  (\case+    This prop -> prop Nothing+    That extraValue -> excess extraValue+    These prop value -> prop (Just value)+    )+  props values++-- | Given a property and a traversable functor-full of values,+-- succeed if the property succeeds on at least one of the values.+elem+  :: (HasCallStack, Traversable f) =>+  Prop a ->+  Prop (f a)+elem prop values+  | null values = fail "nonempty value" values+  | otherwise = foldr1 or $ prop <$> values+ -- | Given a representable functor-full of properties, and a functor-full of values, --  yield a representable functor-full of booleans. Similar to `propful`. compose ::@@ -305,6 +346,11 @@ fun :: (a -> b) -> PT b a fun f p = p . f +fails :: Exception e => Prop e -> Prop (IO a)+fails p actual = trySync actual >>= \case+  Left e -> p e+  Right r -> fail "a failed computation" r+ -- | Prints the input of a property, if the property fails, using `Show`. --   Requires that the property's output type can be checked for failure. traceFailShow :: Show a => PT a a@@ -339,6 +385,26 @@   | expected == actual = succeed actual   | otherwise = fail (PP.pretty (anythingToTextPretty expected)) actual +lt :: (HasCallStack, Ord a) => a -> Prop a+lt expected actual+  | actual < expected = succeed actual+  | otherwise = fail ("less than " <> PP.pretty (anythingToTextPretty expected)) actual++gt :: (HasCallStack, Ord a) => a -> Prop a+gt expected actual+  | actual > expected = succeed actual+  | otherwise = fail ("greater than " <> PP.pretty (anythingToTextPretty expected)) actual++gte :: (HasCallStack, Ord a) => a -> Prop a+gte expected actual+  | actual >= expected = succeed actual+  | otherwise = fail ("greater than/equal to " <> PP.pretty (anythingToTextPretty expected)) actual++lte :: (HasCallStack, Ord a) => a -> Prop a+lte expected actual+  | actual <= expected = succeed actual+  | otherwise = fail ("less than/equal to " <> PP.pretty (anythingToTextPretty expected)) actual+ bool :: HasCallStack => Bool -> Assertion bool b   | b = succeed b@@ -349,6 +415,7 @@ -- `(x :: Either Int Int) & branch [match _Left :=> equals 1, match _Right :=> equals 2]` pattern (:=>) :: a -> b -> (a, b) pattern a :=> b = (a, b)+infixr 7 :=>  -- | Higher precedence '$', to work well with '&'. -- The intended use is something like `x & match _Right ? equals 2`.