leancheck 0.7.5 → 0.7.6
raw patch · 10 files changed
+219/−9 lines, 10 filesdep +ghc-primPVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-prim
API changes (from Hackage documentation)
+ Test.LeanCheck.Generic: genericList :: (Generic a, Listable' (Rep a)) => [a]
+ Test.LeanCheck.Generic: genericTiers :: (Generic a, Listable' (Rep a)) => [[a]]
+ Test.LeanCheck.Generic: instance (Test.LeanCheck.Generic.Listable' a, Test.LeanCheck.Generic.Listable' b) => Test.LeanCheck.Generic.Listable' (a GHC.Generics.:*: b)
+ Test.LeanCheck.Generic: instance (Test.LeanCheck.Generic.Listable' a, Test.LeanCheck.Generic.Listable' b) => Test.LeanCheck.Generic.Listable' (a GHC.Generics.:+: b)
+ Test.LeanCheck.Generic: instance Test.LeanCheck.Core.Listable c => Test.LeanCheck.Generic.Listable' (GHC.Generics.K1 i c)
+ Test.LeanCheck.Generic: instance Test.LeanCheck.Generic.Listable' GHC.Generics.U1
+ Test.LeanCheck.Generic: instance Test.LeanCheck.Generic.Listable' GHC.Generics.V1
+ Test.LeanCheck.Generic: instance Test.LeanCheck.Generic.Listable' f => Test.LeanCheck.Generic.Listable' (GHC.Generics.M1 i c f)
Files
- .gitignore +1/−0
- .travis.yml +2/−2
- Makefile +1/−0
- leancheck.cabal +16/−3
- mk/All.hs +2/−0
- mk/Toplibs.hs +1/−0
- mk/depend.mk +21/−0
- src/Test/LeanCheck/Derive.hs +45/−4
- src/Test/LeanCheck/Generic.hs +65/−0
- tests/test-generic.hs +65/−0
.gitignore view
@@ -17,6 +17,7 @@ tests/test-error tests/test-fun tests/test-funshow+tests/test-generic tests/test-io tests/test-most tests/test-operators
.travis.yml view
@@ -49,8 +49,8 @@ env: GHCVER=8.6.1 CABALVER=2.4 addons: {apt: {packages: [ghc-8.6.1, cabal-install-2.4], sources: hvr-ghc}} - ghc: '8.4'- env: GHCVER=8.4.2 CABALVER=2.2- addons: {apt: {packages: [ghc-8.4.2, cabal-install-2.2], sources: hvr-ghc}}+ env: GHCVER=8.4.4 CABALVER=2.2+ addons: {apt: {packages: [ghc-8.4.4, cabal-install-2.2], sources: hvr-ghc}} - ghc: '8.2' env: GHCVER=8.2.2 CABALVER=2.0 addons: {apt: {packages: [ghc-8.2.2, cabal-install-2.0], sources: hvr-ghc}}
Makefile view
@@ -8,6 +8,7 @@ tests/test-error \ tests/test-fun \ tests/test-funshow \+ tests/test-generic \ tests/test-io \ tests/test-operators \ tests/test-tiers \
leancheck.cabal view
@@ -11,7 +11,7 @@ -- this cabal file too complicated. -- Rudy name: leancheck-version: 0.7.5+version: 0.7.6 synopsis: Enumerative property-based testing description: LeanCheck is a simple enumerative property-based testing library.@@ -70,7 +70,7 @@ source-repository this type: git location: https://github.com/rudymatela/leancheck- tag: v0.7.5+ tag: v0.7.6 library exposed-modules: Test.LeanCheck@@ -78,6 +78,7 @@ , Test.LeanCheck.Core , Test.LeanCheck.Derive , Test.LeanCheck.Error+ , Test.LeanCheck.Generic , Test.LeanCheck.IO , Test.LeanCheck.Tiers , Test.LeanCheck.Utils@@ -98,7 +99,9 @@ , Test.LeanCheck.Function.CoListable , Test.LeanCheck.Function.ShowFunction hs-source-dirs: src- build-depends: base >= 4 && < 5, template-haskell+ build-depends: base >= 4 && < 5, template-haskell+ if impl(ghc < 7.6)+ build-depends: ghc-prim default-language: Haskell2010 test-suite main@@ -147,6 +150,16 @@ other-modules: Test hs-source-dirs: tests build-depends: base >= 4 && < 5, leancheck+ default-language: Haskell2010++test-suite generic+ type: exitcode-stdio-1.0+ main-is: test-generic.hs+ other-modules: Test+ hs-source-dirs: tests+ build-depends: base >= 4 && < 5, leancheck+ if impl(ghc < 7.6)+ build-depends: ghc-prim default-language: Haskell2010 test-suite io
mk/All.hs view
@@ -4,6 +4,7 @@ , module Test.LeanCheck.Basic , module Test.LeanCheck.Utils , module Test.LeanCheck.Tiers+ , module Test.LeanCheck.Generic ) where @@ -12,3 +13,4 @@ import Test.LeanCheck.Basic import Test.LeanCheck.Utils import Test.LeanCheck.Tiers+import Test.LeanCheck.Generic
mk/Toplibs.hs view
@@ -5,3 +5,4 @@ import Test.LeanCheck.Utils () import Test.LeanCheck.Error () import Test.LeanCheck.Function ()+import Test.LeanCheck.Generic ()
mk/depend.mk view
@@ -193,6 +193,7 @@ src/Test/LeanCheck/Stats.hs \ src/Test/LeanCheck.hs \ src/Test/LeanCheck/IO.hs \+ src/Test/LeanCheck/Generic.hs \ src/Test/LeanCheck/Derive.hs \ src/Test/LeanCheck/Core.hs \ src/Test/LeanCheck/Basic.hs \@@ -206,6 +207,7 @@ src/Test/LeanCheck/Stats.hs \ src/Test/LeanCheck.hs \ src/Test/LeanCheck/IO.hs \+ src/Test/LeanCheck/Generic.hs \ src/Test/LeanCheck/Function/Show.hs \ src/Test/LeanCheck/Function/ShowFunction.hs \ src/Test/LeanCheck/Function.hs \@@ -368,6 +370,9 @@ src/Test/LeanCheck/Derive.hs \ src/Test/LeanCheck/Core.hs \ src/Test/LeanCheck/Basic.hs+src/Test/LeanCheck/Generic.o: \+ src/Test/LeanCheck/Generic.hs \+ src/Test/LeanCheck/Core.hs src/Test/LeanCheck/IO.o: \ src/Test/LeanCheck/IO.hs \ src/Test/LeanCheck/Core.hs@@ -488,6 +493,22 @@ tests/test-fun: \ tests/Test.hs \ tests/test-fun.hs \+ mk/toplibs+tests/test-generic.o: \+ tests/Test.hs \+ tests/test-generic.hs \+ src/Test/LeanCheck/Utils/Types.hs \+ src/Test/LeanCheck/Utils/Operators.hs \+ src/Test/LeanCheck/Tiers.hs \+ src/Test/LeanCheck.hs \+ src/Test/LeanCheck/IO.hs \+ src/Test/LeanCheck/Generic.hs \+ src/Test/LeanCheck/Derive.hs \+ src/Test/LeanCheck/Core.hs \+ src/Test/LeanCheck/Basic.hs+tests/test-generic: \+ tests/Test.hs \+ tests/test-generic.hs \ mk/toplibs tests/test-io.o: \ tests/Test.hs \
src/Test/LeanCheck/Derive.hs view
@@ -8,13 +8,14 @@ -- This module is part of LeanCheck, -- a simple enumerative property-based testing library. ----- This is an experimental module for deriving 'Listable' instances.--- -- Needs GHC and Template Haskell -- (tested on GHC 7.4, 7.6, 7.8, 7.10, 8.0, 8.2 and 8.4). -- -- If LeanCheck does not compile under later GHCs, this module is probably the -- culprit.+--+-- If you rather do this through GHC Generics, please see:+-- "Test.LeanCheck.Generic" (experimental). module Test.LeanCheck.Derive ( deriveListable , deriveListableIfNeeded@@ -52,17 +53,52 @@ -- > instance Listable a => Listable (Stack a) where -- > tiers = cons2 Stack \/ cons0 Empty --+-- __Warning:__ if the values in your type need to follow a data invariant, the+-- derived instance won't respect it. Use this only on "free"+-- datatypes.+-- -- Needs the @TemplateHaskell@ extension. deriveListable :: Name -> DecsQ deriveListable = deriveListableX True False --- | Same as 'deriveListable' but does not warn when instance already exists--- ('deriveListable' is preferable).+-- | Same as 'deriveListable' but does not warn when the requested instance+-- already exists. The function 'deriveListable' is preferable in most+-- situations. deriveListableIfNeeded :: Name -> DecsQ deriveListableIfNeeded = deriveListableX False False -- | Derives a 'Listable' instance for a given type 'Name' -- cascading derivation of type arguments as well.+--+-- Consider the following series of datatypes:+--+-- > data Position = CEO | Manager | Programmer+-- >+-- > data Person = Person+-- > { name :: String+-- > , age :: Int+-- > , position :: Position+-- > }+-- >+-- > data Company = Company+-- > { name :: String+-- > , employees :: [Person]+-- > }+--+-- Writing+--+-- > deriveListableCascading ''Company+--+-- will automatically derive the following three 'Listable' instances:+--+-- > instance Listable Position where+-- > tiers = cons0 CEO \/ cons0 Manager \/ cons0 Programmer+-- >+-- > instance Listable Person where+-- > tiers = cons3 Person+-- >+-- > instance Listable Company where+-- > tiers = cons2 Company deriveListableCascading :: Name -> DecsQ deriveListableCascading = deriveListableX True True @@ -104,6 +140,11 @@ -- 'tiers': -- -- > consN C1 \/ consN C2 \/ ... \/ consN CN+--+-- This function can be used in the definition of 'Listable' instances:+--+-- > instance Listable MyType where+-- > tiers = $(deriveTiers) deriveTiers :: Name -> ExpQ deriveTiers t = conse =<< typeConstructors t where
+ src/Test/LeanCheck/Generic.hs view
@@ -0,0 +1,65 @@+{-# LANGUAGE FlexibleContexts, TypeOperators #-}+-- |+-- Module : Test.LeanCheck.Generic+-- Copyright : (c) 2018 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.+--+-- This is an experimental module for deriving 'Listable' instances through+-- GHC's generic.+--+-- If you rather do this through Template Haskell please see:+-- "Test.LeanCheck.Derive".+module Test.LeanCheck.Generic+ ( genericList+ , genericTiers+ )+where++import GHC.Generics+import Test.LeanCheck.Core++-- | A generic implementation of 'list' for instances of 'Generic'.+--+-- Use it to define your 'Listable' instances like so:+--+-- > instance Listable MyType where+-- > list = genericList+--+-- Consider using 'genericTiers' instead of this+-- (unless you know what you're doing).+genericList :: (Generic a, Listable' (Rep a)) => [a]+genericList = concat genericTiers++-- | A generic implementation of 'tiers' for instances of 'Generic'.+--+-- Use it to define your 'Listable' instances like so:+--+-- > instance Listable MyType where+-- > tiers = genericTiers+genericTiers :: (Generic a, Listable' (Rep a)) => [[a]]+genericTiers = mapT to tiers'++class Listable' f where+ tiers' :: [[f p]]++instance Listable' V1 where+ tiers' = undefined++instance Listable' U1 where+ tiers' = [[U1]]++instance Listable c => Listable' (K1 i c) where+ tiers' = mapT K1 tiers++instance (Listable' a, Listable' b) => Listable' (a :+: b) where+ tiers' = mapT L1 tiers' \/ mapT R1 tiers'++instance (Listable' a, Listable' b) => Listable' (a :*: b) where+ tiers' = productWith (:*:) tiers' tiers'++instance Listable' f => Listable' (M1 i c f) where+ tiers' = mapT M1 tiers'
+ tests/test-generic.hs view
@@ -0,0 +1,65 @@+-- Copyright (c) 2015-2018 Rudy Matela.+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).+{-# LANGUAGE DeriveGeneric, StandaloneDeriving #-}+import Test+import Test.LeanCheck+import Test.LeanCheck.Generic+import System.Exit (exitFailure)+import Data.List (elemIndices,sort)+import Test.LeanCheck.Utils.Operators+import GHC.Generics (Generic)++data D0 = D0 deriving (Eq, Show, Generic)+data D1 a = D1 a deriving (Eq, Show, Generic)+data D2 a b = D2 a b deriving (Eq, Show, Generic)+data D3 a b c = D3 a b c deriving (Eq, Show, Generic)+data C1 a = C11 a | C10 deriving (Eq, Show, Generic)+data C2 a b = C22 a b | C21 a | C20 deriving (Eq, Show, Generic)+data I a b = a :+ b deriving (Eq, Show, Generic)++instance Listable D0 where tiers = genericTiers++instance Listable a => Listable (D1 a) where tiers = genericTiers++instance (Listable a, Listable b)+ => Listable (D2 a b) where tiers = genericTiers++instance (Listable a, Listable b, Listable c)+ => Listable (D3 a b c) where tiers = genericTiers++instance Listable a => Listable (C1 a) where tiers = genericTiers++instance (Listable a, Listable b)+ => Listable (C2 a b) where tiers = genericTiers++instance (Listable a, Listable b)+ => Listable (I a b) where tiers = genericTiers++main :: IO ()+main =+ case elemIndices False (tests 100) of+ [] -> putStrLn "Tests passed!"+ is -> do putStrLn ("Failed tests:" ++ show is)+ exitFailure++tests n =+ [ True++ , map unD0 list =| n |= list+ , map unD1 list =| n |= (list :: [Int])+ , map unD2 list =| n |= (list :: [(Int,Int)])+ , map unD3 list =| n |= (list :: [(Int,Int,Int)])++ , map unD1 list == (list :: [()])+ , map unD2 list == (list :: [((),())])+ , map unD3 list == (list :: [((),(),())])++ , map unD1 list == (list :: [Bool])+ , map unD2 list == (list :: [(Bool,Bool)])+ , map unD3 list == (list :: [(Bool,Bool,Bool)])+ ]+ where+ unD0 (D0) = ()+ unD1 (D1 x) = (x)+ unD2 (D2 x y) = (x,y)+ unD3 (D3 x y z) = (x,y,z)