packages feed

abides (empty) → 0.0.0

raw patch · 21 files changed

+444/−0 lines, 21 filesdep +abidesdep +basedep +comonadsetup-changed

Dependencies added: abides, base, comonad, tasty, tasty-quickcheck

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for abides++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Athan Clark (c) 2019++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,7 @@+# abides+++![](https://github.com/athanclark/abides/raw/master/images/the_dude.jpg)+++Just a bunch of functions that make sure a class abides by its laws, man.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ abides.cabal view
@@ -0,0 +1,70 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: f1fefe867335372cccdb4d04ab5a2e0285abcc0e8080fbce2e12adf70dc571bd++name:           abides+version:        0.0.0+synopsis:       Simple boolean tests to see if a value abides by certain properties+description:    Please see the README on GitHub at <https://github.com/athanclark/abides#readme>+category:       Data, Testing+homepage:       https://github.com/athanclark/abides#readme+bug-reports:    https://github.com/athanclark/abides/issues+author:         Athan Clark+maintainer:     athan.clark@gmail.com+copyright:      2019 Athan Clark+license:        BSD3+license-file:   LICENSE+build-type:     Simple+extra-source-files:+    README.md+    ChangeLog.md++source-repository head+  type: git+  location: https://github.com/athanclark/abides++library+  exposed-modules:+      Test.Abides+      Test.Abides.Control.Alternative+      Test.Abides.Control.Applicative+      Test.Abides.Control.Category+      Test.Abides.Control.Comonad+      Test.Abides.Control.Monad+      Test.Abides.Data.Bounded+      Test.Abides.Data.Enum+      Test.Abides.Data.Eq+      Test.Abides.Data.Foldable+      Test.Abides.Data.Functor+      Test.Abides.Data.Monoid+      Test.Abides.Data.Ord+      Test.Abides.Data.Semigroup+      Test.Abides.Properties+  other-modules:+      Paths_abides+  hs-source-dirs:+      src+  build-depends:+      base >=4.7 && <5+    , comonad+  default-language: Haskell2010++test-suite abides-test+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  other-modules:+      Paths_abides+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      abides+    , base >=4.7 && <5+    , comonad+    , tasty+    , tasty-quickcheck+  default-language: Haskell2010
+ src/Test/Abides.hs view
@@ -0,0 +1,2 @@+module Test.Abides where+
+ src/Test/Abides/Control/Alternative.hs view
@@ -0,0 +1,13 @@+module Test.Abides.Control.Alternative where++import Control.Applicative (Alternative ((<|>)), empty)+++-- | (f <|> g) <*> x == (f <*> x) <|> (g <|> x)+distributive :: Alternative f => Applicative f => Eq (f b) => f (a -> b) -> f (a -> b) -> f a -> Bool+distributive f g x = ((f <|> g) <*> x) == ((f <*> x) <|> (g <*> x))+++-- | empty <*> x == empty+annihilation :: Alternative f => Applicative f => Eq (f b) => f (a -> b) -> Bool+annihilation f = (f <*> empty) == empty
+ src/Test/Abides/Control/Applicative.hs view
@@ -0,0 +1,28 @@+{-# LANGUAGE+    RankNTypes+  , ScopedTypeVariables+  #-}++module Test.Abides.Control.Applicative where+++identity :: Applicative f => Eq (f a) => f a -> Bool+identity x = (pure id <*> x) == x+++composition :: Applicative f => Eq (f c) => f (b -> c) -> f (a -> b) -> f a -> Bool+composition f g h = (pure (.) <*> f <*> g <*> h) == (f <*> (g <*> h))+++-- FIXME ambiguous type?+-- homomorphism :: forall f a b. Applicative f => Eq (f b) => (a -> b) -> a -> Bool+-- homomorphism f x = (f' <*> x') == y'+--   where+--     f' :: f (a -> b)+--     f' = pure f++--     x' :: f a+--     x' = pure x++--     y' :: f b+--     y' = pure (f x)
+ src/Test/Abides/Control/Category.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Test.Abides.Control.Category where++import Prelude hiding ((.), id)+import Control.Category (Category ((.), id))+++identity :: Category c => Eq (c a b) => c a b -> Bool+identity p = ((id . p) == p) && ((p . id) == p)+++associative :: Category q => Eq (q a d) => q c d -> q b c -> q a b -> Bool+associative x y z = (x . (y . z)) == ((x . y) . z)
+ src/Test/Abides/Control/Comonad.hs view
@@ -0,0 +1,15 @@+module Test.Abides.Control.Comonad where++import Control.Comonad (Comonad (extend, extract), (<<=))+++leftIdentity :: Comonad w => Eq (w a) => w a -> Bool+leftIdentity x = (extract <<= x) == x+++rightIdentity :: Comonad w => Eq a => (w a -> a) -> w a -> Bool+rightIdentity f x = extract (f <<= x) == f x+++associative :: Comonad w => Eq (w c) => (w b -> c) -> (w a -> b) -> w a -> Bool+associative f g x = extend f (extend g x) == extend (f . extend g) x
+ src/Test/Abides/Control/Monad.hs view
@@ -0,0 +1,24 @@+module Test.Abides.Control.Monad where+++import Control.Monad (MonadPlus (mzero, mplus))+++leftIdentity :: Monad m => Eq (m b) => (a -> m b) -> a -> Bool+leftIdentity f x = (pure x >>= f) == f x+++rightIdentity :: Monad m => Eq (m a) => m a -> Bool+rightIdentity x = (x >>= pure) == x+++associative :: Monad m => Eq (m c) => (a -> m b) -> (b -> m c) -> m a -> Bool+associative f g x = ((x >>= f) >>= g) == (x >>= (\k -> f k >>= g))+++annihilation :: MonadPlus m => Eq (m b) => (a -> m b) -> Bool+annihilation f = (mzero >>= f) == mzero+++distributive :: MonadPlus m => Eq (m b) => (a -> m b) -> m a -> m a -> Bool+distributive f x y = (mplus x y >>= f) == mplus (x >>= f) (y >>= f)
+ src/Test/Abides/Data/Bounded.hs view
@@ -0,0 +1,5 @@+module Test.Abides.Data.Bounded where++-- | minBound <= x <= maxBound?+bounded :: Bounded a => Ord a => a -> Bool+bounded x = minBound <= x && x <= maxBound
+ src/Test/Abides/Data/Enum.hs view
@@ -0,0 +1,16 @@+module Test.Abides.Data.Enum where+++-- | compare x y == compare (fromEnum x) (fromEnum y)+compareHom :: Enum a => Ord a => a -> a -> Bool+compareHom x y = compare x y == compare (fromEnum x) (fromEnum y)+++-- | pred (succ x) == x+predsucc :: Enum a => Eq a => a -> Bool+predsucc x = pred (succ x) == x+++-- | succ (pred x) == x+succpred :: Enum a => Eq a => a -> Bool+succpred x = succ (pred x) == x
+ src/Test/Abides/Data/Eq.hs view
@@ -0,0 +1,23 @@+module Test.Abides.Data.Eq+  ( P.reflexive+  , symmetry+  , transitive+  , negation+  ) where++import qualified Test.Abides.Properties as P+++-- | x == y => y == x?+symmetry :: Eq a => a -> a -> Bool+symmetry x y = if x == y then y == x else True+++-- | x == y && y == z => x == z+transitive :: Eq a => a -> a -> a -> Bool+transitive x y z = if x == y && y == z then x == z else True+++-- | x /= y => not (x == y)+negation :: Eq a => a -> a -> Bool+negation x y = if x /= y then not (x == y) else True
+ src/Test/Abides/Data/Foldable.hs view
@@ -0,0 +1,8 @@+module Test.Abides.Data.Foldable where++import Data.Foldable (fold)+++-- | fold (map f x) == foldMap f x+foldMap' :: Foldable f => Functor f => Monoid b => Eq b => (a -> b) -> f a -> Bool+foldMap' f x = fold (fmap f x) == foldMap f x
+ src/Test/Abides/Data/Functor.hs view
@@ -0,0 +1,10 @@+module Test.Abides.Data.Functor where+++-- | fmap id x == x?+identity :: Functor f => Eq (f a) => f a -> Bool+identity x = fmap id x == x++-- | fmap (f . g) x == fmap f (fmap g x)?+composition :: Functor f => Eq (f a) => (a -> a) -> (a -> a) -> f a -> Bool+composition f g x = fmap (f . g) x == fmap f (fmap g x)
+ src/Test/Abides/Data/Monoid.hs view
@@ -0,0 +1,11 @@+module Test.Abides.Data.Monoid where++import Test.Abides.Properties (constL, constR)+++leftIdentity :: Monoid a => Eq a => a -> Bool+leftIdentity = constR (<>) mempty+++rightIdentity :: Monoid a => Eq a => a -> Bool+rightIdentity x = constL (<>) x mempty
+ src/Test/Abides/Data/Ord.hs view
@@ -0,0 +1,16 @@+module Test.Abides.Data.Ord where+++-- | x <= x?+reflexive :: Ord a => a -> Bool+reflexive x = x <= x+++-- | x <= y && y <= x => x == y+antisymmetry :: Ord a => a -> a -> Bool+antisymmetry x y = if x <= y && y <= x then x == y else True+++-- | x <= y && y <= z => x <= z+transitive :: Ord a => a -> a -> a -> Bool+transitive x y z = if x <= y && y <= z then x <= z else True
+ src/Test/Abides/Data/Semigroup.hs view
@@ -0,0 +1,7 @@+module Test.Abides.Data.Semigroup where++import qualified Test.Abides.Properties as P+++associative :: Semigroup a => Eq a => a -> a -> a -> Bool+associative = P.associative (<>)
+ src/Test/Abides/Properties.hs view
@@ -0,0 +1,31 @@+module Test.Abides.Properties where+++-- | x == x?+reflexive :: Eq a => a -> Bool+reflexive x = x == x++-- | f x y == f y x?+commutative :: Eq b => (a -> a -> b) -> a -> a -> Bool+commutative f x y = f x y == f y x++-- | f (f x y) z == f x (f y z)?+associative :: Eq a => (a -> a -> a) -> a -> a -> a -> Bool+associative f x y z = f (f x y) z == f x (f y z)++-- | f (f x) == f x?+idempotent :: Eq a => (a -> a) -> a -> Bool+idempotent f x = f (f x) == f x++-- | f (g x y) == g (f x) (f y)?+distributive :: Eq a => (a -> a) -> (a -> a -> a) -> a -> a -> Bool+distributive f g x y = f (g x y) == g (f x) (f y)++-- | f x y == x? Note: bottom ~ forall y. f bottom y == bottom, while unit ~ forall x. f x unit == x+constL :: Eq a => (a -> a -> a) -> a -> a -> Bool+constL f x y = f x y == x++-- | f x y == y?+constR :: Eq a => (a -> a -> a) -> a -> a -> Bool+constR f x y = f x y == y+
+ test/Spec.hs view
@@ -0,0 +1,109 @@+import qualified Test.Abides.Control.Alternative as Alt+import qualified Test.Abides.Control.Applicative as App+import qualified Test.Abides.Control.Category as Cat+import qualified Test.Abides.Control.Comonad as Com+import qualified Test.Abides.Control.Monad as Mon+import qualified Test.Abides.Data.Bounded as Bou+import qualified Test.Abides.Data.Enum as Enu+import qualified Test.Abides.Data.Eq as Eq+import qualified Test.Abides.Data.Foldable as Fol+import qualified Test.Abides.Data.Functor as Fun+import qualified Test.Abides.Data.Monoid as Mono+import qualified Test.Abides.Data.Ord as Ord+import qualified Test.Abides.Data.Semigroup as Sem++import Test.Tasty (defaultMain, testGroup)+import Test.Tasty.QuickCheck (testProperty)++import Data.Monoid (Sum (..))++++main :: IO ()+main = defaultMain $ testGroup "All Tests"+  [ testGroup "Test.Abides.Control"+    [ testProperty "Alternative" alternativeTests+    , testProperty "Applicative" applicativeTests+    -- , testProperty "Category" categoryTests+    , testProperty "Comonad" comonadTests+    , testProperty "Monad" monadTests+    , testProperty "MonadPlus" monadPlusTests+    ]+  , testGroup "Test.Abides.Data"+    [ testProperty "Bounded" boundedTests+    , testProperty "Enum" enumTests+    , testProperty "Eq" eqTests+    , testProperty "Foldable" foldableTests+    , testProperty "Functor" functorTests+    , testProperty "Monoid" monoidTests+    , testProperty "Ord" ordTests+    , testProperty "Semigroup" semigroupTests+    ]+  ]+  where+    alternativeTests :: [Int] -> Bool+    alternativeTests x = and+      [ Alt.distributive [(+ 1)] [(* 2)] x+      , Alt.annihilation (map (+) x)+      ]+    applicativeTests :: [Int] -> Bool+    applicativeTests x = and+      [ App.identity x+      , App.composition [(+ 1)] [(* 2)] x+      ]+    -- categoryTests :: Kleisli [] Int Int -> Bool+    -- categoryTests x = and+    --   [ Cat.identity x+    --   , App.composition [(+ 1)] [(* 2)] x+    --   ]+    comonadTests :: (Int,Int) -> Bool+    comonadTests x = and+      [ Com.leftIdentity x+      , Com.rightIdentity (\(a,b) -> b + 1) x+      , Com.associative (\(a,b) -> b * 2) (\(a,b) -> b + 1) x+      ]+    monadTests :: [Int] -> Bool+    monadTests x = and+      [ Mon.leftIdentity (\a -> [a] ++ x) 5+      , Mon.rightIdentity x+      , Mon.associative (\a -> [a,1]) (\a -> [2,a]) x+      ]+    monadPlusTests :: Maybe Int -> Bool+    monadPlusTests x = and+      [ Mon.annihilation (\a -> Just (a + 1))+      , Mon.distributive (\a -> Just (a + 1)) x (Just 5)+      ]+    boundedTests :: Int -> Bool+    boundedTests x = Bou.bounded x+    enumTests :: Int -> Bool+    enumTests x = and+      [ Enu.compareHom x 1+      , Enu.predsucc x+      , Enu.succpred x+      ]+    eqTests :: (Int,Int) -> Bool+    eqTests (x,y) = and+      [ Eq.symmetry x y+      , Eq.transitive x y x+      , Eq.negation x y+      ]+    foldableTests :: [Sum Int] -> Bool+    foldableTests x = Fol.foldMap' (+ (Sum 5)) x+    functorTests :: [Int] -> Bool+    functorTests x = and+      [ Fun.identity x+      , Fun.composition (+ 5) (* 2) x+      ]+    monoidTests :: Sum Int -> Bool+    monoidTests x = and+      [ Mono.leftIdentity x+      , Mono.rightIdentity x+      ]+    ordTests :: (Int,Int) -> Bool+    ordTests (x,y) = and+      [ Ord.reflexive x+      , Ord.antisymmetry x y+      , Ord.transitive x y x+      ]+    semigroupTests :: (Sum Int, Sum Int, Sum Int) -> Bool+    semigroupTests (x,y,z) = Sem.associative x y z