leancheck 0.6.5 → 0.6.6
raw patch · 7 files changed
+111/−31 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Test.LeanCheck.Tiers: discardLaterT :: (a -> a -> Bool) -> [[a]] -> [[a]]
+ Test.LeanCheck.Tiers: discardT :: (a -> Bool) -> [[a]] -> [[a]]
+ Test.LeanCheck.Tiers: nubT :: Ord a => [[a]] -> [[a]]
Files
- README.md +36/−22
- TODO.md +22/−2
- leancheck.cabal +2/−2
- src/Test/LeanCheck/Function/Show.hs +1/−3
- src/Test/LeanCheck/IO.hs +13/−2
- src/Test/LeanCheck/Tiers.hs +32/−0
- tests/test-tiers.hs +5/−0
README.md view
@@ -17,7 +17,9 @@ similar to [Feat]'s. However, the ranking and ordering of values are defined differently. The interface is also different. -In this README, lines ending with `-- >` indicate expected return values.+Throughout this README lines that begin with the [symbol `>`] indicate a line+entered into an interactive interpreter (`ghci`). The result of evaluating the+expression is then printed on the following line. Installing@@ -40,10 +42,12 @@ then, it returns a boolean indicating whether the property holds. See (ghci): - import Test.LeanCheck- import Data.List- holds 100 $ \xs -> sort (sort xs) == sort (xs::[Int]) -- > True- holds 100 $ \xs -> [] `union` xs == (xs::[Int]) -- > False+ > import Test.LeanCheck+ > import Data.List+ > holds 100 $ \xs -> sort (sort xs) == sort (xs::[Int])+ True+ > holds 100 $ \xs -> [] `union` xs == (xs::[Int])+ False Finding counter examples@@ -58,17 +62,17 @@ representing the offending arguments to the property. See (ghci): - import Test.LeanCheck- import Data.List+ > import Test.LeanCheck+ > import Data.List - counterExample 100 $ \xs -> sort (sort xs) == sort (xs::[Int])- -- > Nothing+ > counterExample 100 $ \xs -> sort (sort xs) == sort (xs::[Int])+ Nothing - counterExample 100 $ \xs -> [] `union` xs == (xs::[Int])- -- > Just ["[0,0]"]+ > counterExample 100 $ \xs -> [] `union` xs == (xs::[Int])+ Just ["[0,0]"] - counterExample 100 $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])- -- > Just ["[]","[0,0]"]+ > counterExample 100 $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])+ Just ["[]","[0,0]"] Checking properties like in SmallCheck/QuickCheck@@ -78,15 +82,15 @@ automatically printing results on standard output, you can use the function [`check`] `:: Testable a => a -> IO ()`. - import Test.LeanCheck- import Data.List+ > import Test.LeanCheck+ > import Data.List - check $ \xs -> sort (sort xs) == sort (xs::[Int])- -- > +++ OK, passed 200 tests.+ > check $ \xs -> sort (sort xs) == sort (xs::[Int])+ +++ OK, passed 200 tests. - check $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])- -- > *** Failed! Falsifiable (after 4 tests):- -- > [] [0,0]+ > check $ \xs ys -> xs `union` ys == ys `union` (xs::[Int])+ *** Failed! Falsifiable (after 4 tests):+ [] [0,0] The function [`check`] tests for a maximum of 200 tests. To check for a maximum of `n` tests, use [`checkFor`] `n`.@@ -98,7 +102,7 @@ -------------------------- LeanCheck works on properties with [`Listable`] argument types.-`Listable` instances are declared similarly to SmallCheck:+[`Listable`] instances are declared similarly to SmallCheck: data MyType = MyConsA | MyConsB Int@@ -111,6 +115,12 @@ \/ cons2 MyConsC \/ cons1 MyConsD +For types that do not have a constraning data invariant, instances can be+automatically derived with [Template Haskell] by using [`deriveListable`] like+so:++ deriveListable ''MyType+ The [`tiers`] function return a potentially infinite list of finite sub-lists (tiers). Each successive tier has values of increasing size. @@ -123,7 +133,8 @@ So, for example: - take 5 (list :: [(Int,Int)]) -- > [(0,0),(0,1),(1,0),(0,-1),(1,1)]+ > take 5 (list :: [(Int,Int)])+ [(0,0),(0,1),(1,0),(0,-1),(1,1)] The `list` function can be used to debug your custom instances. @@ -154,11 +165,14 @@ [`checkResultFor`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:checkResultFor [`tiers`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:tiers [`list`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:list+[`deriveListable`]: https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html#v:deriveListable [property-based testing]: https://github.com/rudymatela/leancheck/blob/master/doc/tutorial.md [Feat]: https://hackage.haskell.org/package/testing-feat [SmallCheck]: https://hackage.haskell.org/package/smallcheck [QuickCheck]: https://hackage.haskell.org/package/QuickCheck++[symbol `>`]: https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810780208 [build-status]: https://travis-ci.org/rudymatela/leancheck.svg?branch=master [build-log]: https://travis-ci.org/rudymatela/leancheck
TODO.md view
@@ -25,12 +25,18 @@ * on data-invariant.md, write missing section; -v0.6.6+v0.6.7 ------ * On `bench/tiers`, print if the enumeration has repetitions (import `Function.Eq` for that) +* Modularize the `Derive` module by implementing+ `deriveTiers` and `deriveList`.++* Port `discardLaterT`, `discardT` and `nubT` from Speculate here.+ See `fitspec/eg/alga` for details.+ * add `classify` function to measure distribution of data: something like: @@ -60,7 +66,21 @@ so that the user gets an enumeration of functions with repetitions, but using a mixed strategy for generation of values. -v0.6.7++v0.6.8 ------ * implement stub `Test.LeanCheck.Function.*` modules;+++v0.6.9+------++* somehow, improve the improve the enumeration of `Char`s:++ list = [ ['a'], ['b','c'], ['d','e','f'], ... ]+ ||| [ [' '], ['\n'] ]+ ||| [ ['0'], ['1'], ['2'], ...]+ ||| ...+ where+ ||| is something that interleaves tiers of different lists...
leancheck.cabal view
@@ -11,7 +11,7 @@ -- this cabal file too complicated. -- Rudy name: leancheck-version: 0.6.5+version: 0.6.6 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.5+ tag: v0.6.6 library exposed-modules: Test.LeanCheck
src/Test/LeanCheck/Function/Show.hs view
@@ -16,7 +16,5 @@ import Test.LeanCheck.Function.ShowFunction instance (Show a, Listable a, ShowFunction b) => Show (a->b) where- showsPrec 0 = (++) . showFunction 8- showsPrec _ = (++) . paren . showFunctionLine 4- where paren s = "(" ++ s ++ ")"+ showsPrec _ = (++) . showFunction 8
src/Test/LeanCheck/IO.hs view
@@ -90,6 +90,17 @@ showResult m (OK n) = "+++ OK, passed " ++ show n ++ " tests" ++ takeWhile (\_ -> n < m) " (exhausted)" ++ "." showResult m (Falsified i ce) = "*** Failed! Falsifiable (after "- ++ show i ++ " tests):\n" ++ unwords ce+ ++ show i ++ " tests):\n" ++ join ce showResult m (Exception i ce e) = "*** Failed! Exception '" ++ e ++ "' (after "- ++ show i ++ " tests):\n" ++ unwords ce+ ++ show i ++ " tests):\n" ++ join ce++-- join the counter-example arguments+join :: [String] -> String+join ce | any ('\n' `elem`) ce = unlines $ map chopBreak ce+ | otherwise = unwords ce++-- chops a line break at the end if there is any+chopBreak :: String -> String+chopBreak [] = []+chopBreak ['\n'] = []+chopBreak (x:xs) = x:chopBreak xs
src/Test/LeanCheck/Tiers.hs view
@@ -49,6 +49,9 @@ , normalizeT , catMaybesT , mapMaybeT+ , discardT+ , discardLaterT+ , nubT -- * Tiers of choices , choices@@ -270,6 +273,35 @@ mapMaybeT :: (a -> Maybe b) -> [[a]] -> [[b]] mapMaybeT f = catMaybesT . mapT f++-- | Discard elements _not_ matching a predicate.+--+-- > discardT odd [[1],[2,3],[4]] = [[],[2],[4]]+discardT :: (a -> Bool) -> [[a]] -> [[a]]+discardT p = filterT (not . p)++-- | Discard later elements maching a binary predicate+-- (in relation to an earlier element).+--+-- > discardLaterT (>) [[0],[1],[-1],[2],[-2],...] = [[0],[],[-1],[],[-2],...]+-- > discardLaterT (==) [[0],[0,1],[0,1,2],[0,1,2,3],...] = [[0],[1],[2],[3]]+--+-- This function is quite innefficient, use with care.+-- Consuming the n-th element takes @O(n^2)@ operations.+discardLaterT :: (a -> a -> Bool) -> [[a]] -> [[a]]+discardLaterT d [] = []+discardLaterT d ([]:xss) = [] : discardLaterT d xss+discardLaterT d ((x:xs):xss) = [[x]]+ \/ discardLaterT d (discardT (`d` x) (xs:xss))++-- | Removes repetitions from tiers.+--+-- > nubT [[0],[0,1],[0,1,2],[0,1,2,3],...] = [[0],[1],[2],[3],...]+-- > nubT [[0],[-1,0,1],[-2,-1,0,1,2],...] = [[0],[-1,1],[-2,2],...]+--+-- Consuming the n-th element takes @O(n^2)@ operations.+nubT :: Ord a => [[a]] -> [[a]]+nubT = discardLaterT (==) -- | Takes as argument tiers of element values; -- returns tiers of lists with no repeated elements.
tests/test-tiers.hs view
@@ -63,6 +63,11 @@ , finite (tiers :: [[ Word4 ]]) == False , finite (tiers :: [[ (Bool,Bool,Bool,Bool,Bool) ]]) == False , finite (tiers :: [[ (Bool,Bool,Bool,Bool,Bool,Bool) ]]) == False++ , holds 100 $ \xss -> ordered . concat $ discardLaterT (<) (xss::[[Int]])+ , holds 100 $ \xss -> ordered . concat $ discardLaterT (<=) (xss::[[Int]])+ , (length . concat $ discardLaterT (<=) [[00..99],[100..199::Int]]) == 200+ , holds 100 $ \xss -> nub (concat xss) == concat (nubT xss :: [[Int]]) ] deleteT_is_map_delete :: (Eq a, Listable a) => Int -> a -> Bool