packages feed

leancheck 0.6.4 → 0.6.5

raw patch · 14 files changed

+213/−194 lines, 14 filesdep +leancheck

Dependencies added: leancheck

Files

TODO.md view
@@ -16,42 +16,21 @@  * add diff test for IO functions (diff w/ model output and exit status) -* (?) on leancheck.cabal, add upper bound for template-haskell package -* Show when test cases are exhausted after testing:--	> check $ \p -> p == (p :: Bool)-	+++ OK, passed 2 tests (test cases exhausted).--  Instead of just:--	> check $ \p -> p == (p :: Bool)-	+++ OK, passed 2 tests.-- documentation ------------- -* add eg folder with some examples of testing using LeanCheck;- * on tutorial.md, write about how to create test programs;  * on data-invariant.md, write missing section;  -v0.6.5+v0.6.6 ------ -* Document `X` and `Xs` on `Utils.Types`.- * On `bench/tiers`, print if the enumeration has repetitions   (import `Function.Eq` for that) -* Add `names` function to the ShowFunction typeclass that lists templates of-  names for variables of the type.-  Sadly, there is no way to do this without introducing a typeclass restriction-  on function arguments.  Make a separate `Argument` typeclass to do that?- * add `classify` function to measure distribution of data:   something like: @@ -81,7 +60,7 @@   so that the user gets an enumeration of functions with repetitions, but using   a mixed strategy for generation of values. -v0.6.6+v0.6.7 ------  * implement stub `Test.LeanCheck.Function.*` modules;
leancheck.cabal view
@@ -11,7 +11,7 @@ -- this cabal file too complicated.  -- Rudy  name:                leancheck-version:             0.6.4+version:             0.6.5 synopsis:            Cholesterol-free property-based testing description:   LeanCheck is a simple enumerative property-based testing library.@@ -50,7 +50,7 @@ source-repository this   type:            git   location:        https://github.com/rudymatela/leancheck-  tag:             v0.6.4+  tag:             v0.6.5  library   exposed-modules: Test.LeanCheck@@ -72,7 +72,6 @@                  , Test.LeanCheck.Function.Periodic                  , Test.LeanCheck.Function.Show                  , Test.LeanCheck.Function.ShowFunction-  other-modules:   Test.LeanCheck.Invariants   hs-source-dirs:      src   build-depends:       base >= 4 && < 5, template-haskell   default-language:    Haskell2010@@ -80,41 +79,47 @@ test-suite test   type:                exitcode-stdio-1.0   main-is:             test.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010  test-suite types   type:                exitcode-stdio-1.0   main-is:             test-types.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010  test-suite tiers   type:                exitcode-stdio-1.0   main-is:             test-tiers.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010  test-suite operators   type:                exitcode-stdio-1.0   main-is:             test-operators.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010  test-suite derive   type:                exitcode-stdio-1.0   main-is:             test-derive.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010  test-suite error   type:                exitcode-stdio-1.0   main-is:             test-error.hs-  hs-source-dirs:      src, tests-  build-depends:       base >= 4 && < 5, template-haskell+  other-modules:       Test+  hs-source-dirs:      tests+  build-depends:       base >= 4 && < 5, leancheck   default-language:    Haskell2010
src/Test/LeanCheck/Core.hs view
@@ -158,7 +158,7 @@ instance Listable Bool where   tiers = cons0 False \/ cons0 True --- | > tiers :: [[Maybe Int]] = [[Nothing], [Just 0], [Just 1], [Just -1], ...]+-- | > tiers :: [[Maybe Int]] = [[Nothing], [Just 0], [Just 1], ...] --   > tiers :: [[Maybe Bool]] = [[Nothing], [Just False, Just True]] instance Listable a => Listable (Maybe a) where   tiers = cons0 Nothing \/ cons1 Just@@ -167,8 +167,12 @@   tiers = reset (cons1 Left)      \\// reset (cons1 Right) --- | > tiers :: [[(Int,Int)]] = [ [(0,0)], [(0,1),(1,0)], [(0,-1),(1,1),(-1,0)], ...]---   > list :: [(Int,Int)] = [ (0,0), (0,1), (1,0), (0,-1), (1,1), (-1,0), ...]+-- | > tiers :: [[(Int,Int)]] =+--   > [ [(0,0)]+--   > , [(0,1),(1,0)]+--   > , [(0,-1),(1,1),(-1,0)]+--   > , ...]+--   > list :: [(Int,Int)] = [ (0,0), (0,1), (1,0), (0,-1), (1,1), ...] instance (Listable a, Listable b) => Listable (a,b) where   tiers = tiers >< tiers @@ -191,7 +195,7 @@ --   >                        , [ [0,0], [1] ] --   >                        , [ [0,0,0], [0,1], [1,0], [-1] ] --   >                        , ... ]---   > list :: [ [Int] ] = [ [], [0], [0,0], [1], [0,0,0], [0,1], [1,0], [-1], ... ]+--   > list :: [ [Int] ] = [ [], [0], [0,0], [1], [0,0,0], ... ] instance (Listable a) => Listable [a] where   tiers = cons0 []        \/ cons2 (:)
src/Test/LeanCheck/IO.hs view
@@ -46,7 +46,7 @@ --   returning 'True' on success. -- -- There is no option to silence this function:--- for silence, you should use 'TestLean.Check.holds'.+-- for silence, you should use 'Test.LeanCheck.holds'. checkResult :: Testable a => a -> IO Bool checkResult p = checkResultFor 200 p 
− src/Test/LeanCheck/Invariants.hs
@@ -1,148 +0,0 @@--- |--- Module      : Test.LeanCheck.Invariants--- Copyright   : (c) 2015-2017 Rudy Matela--- License     : 3-Clause BSD  (see the file LICENSE)--- Maintainer  : Rudy Matela <rudy@matela.com.br>------ This module is part of LeanCheck,--- a simple enumerative property-based testing library.------ Some invariants about Test.LeanCheck functions.------ You should be importing this ONLY to test "Test.LeanCheck" itself.-module Test.LeanCheck.Invariants-  ( tNatPairOrd-  , tNatTripleOrd-  , tNatQuadrupleOrd-  , tNatQuintupleOrd-  , tNatSixtupleOrd-  , tNatListOrd-  , tListsOfNatOrd-  , tPairEqParams-  , tTripleEqParams-  , tProductsIsFilterByLength--  , ordered-  , orderedBy-  , orderedOn-  , strictlyOrdered-  , strictlyOrderedBy-  , strictlyOrderedOn-  )-where--import Test.LeanCheck-import Data.List-import Data.Ord-import Test.LeanCheck.Utils.Types (Nat(..))---- | check if a list is ordered-ordered :: Ord a => [a] -> Bool-ordered = orderedBy compare--- ordered [] = True--- ordered [_] = True--- ordered (x:y:xs) = x <= y && ordered (y:xs)--strictlyOrdered :: Ord a => [a] -> Bool-strictlyOrdered = strictlyOrderedBy compare---- | check if a list is ordered by a given ordering function-orderedBy :: (a -> a -> Ordering) -> [a] -> Bool-orderedBy _ [] = True-orderedBy _ [_] = True-orderedBy cmp (x:y:xs) = case x `cmp` y of-                           GT -> False-                           _  -> orderedBy cmp (y:xs)--orderedOn :: Ord b => (a -> b) -> [a] -> Bool-orderedOn f = orderedBy (comparing f)---- | check if a list is strictly ordered by a given ordering function-strictlyOrderedBy :: (a -> a -> Ordering) -> [a] -> Bool-strictlyOrderedBy _ [] = True-strictlyOrderedBy _ [_] = True-strictlyOrderedBy cmp (x:y:xs) = case x `cmp` y of-                                   LT -> strictlyOrderedBy cmp (y:xs)-                                   _  -> False--strictlyOrderedOn :: Ord b => (a -> b) -> [a] -> Bool-strictlyOrderedOn f = strictlyOrderedBy (comparing f)--ifNotEq :: Ordering -> Ordering -> Ordering--- Could be implemented as:  ifNotEq = mappend-ifNotEq EQ p = p-ifNotEq  o _ = o--thn :: (a->a->Ordering) -> (a->a->Ordering) -> a -> a -> Ordering-thn cmp1 cmp2 x y = (x `cmp1` y) `ifNotEq` (x `cmp2` y)-infixr 9 `thn`----- | checks if the first 'n' elements on tiers are ordered by 'cmp'.------ > (n `seriesOrderedBy`) comparing (id :: Type)-tOrderedBy :: Listable a => Int -> (a -> a -> Ordering) -> Bool-tOrderedBy n cmp = orderedBy cmp $ take n list-infixr 9 `tOrderedBy`--tStrictlyOrderedBy :: Listable a => Int -> (a -> a -> Ordering) -> Bool-tStrictlyOrderedBy n cmp = strictlyOrderedBy cmp $ take n list-infixr 9 `tStrictlyOrderedBy`--tNatPairOrd :: Int -> Bool-tNatPairOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' (x,y) = x+y :: Nat--tNatTripleOrd :: Int -> Bool-tNatTripleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' (x,y,z) = x+y+z :: Nat--tNatQuadrupleOrd :: Int -> Bool-tNatQuadrupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' (x,y,z,w) = x+y+z+w :: Nat--tNatQuintupleOrd :: Int -> Bool-tNatQuintupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' (x,y,z,w,v) = x+y+z+w+v :: Nat--tNatSixtupleOrd :: Int -> Bool-tNatSixtupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' (x,y,z,w,v,u) = x+y+z+w+v+u :: Nat--tNatListOrd :: Int -> Bool-tNatListOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare-  where sum' = sum . map (+1) :: [Nat] -> Nat--tListsOfStrictlyOrderedBy :: Int-                           -> (a -> a -> Ordering)-                           -> [[a]]-                           -> Bool-tListsOfStrictlyOrderedBy n cmp = strictlyOrderedBy cmp . take n . concat-infixr 9 `tListsOfStrictlyOrderedBy`--tListsOfNatOrd :: Int -> Bool-tListsOfNatOrd n = tListsOfStrictlyOrderedBy n (comparing sum' `thn` compare) tiers-  where sum' = sum . map (+1) :: [Nat] -> Nat--tPairEqParams :: Int -> Bool-tPairEqParams n = ces == srs-  where-    ces = map (map read) $ counterExamples n fail-    srs = map pairToList $ take n list-    pairToList (x,y) = [x,y :: Nat]-    fail :: Nat -> Nat -> Bool-    fail x y = False--tTripleEqParams :: Int -> Bool-tTripleEqParams n = ces == srs-  where-    ces = map (map read) $ counterExamples n fail-    srs = map tripleToList $ take n list-    tripleToList (x,y,z) = [x,y,z :: Nat]-    fail :: Nat -> Nat -> Nat -> Bool-    fail x y z = False--tProductsIsFilterByLength :: Eq a => [[a]] -> Int -> Int -> Bool-tProductsIsFilterByLength values m n = concat (take m byProduct) `isPrefixOf` concat byFilter-  where byProduct = products $ replicate n values-        byFilter  = ((==n) . length) `filterT` listsOf values
src/Test/LeanCheck/Utils/TypeBinding.hs view
@@ -92,6 +92,7 @@   , int, integer   , float, double   , char, string+  , ordering   , mayb, eith   -- ** Testing types   , nat@@ -289,6 +290,9 @@  string :: String string = undefinedOf "string"++ordering :: Ordering+ordering = undefinedOf "ordering"  -- | It might be better to just use 'Just' mayb :: a -> Maybe a
src/Test/LeanCheck/Utils/Types.hs view
@@ -465,9 +465,26 @@ instance Listable a => Listable (Bag a)   where tiers = bagCons Bag instance Listable a => Listable (Set a)   where tiers = setCons Set +-- | 'X' type to be wrapped around integer types for an e-'X'-treme integer+--   enumeration.  See the 'Listable' instance for 'X'.  Use 'X' when+--   testing properties about overflows and the like:+--+-- > > check $ \x -> x + 1 > (x :: Int)+-- > +++ OK, passed 200 tests.+--+-- > > check $ \(X x) -> x + 1 > (x :: Int)+-- > +++ Failed! Falsifiable (after 4 tests):+-- > 9223372036854775807 newtype X a = X {unX :: a} deriving (Eq, Ord) instance Show a => Show (X a) where show (X x) = show x instance (Integral a, Bounded a) => Listable (X a) where list = map X listXIntegral+-- ^ Extremily large integers are intercalated with small integers.+--+--   > list :: [X Int] = map X+--   >   [ 0, 1, -1, maxBound,   minBound+--   >      , 2, -2, maxBound-1, minBound+1+--   >      , 3, -3, maxBound-2, minBound+2+--   >      , ... ]  -- FIXME: make this work for Int2 / Word2 types --        by checking then using normal enumeration@@ -516,3 +533,4 @@ instance Show a => Show (Xs a) where show (Xs xs) = show xs instance (Integral a, Bounded a) => Listable (Xs a) where   tiers = cons1 (Xs . map unX)+-- ^ Lists with elements of the 'X' type.
+ tests/Test.hs view
@@ -0,0 +1,148 @@+-- |+-- Module      : Test+-- Copyright   : (c) 2015-2017 Rudy Matela+-- License     : 3-Clause BSD  (see the file LICENSE)+-- Maintainer  : Rudy Matela <rudy@matela.com.br>+--+-- This module is part of LeanCheck,+-- a simple enumerative property-based testing library.+--+-- Some helper functios to test LeanCheck itself.+module Test+  ( module Test.LeanCheck++  , tNatPairOrd+  , tNatTripleOrd+  , tNatQuadrupleOrd+  , tNatQuintupleOrd+  , tNatSixtupleOrd+  , tNatListOrd+  , tListsOfNatOrd+  , tPairEqParams+  , tTripleEqParams+  , tProductsIsFilterByLength++  , ordered+  , orderedBy+  , orderedOn+  , strictlyOrdered+  , strictlyOrderedBy+  , strictlyOrderedOn+  )+where++import Test.LeanCheck+import Data.List+import Data.Ord+import Test.LeanCheck.Utils.Types (Nat(..))++-- | check if a list is ordered+ordered :: Ord a => [a] -> Bool+ordered = orderedBy compare+-- ordered [] = True+-- ordered [_] = True+-- ordered (x:y:xs) = x <= y && ordered (y:xs)++strictlyOrdered :: Ord a => [a] -> Bool+strictlyOrdered = strictlyOrderedBy compare++-- | check if a list is ordered by a given ordering function+orderedBy :: (a -> a -> Ordering) -> [a] -> Bool+orderedBy _ [] = True+orderedBy _ [_] = True+orderedBy cmp (x:y:xs) = case x `cmp` y of+                           GT -> False+                           _  -> orderedBy cmp (y:xs)++orderedOn :: Ord b => (a -> b) -> [a] -> Bool+orderedOn f = orderedBy (comparing f)++-- | check if a list is strictly ordered by a given ordering function+strictlyOrderedBy :: (a -> a -> Ordering) -> [a] -> Bool+strictlyOrderedBy _ [] = True+strictlyOrderedBy _ [_] = True+strictlyOrderedBy cmp (x:y:xs) = case x `cmp` y of+                                   LT -> strictlyOrderedBy cmp (y:xs)+                                   _  -> False++strictlyOrderedOn :: Ord b => (a -> b) -> [a] -> Bool+strictlyOrderedOn f = strictlyOrderedBy (comparing f)++ifNotEq :: Ordering -> Ordering -> Ordering+-- Could be implemented as:  ifNotEq = mappend+ifNotEq EQ p = p+ifNotEq  o _ = o++thn :: (a->a->Ordering) -> (a->a->Ordering) -> a -> a -> Ordering+thn cmp1 cmp2 x y = (x `cmp1` y) `ifNotEq` (x `cmp2` y)+infixr 9 `thn`+++-- | checks if the first 'n' elements on tiers are ordered by 'cmp'.+--+-- > (n `seriesOrderedBy`) comparing (id :: Type)+tOrderedBy :: Listable a => Int -> (a -> a -> Ordering) -> Bool+tOrderedBy n cmp = orderedBy cmp $ take n list+infixr 9 `tOrderedBy`++tStrictlyOrderedBy :: Listable a => Int -> (a -> a -> Ordering) -> Bool+tStrictlyOrderedBy n cmp = strictlyOrderedBy cmp $ take n list+infixr 9 `tStrictlyOrderedBy`++tNatPairOrd :: Int -> Bool+tNatPairOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' (x,y) = x+y :: Nat++tNatTripleOrd :: Int -> Bool+tNatTripleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' (x,y,z) = x+y+z :: Nat++tNatQuadrupleOrd :: Int -> Bool+tNatQuadrupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' (x,y,z,w) = x+y+z+w :: Nat++tNatQuintupleOrd :: Int -> Bool+tNatQuintupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' (x,y,z,w,v) = x+y+z+w+v :: Nat++tNatSixtupleOrd :: Int -> Bool+tNatSixtupleOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' (x,y,z,w,v,u) = x+y+z+w+v+u :: Nat++tNatListOrd :: Int -> Bool+tNatListOrd n = n `tStrictlyOrderedBy`  comparing sum' `thn` compare+  where sum' = sum . map (+1) :: [Nat] -> Nat++tListsOfStrictlyOrderedBy :: Int+                           -> (a -> a -> Ordering)+                           -> [[a]]+                           -> Bool+tListsOfStrictlyOrderedBy n cmp = strictlyOrderedBy cmp . take n . concat+infixr 9 `tListsOfStrictlyOrderedBy`++tListsOfNatOrd :: Int -> Bool+tListsOfNatOrd n = tListsOfStrictlyOrderedBy n (comparing sum' `thn` compare) tiers+  where sum' = sum . map (+1) :: [Nat] -> Nat++tPairEqParams :: Int -> Bool+tPairEqParams n = ces == srs+  where+    ces = map (map read) $ counterExamples n fail+    srs = map pairToList $ take n list+    pairToList (x,y) = [x,y :: Nat]+    fail :: Nat -> Nat -> Bool+    fail x y = False++tTripleEqParams :: Int -> Bool+tTripleEqParams n = ces == srs+  where+    ces = map (map read) $ counterExamples n fail+    srs = map tripleToList $ take n list+    tripleToList (x,y,z) = [x,y,z :: Nat]+    fail :: Nat -> Nat -> Nat -> Bool+    fail x y z = False++tProductsIsFilterByLength :: Eq a => [[a]] -> Int -> Int -> Bool+tProductsIsFilterByLength values m n = concat (take m byProduct) `isPrefixOf` concat byFilter+  where byProduct = products $ replicate n values+        byFilter  = ((==n) . length) `filterT` listsOf values
tests/test-derive.hs view
@@ -1,8 +1,9 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE). {-# LANGUAGE TemplateHaskell, CPP #-}-import Test.LeanCheck.Derive+import Test import Test.LeanCheck+import Test.LeanCheck.Derive import System.Exit (exitFailure) import Data.List (elemIndices) import Test.LeanCheck.Utils.Operators
tests/test-error.hs view
@@ -1,5 +1,7 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Test ()+ import System.Exit (exitFailure) import Data.List (elemIndices,sort) 
tests/test-operators.hs view
@@ -1,5 +1,7 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Test+ import System.Exit (exitFailure) import Data.List (elemIndices,sort) import Test.LeanCheck
tests/test-tiers.hs view
@@ -1,10 +1,11 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Test+ import System.Exit (exitFailure) import Data.List (elemIndices, sort, nub, delete)  import Test.LeanCheck-import Test.LeanCheck.Invariants import Test.LeanCheck.Utils  import Test.LeanCheck.Tiers
tests/test-types.hs view
@@ -1,5 +1,6 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Test import System.Exit (exitFailure) import Data.List (elemIndices,delete,isPrefixOf) import Test.LeanCheck.Utils.Types
tests/test.hs view
@@ -1,10 +1,11 @@ -- Copyright (c) 2015-2017 Rudy Matela. -- Distributed under the 3-Clause BSD licence (see the file LICENSE).+import Test+ import System.Exit (exitFailure) import Data.List (elemIndices)  import Test.LeanCheck-import Test.LeanCheck.Invariants import Test.LeanCheck.Utils  import Data.Ratio@@ -17,6 +18,7 @@     is -> do putStrLn ("Failed tests:" ++ show is)              exitFailure +tests :: [Bool] tests =   [ True