packages feed

QuickCheck 2.7.3 → 2.7.4

raw patch · 7 files changed

+151/−23 lines, 7 filesdep +transformersdep ~QuickCheck

Dependencies added: transformers

Dependency ranges changed: QuickCheck

Files

QuickCheck.cabal view
@@ -1,5 +1,5 @@ Name: QuickCheck-Version: 2.7.3+Version: 2.7.4 Cabal-Version: >= 1.8 Build-type: Simple License: BSD3@@ -10,7 +10,7 @@ Maintainer: QuickCheck developers <quickcheck@projects.haskell.org> Bug-reports: mailto:quickcheck@projects.haskell.org Tested-with: GHC >=6.8, Hugs, UHC-Homepage: http://code.haskell.org/QuickCheck+Homepage: https://github.com/nick8325/quickcheck Category:       Testing Synopsis:       Automatic testing of Haskell programs Description:@@ -34,7 +34,7 @@ source-repository this   type:     git   location: https://github.com/nick8325/quickcheck-  tag:      2.7.3+  tag:      2.7.4  flag base3   Description: Choose the new smaller, split-up base package.@@ -74,6 +74,10 @@   -- GHC-specific modules.   if impl(ghc)     Exposed-Modules: Test.QuickCheck.Function+  if impl(ghc >= 7)+    Build-depends: transformers >= 0.2+  else+    cpp-options: -DNO_TRANSFORMERS   if impl(ghc >= 6.12) && flag(templateHaskell)     Build-depends: template-haskell >= 2.4     Exposed-Modules: Test.QuickCheck.All@@ -137,6 +141,6 @@     main-is: Heap.hs     build-depends:       base,-      QuickCheck == 2.7.3,+      QuickCheck == 2.7.4,       template-haskell >= 2.4,       test-framework >= 0.4 && < 0.9
Test/QuickCheck/All.hs view
@@ -22,6 +22,8 @@ import Data.List import Control.Monad +import qualified System.IO as S+ -- | Test a polymorphic property, defaulting all type variables to 'Integer'. -- -- Invoke as @$('polyQuickCheck' 'prop)@, where @prop@ is a property.@@ -32,11 +34,19 @@ -- @'quickCheck' $('monomorphic' \'prop)@. -- If you want to supply custom arguments to 'polyQuickCheck', -- you will have to combine 'quickCheckWith' and 'monomorphic' yourself.+--+-- If you want to use 'polyQuickCheck' in the same file where you defined the+-- property, the same scoping problems pop up as in 'quickCheckAll':+-- see the note there about @return []@. polyQuickCheck :: Name -> ExpQ polyQuickCheck x = [| quickCheck $(monomorphic x) |]  -- | Test a polymorphic property, defaulting all type variables to 'Integer'. -- This is just a convenience function that combines 'verboseCheck' and 'monomorphic'.+--+-- If you want to use 'polyVerboseCheck' in the same file where you defined the+-- property, the same scoping problems pop up as in 'quickCheckAll':+-- see the note there about @return []@. polyVerboseCheck :: Name -> ExpQ polyVerboseCheck x = [| verboseCheck $(monomorphic x) |] @@ -46,6 +56,10 @@ -- -- For example, if @f@ has type @'Ord' a => [a] -> [a]@ -- then @$('monomorphic' 'f)@ has type @['Integer'] -> ['Integer']@.+--+-- If you want to use 'monomorphic' in the same file where you defined the+-- property, the same scoping problems pop up as in 'quickCheckAll':+-- see the note there about @return []@. monomorphic :: Name -> ExpQ monomorphic t = do   ty0 <- fmap infoType (reify t)@@ -84,37 +98,71 @@ -- @$'forAllProperties'@ has type @('Property' -> 'IO' 'Result') -> 'IO' 'Bool'@. -- An example invocation is @$'forAllProperties' 'quickCheckResult'@, -- which does the same thing as @$'quickCheckAll'@.+--+-- 'forAllProperties' has the same issue with scoping as 'quickCheckAll':+-- see the note there about @return []@. forAllProperties :: Q Exp -- :: (Property -> IO Result) -> IO Bool forAllProperties = do   Loc { loc_filename = filename } <- location   when (filename == "<interactive>") $ error "don't run this interactively"-  ls <- runIO (fmap lines (readFile filename))+  ls <- runIO (fmap lines (readUTF8File filename))   let prefixes = map (takeWhile (\c -> isAlphaNum c || c == '_') . dropWhile (\c -> isSpace c || c == '>')) ls       idents = nubBy (\x y -> snd x == snd y) (filter (("prop_" `isPrefixOf`) . snd) (zip [1..] prefixes))+#if __GLASGOW_HASKELL__ > 705+      warning x = reportWarning ("Name " ++ x ++ " found in source file but was not in scope")+#else+      warning x = report False ("Name " ++ x ++ " found in source file but was not in scope")+#endif       quickCheckOne :: (Int, String) -> Q [Exp]       quickCheckOne (l, x) = do-        exists <- return False `recover` (reify (mkName x) >> return True)+        exists <- (warning x >> return False) `recover` (reify (mkName x) >> return True)         if exists then sequence [ [| ($(stringE $ x ++ " from " ++ filename ++ ":" ++ show l),                                      property $(monomorphic (mkName x))) |] ]          else return []   [| runQuickCheckAll $(fmap (ListE . concat) (mapM quickCheckOne idents)) |] +readUTF8File name = S.openFile name S.ReadMode >>=+                    set_utf8_io_enc >>=+                    S.hGetContents++-- Deal with UTF-8 input and output.+set_utf8_io_enc :: S.Handle -> IO S.Handle+#if __GLASGOW_HASKELL__ > 611+-- possibly if MIN_VERSION_base(4,2,0)+set_utf8_io_enc h = do S.hSetEncoding h S.utf8; return h+#else+set_utf8_io_enc h = return h+#endif+ -- | Test all properties in the current module. -- The name of the property must begin with @prop_@. -- Polymorphic properties will be defaulted to 'Integer'. -- Returns 'True' if all tests succeeded, 'False' otherwise. ----- Using 'quickCheckAll' interactively doesn't work.--- Instead, add a definition to your module along the lines of+-- To use 'quickCheckAll', add a definition to your module along+-- the lines of --+-- > return [] -- > runTests = $quickCheckAll -- -- and then execute @runTests@.+--+-- Note: the bizarre @return []@ in the example above is needed on+-- GHC 7.8; without it, 'quickCheckAll' will not be able to find+-- any of the properties. For the curious, the @return []@ is a+-- Template Haskell splice that makes GHC insert the empty list+-- of declarations at that point in the program; GHC typechecks+-- everything before the @return []@ before it starts on the rest+-- of the module, which means that the later call to 'quickCheckAll'+-- can see everything that was defined before the @return []@. Yikes! quickCheckAll :: Q Exp quickCheckAll = [| $(forAllProperties) quickCheckResult |]  -- | Test all properties in the current module. -- This is just a convenience function that combines 'quickCheckAll' and 'verbose'.+--+-- 'verboseCheckAll' has the same issue with scoping as 'quickCheckAll':+-- see the note there about @return []@. verboseCheckAll :: Q Exp verboseCheckAll = [| $(forAllProperties) verboseCheckResult |] 
Test/QuickCheck/Arbitrary.hs view
@@ -10,7 +10,7 @@   , CoArbitrary(..)    -- ** Helper functions for implementing arbitrary-  , arbitrarySizedIntegral        -- :: Num a => Gen a+  , arbitrarySizedIntegral        -- :: Integral a => Gen a   , arbitraryBoundedIntegral      -- :: (Bounded a, Integral a) => Gen a   , arbitrarySizedBoundedIntegral -- :: (Bounded a, Integral a) => Gen a   , arbitrarySizedFractional      -- :: Fractional a => Gen a@@ -436,16 +436,10 @@ arbitrarySizedIntegral :: Integral a => Gen a arbitrarySizedIntegral =   sized $ \n ->-  withoutOverflow (toInteger n) $ \n' _ ->-  withoutOverflow (negate (toInteger n)) $ \m' _ ->-    fmap fromInteger (choose (m', n'))+  inBounds fromInteger (choose (-toInteger n, toInteger n)) -withoutOverflow :: Integral a => Integer -> (Integer -> a -> Gen a) -> Gen a-withoutOverflow n k-  | toInteger n' == n = k n n'-  | otherwise = k 0 0-  where-    n' = fromInteger n+inBounds :: Integral a => (Integer -> a) -> Gen Integer -> Gen a+inBounds fi g = fmap fi (g `suchThat` (\x -> toInteger (fi x) == x))  -- | Generates a fractional number. The number can be positive or negative -- and its maximum absolute value depends on the size parameter.
Test/QuickCheck/Modifiers.hs view
@@ -145,10 +145,33 @@ newtype Positive a = Positive {getPositive :: a}  deriving ( Eq, Ord, Show, Read #ifndef NO_NEWTYPE_DERIVING-          , Num, Integral, Real, Enum+          , Integral, Real #endif           ) +instance (Ord a, Num a) => Num (Positive a) where+  Positive x + Positive y = positive (x+y)+  Positive x - Positive y = positive (x-y)+  Positive x * Positive y = positive (x*y)+  negate (Positive x) = positive (negate x)+  abs (Positive x) = positive (abs x)+  signum (Positive x) = positive (signum x)+  fromInteger n = positive (clamp (> 0) 1 (fromInteger n))++clamp :: (a -> Bool) -> a -> a -> a+clamp p d x+  | p x = x+  | otherwise = d++positive :: (Ord a, Num a) => a -> Positive a+positive x+  | x <= 0 = error "Positive: negative number"+  | otherwise = Positive x++instance Enum a => Enum (Positive a) where+  toEnum n = fmap toEnum (positive n)+  fromEnum (Positive x) = fromEnum x+ instance Functor Positive where   fmap f (Positive x) = Positive (f x) @@ -168,10 +191,27 @@ newtype NonZero a = NonZero {getNonZero :: a}  deriving ( Eq, Ord, Show, Read #ifndef NO_NEWTYPE_DERIVING-          , Num, Integral, Real, Enum+          , Integral, Real #endif           ) +instance (Eq a, Num a) => Num (NonZero a) where+  NonZero x + NonZero y = nonZero (x+y)+  NonZero x - NonZero y = nonZero (x-y)+  NonZero x * NonZero y = nonZero (x*y)+  negate (NonZero x) = nonZero (negate x)+  abs (NonZero x) = nonZero (abs x)+  signum (NonZero x) = nonZero (signum x)+  fromInteger n = nonZero (clamp (/= 0) 0 (fromInteger n))++nonZero :: (Eq a, Num a) => a -> NonZero a+nonZero 0 = error "NonZero: passed in zero"+nonZero x = NonZero x++instance Enum a => Enum (NonZero a) where+  toEnum n = fmap toEnum (nonZero n)+  fromEnum (NonZero x) = fromEnum x+ instance Functor NonZero where   fmap f (NonZero x) = NonZero (f x) @@ -185,9 +225,27 @@ newtype NonNegative a = NonNegative {getNonNegative :: a}  deriving ( Eq, Ord, Show, Read #ifndef NO_NEWTYPE_DERIVING-          , Num, Integral, Real, Enum+          , Integral, Real #endif           )++instance (Ord a, Num a) => Num (NonNegative a) where+  NonNegative x + NonNegative y = nonNegative (x+y)+  NonNegative x - NonNegative y = nonNegative (x-y)+  NonNegative x * NonNegative y = nonNegative (x*y)+  negate (NonNegative x) = nonNegative (negate x)+  abs (NonNegative x) = nonNegative (abs x)+  signum (NonNegative x) = nonNegative (signum x)+  fromInteger n = nonNegative (clamp (>= 0) 0 (fromInteger n))++nonNegative :: (Ord a, Num a) => a -> NonNegative a+nonNegative x+  | x < 0 = error "NonNegative: negative number"+  | otherwise = NonNegative x++instance Enum a => Enum (NonNegative a) where+  toEnum n = fmap toEnum (nonNegative n)+  fromEnum (NonNegative x) = fromEnum x  instance Functor NonNegative where   fmap f (NonNegative x) = NonNegative (f x)
Test/QuickCheck/Monadic.hs view
@@ -19,7 +19,10 @@ import Control.Monad.ST import Control.Applicative --- instance of monad transformer?+#ifndef NO_TRANSFORMERS+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+#endif  -------------------------------------------------------------------------- -- type PropertyM@@ -38,6 +41,14 @@   return x            = MkPropertyM (\k -> k x)   MkPropertyM m >>= f = MkPropertyM (\k -> m (\a -> unPropertyM (f a) k))   fail s              = stop (failed { reason = s })++#ifndef NO_TRANSFORMERS+instance MonadTrans PropertyM where+  lift = run++instance MonadIO m => MonadIO (PropertyM m) where+  liftIO = run . liftIO+#endif  stop :: (Testable prop, Monad m) => prop -> PropertyM m a stop p = MkPropertyM (\_k -> return (return (property p)))
Test/QuickCheck/Property.hs view
@@ -63,6 +63,16 @@ -- * Property and Testable types  -- | The type of properties.+--+-- Backwards combatibility note: in older versions of QuickCheck+-- 'Property' was a type synonym for @'Gen' 'Prop'@, so you could mix+-- and match property combinators and 'Gen' monad operations. Code+-- that does this will no longer typecheck.+-- However, it is easy to fix: because of the 'Testable' typeclass, any+-- combinator that expects a 'Property' will also accept a @'Gen' 'Property'@.+-- If you have a 'Property' where you need a @'Gen' 'a'@, simply wrap+-- the property combinator inside a 'return' to get a @'Gen' 'Property'@, and+-- all should be well. newtype Property = MkProperty { unProperty :: Gen Prop }  -- | The class of things which can be tested, i.e. turned into a property.@@ -98,7 +108,7 @@   property mp = MkProperty $ do p <- mp; unProperty (property p)  instance Testable Property where-  property = id+  property = property . unProperty  -- | Do I/O inside a property. This can obviously lead to unrepeatable -- testcases, so use with care.
examples/Heap.hs view
@@ -145,6 +145,9 @@ -------------------------------------------------------------------------- -- main +return []+-- quickCheckAll reads this file and treats it as UTF-8+-- Here is a bait to test: Привет! main = $(quickCheckAll)  --------------------------------------------------------------------------