Mailinglist Archive: opensuse-commit (1903 mails)

< Previous Next >
commit ghc-QuickCheck for openSUSE:Factory
Hello community,

here is the log from the commit of package ghc-QuickCheck for openSUSE:Factory
checked in at 2019-04-03 09:27:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-QuickCheck (Old)
and /work/SRC/openSUSE:Factory/.ghc-QuickCheck.new.25356 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-QuickCheck"

Wed Apr 3 09:27:00 2019 rev:16 rq:690177 version:2.13.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-QuickCheck/ghc-QuickCheck.changes
2018-10-25 08:18:33.896012332 +0200
+++ /work/SRC/openSUSE:Factory/.ghc-QuickCheck.new.25356/ghc-QuickCheck.changes
2019-04-03 09:27:05.983789371 +0200
@@ -1,0 +2,27 @@
+Sat Mar 30 19:21:39 UTC 2019 - psimons@xxxxxxxx
+
+- Update QuickCheck to version 2.13.1.
+ QuickCheck 2.13.1 (release 2019-03-29)
+ * A couple of bug fixes
+
+ QuickCheck 2.13 (released 2019-03-26)
+ * Properties with multiple arguments now shrink better.
+ Previously, the first argument was shrunk, then the second, and
+ so on. Now, the arguments are shrunk as a whole, so shrink steps
+ for different arguments can be interleaved.
+
+ * New features:
+ - New modifiers Negative and NonPositive
+ - A Testable instance for Maybe prop (where Nothing means
'discard
+ the test case')
+ * Dependencies on C code removed:
+ - Use splitmix instead of tf-random for random number generation
+ - Remove dependency on 'erf' package
+ * Small changes:
+ - Say 'Falsified' instead of 'Falsifiable' when a property fails
+ * Compatibility improvements:
+ - Explicitly derive instance Typeable Args
+ - Lower bound on deepseq
+ - A script for building Hugs packages
+
+-------------------------------------------------------------------

Old:
----
QuickCheck-2.12.6.1.tar.gz

New:
----
QuickCheck-2.13.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-QuickCheck.spec ++++++
--- /var/tmp/diff_new_pack.2GQHns/_old 2019-04-03 09:27:07.551790109 +0200
+++ /var/tmp/diff_new_pack.2GQHns/_new 2019-04-03 09:27:07.571790118 +0200
@@ -1,7 +1,7 @@
#
# spec file for package ghc-QuickCheck
#
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
%global pkg_name QuickCheck
%bcond_with tests
Name: ghc-%{pkg_name}
-Version: 2.12.6.1
+Version: 2.13.1
Release: 0
Summary: Automatic testing of Haskell programs
License: BSD-3-Clause
@@ -29,11 +29,10 @@
BuildRequires: ghc-Cabal-devel
BuildRequires: ghc-containers-devel
BuildRequires: ghc-deepseq-devel
-BuildRequires: ghc-erf-devel
BuildRequires: ghc-random-devel
BuildRequires: ghc-rpm-macros
+BuildRequires: ghc-splitmix-devel
BuildRequires: ghc-template-haskell-devel
-BuildRequires: ghc-tf-random-devel
BuildRequires: ghc-transformers-devel
%if %{with tests}
BuildRequires: ghc-process-devel
@@ -60,7 +59,7 @@
<https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html>, a detailed
tutorial written by a user of QuickCheck.

-The <http://hackage.haskell.org/package/quickcheck-instances
+The <https://hackage.haskell.org/package/quickcheck-instances
quickcheck-instances> companion package provides instances for types in Haskell
Platform packages at the cost of additional dependencies.


++++++ QuickCheck-2.12.6.1.tar.gz -> QuickCheck-2.13.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/LICENSE
new/QuickCheck-2.13.1/LICENSE
--- old/QuickCheck-2.12.6.1/LICENSE 1970-01-01 01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/LICENSE 2019-03-27 08:33:34.000000000 +0100
@@ -1,8 +1,8 @@
(The following is the 3-clause BSD license.)

-Copyright (c) 2000-2018, Koen Claessen
+Copyright (c) 2000-2019, Koen Claessen
Copyright (c) 2006-2008, Björn Bringert
-Copyright (c) 2009-2018, Nick Smallbone
+Copyright (c) 2009-2019, Nick Smallbone

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/QuickCheck.cabal
new/QuickCheck-2.13.1/QuickCheck.cabal
--- old/QuickCheck-2.12.6.1/QuickCheck.cabal 1970-01-01 01:00:00.000000000
+0100
+++ new/QuickCheck-2.13.1/QuickCheck.cabal 2019-03-29 06:56:48.000000000
+0100
@@ -1,10 +1,10 @@
Name: QuickCheck
-Version: 2.12.6.1
+Version: 2.13.1
Cabal-Version: >= 1.8
Build-type: Simple
License: BSD3
License-file: LICENSE
-Copyright: 2000-2018 Koen Claessen, 2006-2008 Björn Bringert, 2009-2018 Nick
Smallbone
+Copyright: 2000-2019 Koen Claessen, 2006-2008 Björn Bringert, 2009-2019 Nick
Smallbone
Author: Koen Claessen <koen@xxxxxxxxxxx>
Maintainer: Nick Smallbone <nick@xxxxxxxxxxxx>
Bug-reports: https://github.com/nick8325/quickcheck/issues
@@ -33,7 +33,7 @@
* <https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html>,
a detailed tutorial written by a user of QuickCheck.
.
- The <http://hackage.haskell.org/package/quickcheck-instances
quickcheck-instances>
+ The <https://hackage.haskell.org/package/quickcheck-instances
quickcheck-instances>
companion package provides instances for types in Haskell Platform packages
at the cost of additional dependencies.

@@ -47,6 +47,7 @@
examples/Merge.hs
examples/Set.hs
examples/Simple.hs
+ make-hugs

source-repository head
type: git
@@ -55,14 +56,14 @@
source-repository this
type: git
location: https://github.com/nick8325/quickcheck
- tag: 2.12.6.1
+ tag: 2.13.1

flag templateHaskell
Description: Build Test.QuickCheck.All, which uses Template Haskell.
Default: True

library
- Build-depends: base >=4.3 && <5, random, containers, erf >= 2
+ Build-depends: base >=4.3 && <5, random, containers

-- Modules that are always built.
Exposed-Modules:
@@ -84,7 +85,7 @@
-- GHC-specific modules.
if impl(ghc)
Exposed-Modules: Test.QuickCheck.Function
- Build-depends: transformers >= 0.3, deepseq
+ Build-depends: transformers >= 0.3, deepseq >= 1.1.0.0
else
cpp-options: -DNO_TRANSFORMERS -DNO_DEEPSEQ

@@ -109,11 +110,11 @@
if impl (ghc < 7.4)
cpp-options: -DNO_SAFE_HASKELL

- -- Use tf-random on newer GHCs.
- if impl(ghc)
- Build-depends: tf-random >= 0.4
+ -- Use splitmix on newer GHCs.
+ if impl(ghc >= 7.0)
+ Build-depends: splitmix >= 0.0.2
else
- cpp-options: -DNO_TF_RANDOM
+ cpp-options: -DNO_SPLITMIX

if !impl(ghc >= 7.6)
cpp-options: -DNO_POLYKINDS
@@ -125,7 +126,7 @@
if !impl(ghc)
-- If your Haskell compiler can cope without some of these, please
-- send a message to the QuickCheck mailing list!
- cpp-options: -DNO_TIMEOUT -DNO_NEWTYPE_DERIVING -DNO_GENERICS
-DNO_TEMPLATE_HASKELL -DNO_SAFE_HASKELL -DNO_TYPEABLE
+ cpp-options: -DNO_TIMEOUT -DNO_NEWTYPE_DERIVING -DNO_GENERICS
-DNO_TEMPLATE_HASKELL -DNO_SAFE_HASKELL -DNO_TYPEABLE -DNO_GADTS
if !impl(hugs) && !impl(uhc)
cpp-options: -DNO_ST_MONAD -DNO_MULTI_PARAM_TYPE_CLASSES

@@ -154,7 +155,7 @@
hs-source-dirs: tests
main-is: GCoArbitraryExample.hs
build-depends: base, QuickCheck
- if !impl(ghc >= 7.2)
+ if !flag(templateHaskell) || !impl(ghc >= 7.2)
buildable: False
if impl(ghc >= 7.2) && impl(ghc < 7.6)
build-depends: ghc-prim
@@ -172,7 +173,7 @@
hs-source-dirs: tests
main-is: GShrinkExample.hs
build-depends: base, QuickCheck
- if !impl(ghc >= 7.2)
+ if !flag(templateHaskell) || !impl(ghc >= 7.2)
buildable: False
if impl(ghc >= 7.2) && impl(ghc < 7.6)
build-depends: ghc-prim
@@ -181,8 +182,8 @@
type: exitcode-stdio-1.0
hs-source-dirs: tests
main-is: Terminal.hs
- build-depends: base, process, deepseq, QuickCheck
- if !impl(ghc >= 7.10)
+ build-depends: base, process, deepseq >= 1.1.0.0, QuickCheck
+ if !flag(templateHaskell) || !impl(ghc >= 7.10)
buildable: False

Test-Suite test-quickcheck-monadfix
@@ -190,5 +191,19 @@
hs-source-dirs: tests
main-is: MonadFix.hs
build-depends: base, QuickCheck
- if !impl(ghc >= 7.10)
+ if !flag(templateHaskell) || !impl(ghc >= 7.10)
+ buildable: False
+
+Test-Suite test-quickcheck-split
+ type: exitcode-stdio-1.0
+ hs-source-dirs: tests
+ main-is: Split.hs
+ build-depends: base, QuickCheck
+
+Test-Suite test-quickcheck-misc
+ type: exitcode-stdio-1.0
+ hs-source-dirs: tests
+ main-is: Misc.hs
+ build-depends: base, QuickCheck
+ if !flag(templateHaskell) || !impl(ghc >= 7.10)
buildable: False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/README
new/QuickCheck-2.13.1/README
--- old/QuickCheck-2.12.6.1/README 1970-01-01 01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/README 2019-03-28 13:31:22.000000000 +0100
@@ -7,4 +7,7 @@
The quickcheck-instances [1] companion package provides instances for types in
Haskell Platform packages at the cost of additional dependencies.

+The make-hugs script makes a Hugs-compatible version of QuickCheck.
+It may also be useful for other non-GHC implementations.
+
[1]: http://hackage.haskell.org/package/quickcheck-instances
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Exception.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Exception.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Exception.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Exception.hs 2019-03-27
08:35:06.000000000 +0100
@@ -59,15 +59,17 @@
tryEvaluateIO :: IO a -> IO (Either AnException a)
tryEvaluateIO m = E.tryJust notAsync (m >>= E.evaluate)
where
- notAsync :: E.SomeException -> Maybe AnException
+ notAsync :: AnException -> Maybe AnException
#if MIN_VERSION_base(4,7,0)
notAsync e = case E.fromException e of
Just (E.SomeAsyncException _) -> Nothing
Nothing -> Just e
-#else
+#elif !defined(OLD_EXCEPTIONS)
notAsync e = case E.fromException e :: Maybe E.AsyncException of
Just _ -> Nothing
Nothing -> Just e
+#else
+ notAsync e = Just e
#endif

--tryEvaluateIO m = Right `fmap` m
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Features.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Features.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Features.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Features.hs 2018-11-17
21:28:13.000000000 +0100
@@ -92,7 +92,7 @@
Failure{reason = "New feature found"} -> do
putLine (terminal state) $
"*** Found example of " ++
- intercalate ", " (Set.toList (feats' Set.\\ feats))
+ concat (intersperse ", " (Set.toList (feats' Set.\\ feats)))
mapM_ (putLine (terminal state)) (failingTestCase res)
putStrLn ""
loop (Set.union feats feats')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Function.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Function.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Function.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Function.hs 2019-01-19
22:22:47.000000000 +0100
@@ -27,7 +27,7 @@
-- >>> prop (Fun _ f) = f "monkey" == f "banana" || f "banana" == f
"elephant"
-- >>> :}
-- >>> quickCheck prop
--- *** Failed! Falsifiable (after 3 tests and 134 shrinks):
+-- *** Failed! Falsified (after 3 tests and 134 shrinks):
-- {"elephant"->1, "monkey"->1, _->0}
--
-- To generate random values of type @'Fun' a b@,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Gen.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Gen.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Gen.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Gen.hs 2019-03-27
08:42:06.000000000 +0100
@@ -41,9 +41,11 @@

-- | A generator for values of type @a@.
--
--- The third-party package
+-- The third-party packages
-- <http://hackage.haskell.org/package/QuickCheck-GenT QuickCheck-GenT>
--- provides a monad transformer version of @GenT@.
+-- and
+-- <http://hackage.haskell.org/package/quickcheck-transformer
quickcheck-transformer>
+-- provide monad transformer versions of @Gen@.
newtype Gen a = MkGen{
unGen :: QCGen -> Int -> a -- ^ Run the generator on a particular seed.
-- If you just want to get a random value out,
consider using 'generate'.
@@ -80,7 +82,7 @@

-- | Modifies a generator using an integer seed.
variant :: Integral n => n -> Gen a -> Gen a
-variant k (MkGen g) = MkGen (\r n -> g (variantQCGen k r) n)
+variant k (MkGen g) = MkGen (\r n -> g (integerVariant (toInteger k) $! r) n)

-- | Used to construct generators that depend on the size parameter.
--
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Modifiers.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Modifiers.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Modifiers.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Modifiers.hs 2019-03-27
08:42:06.000000000 +0100
@@ -54,8 +54,10 @@
, InfiniteList(..)
, SortedList(..)
, Positive(..)
+ , Negative(..)
, NonZero(..)
, NonNegative(..)
+ , NonPositive(..)
, Large(..)
, Small(..)
, Smart(..)
@@ -186,7 +188,7 @@
-- the remaining (infinite) part can contain anything:
--
-- >>> quickCheck prop_take_10
--- *** Failed! Falsifiable (after 1 test and 14 shrinks):
+-- *** Failed! Falsified (after 1 test and 14 shrinks):
-- "bbbbbbbbbb" ++ ...
data InfiniteList a =
InfiniteList {
@@ -262,15 +264,27 @@
fmap f (Positive x) = Positive (f x)

instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where
- arbitrary =
- ((Positive . abs) `fmap` (arbitrary `suchThat` (/= 0))) `suchThat` gt0
- where gt0 (Positive x) = x > 0
-
- shrink (Positive x) =
- [ Positive x'
- | x' <- shrink x
- , x' > 0
- ]
+ arbitrary = fmap Positive (fmap abs arbitrary `suchThat` (> 0))
+ shrink (Positive x) = [ Positive x' | x' <- shrink x , x' > 0 ]
+
+--------------------------------------------------------------------------
+-- | @Negative x@: guarantees that @x \< 0@.
+newtype Negative a = Negative {getNegative :: a}
+ deriving ( Eq, Ord, Show, Read
+#ifndef NO_NEWTYPE_DERIVING
+ , Enum
+#endif
+#ifndef NO_TYPEABLE
+ , Typeable
+#endif
+ )
+
+instance Functor Negative where
+ fmap f (Negative x) = Negative (f x)
+
+instance (Num a, Ord a, Arbitrary a) => Arbitrary (Negative a) where
+ arbitrary = fmap Negative (arbitrary `suchThat` (< 0))
+ shrink (Negative x) = [ Negative x' | x' <- shrink x , x' < 0 ]

--------------------------------------------------------------------------
-- | @NonZero x@: guarantees that @x \/= 0@.
@@ -308,20 +322,27 @@
fmap f (NonNegative x) = NonNegative (f x)

instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonNegative a) where
- arbitrary =
- (frequency
- -- why is this distrbution like this?
- [ (5, (NonNegative . abs) `fmap` arbitrary)
- , (1, return (NonNegative 0))
- ]
- ) `suchThat` ge0
- where ge0 (NonNegative x) = x >= 0
-
- shrink (NonNegative x) =
- [ NonNegative x'
- | x' <- shrink x
- , x' >= 0
- ]
+ arbitrary = fmap NonNegative (fmap abs arbitrary `suchThat` (>= 0))
+ shrink (NonNegative x) = [ NonNegative x' | x' <- shrink x , x' >= 0 ]
+
+--------------------------------------------------------------------------
+-- | @NonPositive x@: guarantees that @x \<= 0@.
+newtype NonPositive a = NonPositive {getNonPositive :: a}
+ deriving ( Eq, Ord, Show, Read
+#ifndef NO_NEWTYPE_DERIVING
+ , Enum
+#endif
+#ifndef NO_TYPEABLE
+ , Typeable
+#endif
+ )
+
+instance Functor NonPositive where
+ fmap f (NonPositive x) = NonPositive (f x)
+
+instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonPositive a) where
+ arbitrary = fmap NonPositive (arbitrary `suchThat` (<= 0))
+ shrink (NonPositive x) = [ NonPositive x' | x' <- shrink x , x' <= 0 ]

--------------------------------------------------------------------------
-- | @Large x@: by default, QuickCheck generates 'Int's drawn from a small
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Property.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Property.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Property.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Property.hs 2019-03-28
13:31:33.000000000 +0100
@@ -94,6 +94,16 @@
-- | Convert the thing to a property.
property :: prop -> Property

+ -- | Optional; used internally in order to improve shrinking.
+ -- Tests a property but also quantifies over an extra value
+ -- (with a custom shrink and show function).
+ -- The 'Testable' instance for functions defines
+ -- @propertyForAllShrinkShow@ in a way that improves shrinking.
+ propertyForAllShrinkShow :: Gen a -> (a -> [a]) -> (a -> [String]) -> (a ->
prop) -> Property
+ propertyForAllShrinkShow gen shr shw f =
+ forAllShrinkBlind gen shr $
+ \x -> foldr counterexample (property (f x)) (shw x)
+
-- | If a property returns 'Discard', the current test case is discarded,
-- the same as if a precondition was false.
--
@@ -115,6 +125,13 @@
-- so that we turn exceptions into test failures
liftUnit () = succeeded

+instance Testable prop => Testable (Maybe prop) where
+ property = property . liftMaybe
+ where
+ -- See comment for liftUnit above
+ liftMaybe Nothing = property Discard
+ liftMaybe (Just prop) = property prop
+
instance Testable Bool where
property = property . liftBool

@@ -122,13 +139,13 @@
property = MkProperty . return . MkProp . protectResults . return

instance Testable Prop where
- property (MkProp r) = MkProperty . return . MkProp . ioRose . return $ r
+ property p = MkProperty . return . protectProp $ p

instance Testable prop => Testable (Gen prop) where
property mp = MkProperty $ do p <- mp; unProperty (again p)

instance Testable Property where
- property (MkProperty mp) = MkProperty $ do p <- mp; unProperty (property p)
+ property (MkProperty mp) = MkProperty (fmap protectProp mp)

-- | Do I/O inside a property.
{-# DEPRECATED morallyDubiousIOProperty "Use 'ioProperty' instead" #-}
@@ -157,7 +174,16 @@
promote . fmap (unProperty . property)

instance (Arbitrary a, Show a, Testable prop) => Testable (a -> prop) where
- property f = forAllShrink arbitrary shrink f
+ property f =
+ propertyForAllShrinkShow arbitrary shrink (return . show) f
+ propertyForAllShrinkShow gen shr shw f =
+ -- gen :: Gen b, shr :: b -> [b], f :: b -> a -> prop
+ -- Idea: Generate and shrink (b, a) as a pair
+ propertyForAllShrinkShow
+ (liftM2 (,) gen arbitrary)
+ (liftShrink2 shr shrink)
+ (\(x, y) -> shw x ++ [show y])
+ (uncurry f)

-- ** Exception handling
protect :: (AnException -> a) -> IO a -> IO a
@@ -216,6 +242,10 @@
protectRose :: IO (Rose Result) -> IO (Rose Result)
protectRose = protect (return . exception "Exception")

+-- | Wrap the top level of a 'Prop' in an exception handler.
+protectProp :: Prop -> Prop
+protectProp (MkProp r) = MkProp (IORose . protectRose . return $ r)
+
-- | Wrap all the Results in a rose tree in exception handlers.
protectResults :: Rose Result -> Rose Result
protectResults = onRose $ \x rs ->
@@ -305,7 +335,7 @@

liftBool :: Bool -> Result
liftBool True = succeeded
-liftBool False = failed { reason = "Falsifiable" }
+liftBool False = failed { reason = "Falsified" }

mapResult :: Testable prop => (Result -> Result) -> prop -> Property
mapResult f = mapRoseResult (protectResults . fmap f)
@@ -505,7 +535,9 @@
-- not what you want, use 'tabulate'.
label :: Testable prop => String -> prop -> Property
label s =
+#ifndef NO_DEEPSEQ
s `deepseq`
+#endif
mapTotalResult $
\res -> res { labels = s:labels res }

@@ -553,7 +585,9 @@
-> prop -> Property
classify False _ = property
classify True s =
+#ifndef NO_DEEPSEQ
s `deepseq`
+#endif
mapTotalResult $
\res -> res { classes = s:classes res }

@@ -654,7 +688,9 @@
-- 16% LogOut
tabulate :: Testable prop => String -> [String] -> prop -> Property
tabulate key values =
+#ifndef NO_DEEPSEQ
key `deepseq` values `deepseq`
+#endif
mapTotalResult $
\res -> res { tables = [(key, value) | value <- values] ++ tables res }

@@ -704,7 +740,9 @@
coverTable :: Testable prop =>
String -> [(String, Double)] -> prop -> Property
coverTable table xs =
- tables `deepseq` xs `deepseq`
+#ifndef NO_DEEPSEQ
+ table `deepseq` xs `deepseq`
+#endif
mapTotalResult $
\res -> res { requiredCoverage = ys ++ requiredCoverage res }
where
@@ -721,6 +759,16 @@

-- | Considers a property failed if it does not complete within
-- the given number of microseconds.
+--
+-- Note: if the property times out, variables quantified inside the
+-- `within` will not be printed. Therefore, you should use `within`
+-- only in the body of your property.
+--
+-- Good: @prop_foo a b c = within 1000000 ...@
+--
+-- Bad: @prop_foo = within 1000000 $ \\a b c -> ...@
+--
+-- Bad: @prop_foo a b c = ...; main = quickCheck (within 1000000 prop_foo)@
within :: Testable prop => Int -> prop -> Property
within n = mapRoseResult f
where
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Random.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Random.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Random.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Random.hs 2019-03-27
08:42:06.000000000 +0100
@@ -6,65 +6,23 @@
#endif
module Test.QuickCheck.Random where

-#ifndef NO_TF_RANDOM
import System.Random
-import System.Random.TF
-import System.Random.TF.Gen(splitn)
-import Data.Word
-import Data.Bits
-
-#define TheGen TFGen
-
-newTheGen :: IO TFGen
-newTheGen = newTFGen
-
-bits, mask, doneBit :: Integral a => a
-bits = 14
-mask = 0x3fff
-doneBit = 0x4000
-
-chip :: Bool -> Word32 -> TFGen -> TFGen
-chip done n g = splitn g (bits+1) (if done then m .|. doneBit else m)
- where
- m = n .&. mask
-
-chop :: Integer -> Integer
-chop n = n `shiftR` bits
-
-stop :: Integral a => a -> Bool
-stop n = n <= mask
-
-mkTheGen :: Int -> TFGen
-mkTheGen = mkTFGen
-
-#else
-import System.Random
-
-#define TheGen StdGen
-
-newTheGen :: IO StdGen
-newTheGen = newStdGen
-
-mkTheGen :: Int -> StdGen
-mkTheGen = mkStdGen
-
-chip :: Bool -> Int -> StdGen -> StdGen
-chip finished n = boolVariant finished . boolVariant (even n)
-
-chop :: Integer -> Integer
-chop n = n `div` 2
-
-stop :: Integral a => a -> Bool
-stop n = n <= 1
+#ifndef NO_SPLITMIX
+import System.Random.SplitMix
#endif
+import Data.Bits

-- | The "standard" QuickCheck random number generator.
--- A wrapper around either 'TFGen' on GHC, or 'StdGen'
+-- A wrapper around either 'SMGen' on GHC, or 'StdGen'
-- on other Haskell systems.
-newtype QCGen = QCGen TheGen
+#ifdef NO_SPLITMIX
+newtype QCGen = QCGen StdGen
+#else
+newtype QCGen = QCGen SMGen
+#endif

instance Show QCGen where
- showsPrec n (QCGen g) s = showsPrec n g "" ++ s
+ showsPrec n (QCGen g) s = showsPrec n g s
instance Read QCGen where
readsPrec n xs = [(QCGen g, ys) | (g, ys) <- readsPrec n xs]

@@ -78,32 +36,55 @@
(x, g') -> (x, QCGen g')

newQCGen :: IO QCGen
-newQCGen = fmap QCGen newTheGen
+#ifdef NO_SPLITMIX
+newQCGen = fmap QCGen newStdGen
+#else
+newQCGen = fmap QCGen newSMGen
+#endif

mkQCGen :: Int -> QCGen
-mkQCGen n = QCGen (mkTheGen n)
+#ifdef NO_SPLITMIX
+mkQCGen n = QCGen (mkStdGen n)
+#else
+mkQCGen n = QCGen (mkSMGen (fromIntegral n))
+#endif
+
+-- Parameterised in order to make this code testable.
+class Splittable a where
+ left, right :: a -> a
+
+instance Splittable QCGen where
+ left = fst . split
+ right = snd . split
+
+-- The logic behind 'variant'. Given a random number seed, and an integer, uses
+-- splitting to transform the seed according to the integer. We use a
+-- prefix-free code so that calls to integerVariant n g for different values of
+-- n are guaranteed to return independent seeds.
+{-# INLINE integerVariant #-}
+integerVariant :: Splittable a => Integer -> a -> a
+integerVariant n g
+ -- Use one bit to encode the sign, then use Elias gamma coding
+ -- (https://en.wikipedia.org/wiki/Elias_gamma_coding) to do the rest.
+ -- Actually, the first bit encodes whether n >= 1 or not;
+ -- this has the advantage that both 0 and 1 get short codes.
+ | n >= 1 = gamma n $! left g
+ | otherwise = gamma (1-n) $! right g
+ where
+ gamma n =
+ encode k . zeroes k
+ where
+ k = ilog2 n
+
+ encode (-1) g = g
+ encode k g
+ | testBit n k =
+ encode (k-1) $! right g
+ | otherwise =
+ encode (k-1) $! left g

-bigNatVariant :: Integer -> TheGen -> TheGen
-bigNatVariant n g
- | g `seq` stop n = chip True (fromInteger n) g
- | otherwise = (bigNatVariant $! chop n) $! chip False (fromInteger n) g
-
-{-# INLINE natVariant #-}
-natVariant :: Integral a => a -> TheGen -> TheGen
-natVariant n g
- | g `seq` stop n = chip True (fromIntegral n) g
- | otherwise = bigNatVariant (toInteger n) g
-
-{-# INLINE variantTheGen #-}
-variantTheGen :: Integral a => a -> TheGen -> TheGen
-variantTheGen n g
- | n >= 1 = natVariant (n-1) (boolVariant False g)
- | n == 0 = natVariant (0 `asTypeOf` n) (boolVariant True g)
- | otherwise = bigNatVariant (negate (toInteger n)) (boolVariant True g)
-
-boolVariant :: Bool -> TheGen -> TheGen
-boolVariant False = fst . split
-boolVariant True = snd . split
+ zeroes 0 g = g
+ zeroes k g = zeroes (k-1) $! left g

-variantQCGen :: Integral a => a -> QCGen -> QCGen
-variantQCGen n (QCGen g) = QCGen (variantTheGen n g)
+ ilog2 1 = 0
+ ilog2 n = 1 + ilog2 (n `div` 2)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Test.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Test.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Test.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Test.hs 2019-03-27
08:42:06.000000000 +0100
@@ -1,6 +1,9 @@
{-# OPTIONS_HADDOCK hide #-}
-- | The main test loop.
{-# LANGUAGE CPP #-}
+#ifndef NO_TYPEABLE
+{-# LANGUAGE DeriveDataTypeable #-}
+#endif
#ifndef NO_SAFE_HASKELL
{-# LANGUAGE Trustworthy #-}
#endif
@@ -17,7 +20,6 @@
import qualified Test.QuickCheck.State as S
import Test.QuickCheck.Exception
import Test.QuickCheck.Random
-import Data.Number.Erf(invnormcdf)
import System.Random(split)
#if defined(MIN_VERSION_containers)
#if MIN_VERSION_containers(0,5,0)
@@ -41,16 +43,18 @@
, sortBy
, group
, intersperse
- , intercalate
)

import Data.Maybe(fromMaybe, isNothing, catMaybes)
import Data.Ord(comparing)
import Text.Printf(printf)
-import Data.Either(lefts, rights)
import Control.Monad
import Data.Bits

+#ifndef NO_TYPEABLE
+import Data.Typeable (Typeable)
+#endif
+
--------------------------------------------------------------------------
-- quickCheck

@@ -79,7 +83,11 @@
-- ^ Maximum number of shrinks to before giving up. Setting this to zero
-- turns shrinking off.
}
- deriving ( Show, Read )
+ deriving ( Show, Read
+#ifndef NO_TYPEABLE
+ , Typeable
+#endif
+ )

-- | Result represents the test result
data Result
@@ -167,6 +175,12 @@
--
-- By default up to 100 tests are performed, which may not be enough
-- to find all bugs. To run more tests, use 'withMaxSuccess'.
+--
+-- If you want to get the counterexample as a Haskell value,
+-- rather than just printing it, try the
+-- <http://hackage.haskell.org/package/quickcheck-with-counterexamples
quickcheck-with-counterexamples>
+-- package.
+
quickCheck :: Testable prop => prop -> IO ()
quickCheck p = quickCheckWith stdArgs p

@@ -390,16 +404,16 @@
where
summary =
header ++
- short 26 (oneLine reason ++ " ") ++
+ short 26 (oneLine theReason ++ " ") ++
count True ++ "..."

full =
(header ++
- (if isOneLine reason then reason ++ " " else "") ++
+ (if isOneLine theReason then theReason ++ " " else "") ++
count False ++ ":"):
- if isOneLine reason then [] else lines reason
+ if isOneLine theReason then [] else lines theReason

- reason = P.reason res
+ theReason = P.reason res

header =
if expect res then
@@ -433,10 +447,10 @@
(":":short, long)

labelsAndTables :: State -> ([String], [String])
-labelsAndTables st = (labels, tables)
+labelsAndTables st = (theLabels, theTables)
where
- labels :: [String]
- labels =
+ theLabels :: [String]
+ theLabels =
paragraphs $
[ showTable (numSuccessTests st) Nothing m
| m <- S.classes st:Map.elems numberedLabels ]
@@ -448,8 +462,8 @@
| (labels, n) <- Map.toList (S.labels st),
(i, l) <- zip [0..] labels ]

- tables :: [String]
- tables =
+ theTables :: [String]
+ theTables =
paragraphs $
[ showTable (sum (Map.elems m)) (Just table) m
| (table, m) <- Map.toList (S.tables st) ] ++
@@ -573,6 +587,67 @@
wilsonHigh :: Integer -> Integer -> Double -> Double
wilsonHigh k n a = wilson k n (invnormcdf (1-a/2))

+-- Algorithm taken from
+--
https://web.archive.org/web/20151110174102/http://home.online.no/~pjacklam/notes/invnorm/
+-- Accurate to about one part in 10^9.
+--
+-- The 'erf' package uses the same algorithm, but with an extra step
+-- to get a fully accurate result, which we skip because it requires
+-- the 'erfc' function.
+invnormcdf :: Double -> Double
+invnormcdf p
+ | p < 0 = 0/0
+ | p > 1 = 0/0
+ | p == 0 = -1/0
+ | p == 1 = 1/0
+ | p < p_low =
+ let
+ q = sqrt(-2*log(p))
+ in
+ (((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q+c6) /
+ ((((d1*q+d2)*q+d3)*q+d4)*q+1)
+ | p <= p_high =
+ let
+ q = p - 0.5
+ r = q*q
+ in
+ (((((a1*r+a2)*r+a3)*r+a4)*r+a5)*r+a6)*q /
+ (((((b1*r+b2)*r+b3)*r+b4)*r+b5)*r+1)
+ | otherwise =
+ let
+ q = sqrt(-2*log(1-p))
+ in
+ -(((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q+c6) /
+ ((((d1*q+d2)*q+d3)*q+d4)*q+1)
+ where
+ a1 = -3.969683028665376e+01
+ a2 = 2.209460984245205e+02
+ a3 = -2.759285104469687e+02
+ a4 = 1.383577518672690e+02
+ a5 = -3.066479806614716e+01
+ a6 = 2.506628277459239e+00
+
+ b1 = -5.447609879822406e+01
+ b2 = 1.615858368580409e+02
+ b3 = -1.556989798598866e+02
+ b4 = 6.680131188771972e+01
+ b5 = -1.328068155288572e+01
+
+ c1 = -7.784894002430293e-03
+ c2 = -3.223964580411365e-01
+ c3 = -2.400758277161838e+00
+ c4 = -2.549732539343734e+00
+ c5 = 4.374664141464968e+00
+ c6 = 2.938163982698783e+00
+
+ d1 = 7.784695709041462e-03
+ d2 = 3.224671290700398e-01
+ d3 = 2.445134137142996e+00
+ d4 = 3.754408661907416e+00
+
+ p_low = 0.02425
+ p_high = 1 - p_low
+
addCoverageCheck :: Confidence -> State -> Property -> Property
addCoverageCheck confidence st prop
| and [ sufficientlyCovered confidence tot n p
@@ -581,9 +656,9 @@
once prop
| or [ insufficientlyCovered (Just (certainty confidence)) tot n p
| (_, _, tot, n, p) <- allCoverage st ] =
- let (labels, tables) = labelsAndTables st in
+ let (theLabels, theTables) = labelsAndTables st in
foldr counterexample (property failed{P.reason = "Insufficient coverage"})
- (paragraphs [labels, tables])
+ (paragraphs [theLabels, theTables])
| otherwise = prop

allCoverage :: State -> [(Maybe String, String, Int, Int, Double)]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck/Text.hs
new/QuickCheck-2.13.1/Test/QuickCheck/Text.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck/Text.hs 1970-01-01
01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck/Text.hs 2018-11-17
21:20:32.000000000 +0100
@@ -125,7 +125,7 @@
cols = transpose rows
widths = map (maximum . map (length . text)) cols

- row cells = intercalate " " (zipWith cell widths cells)
+ row cells = concat (intersperse " " (zipWith cell widths cells))
cell n (LJust xs) = ljust n xs
cell n (RJust xs) = rjust n xs
cell n (Centred xs) = centre n xs
@@ -149,7 +149,7 @@
border x y xs = [x, y] ++ centre width xs ++ [y, x]

paragraphs :: [[String]] -> [String]
-paragraphs = intercalate [""] . filter (not . null)
+paragraphs = concat . intersperse [""] . filter (not . null)

bold :: String -> String
-- not portable:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/Test/QuickCheck.hs
new/QuickCheck-2.13.1/Test/QuickCheck.hs
--- old/QuickCheck-2.12.6.1/Test/QuickCheck.hs 1970-01-01 01:00:00.000000000
+0100
+++ new/QuickCheck-2.13.1/Test/QuickCheck.hs 2019-03-22 16:01:07.000000000
+0100
@@ -136,6 +136,7 @@
, sample
, sample'

+#ifndef NO_GADTS
-- * The 'Function' typeclass: generation of random shrinkable, showable
functions

-- | Example of use:
@@ -145,7 +146,7 @@
-- >>> prop (Fun _ f) = f "monkey" == f "banana" || f "banana" == f
"elephant"
-- >>> :}
-- >>> quickCheck prop
- -- *** Failed! Falsifiable (after 3 tests and 134 shrinks):
+ -- *** Failed! Falsified (after 3 tests and 134 shrinks):
-- {"elephant"->1, "monkey"->1, _->0}
--
-- To generate random values of type @'Fun' a b@,
@@ -170,6 +171,7 @@
, functionIntegral
, functionRealFrac
, functionBoundedEnum
+#endif

-- * The 'CoArbitrary' typeclass: generation of functions the
old-fashioned way
, CoArbitrary(..)
@@ -220,8 +222,10 @@
, InfiniteList(..)
, SortedList(..)
, Positive(..)
+ , Negative(..)
, NonZero(..)
, NonNegative(..)
+ , NonPositive(..)
, Large(..)
, Small(..)
, Smart(..)
@@ -303,7 +307,9 @@
import Test.QuickCheck.Property hiding ( Result(..) )
import Test.QuickCheck.Test
import Test.QuickCheck.Exception
+#ifndef NO_GADTS
import Test.QuickCheck.Function
+#endif
import Test.QuickCheck.Features
import Test.QuickCheck.State
#ifndef NO_TEMPLATE_HASKELL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/changelog
new/QuickCheck-2.13.1/changelog
--- old/QuickCheck-2.12.6.1/changelog 1970-01-01 01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/changelog 2019-03-29 06:20:20.000000000 +0100
@@ -1,3 +1,26 @@
+QuickCheck 2.13.1 (release 2019-03-29)
+ * A couple of bug fixes
+
+QuickCheck 2.13 (released 2019-03-26)
+ * Properties with multiple arguments now shrink better.
+ Previously, the first argument was shrunk, then the second, and
+ so on. Now, the arguments are shrunk as a whole, so shrink steps
+ for different arguments can be interleaved.
+
+ * New features:
+ - New modifiers Negative and NonPositive
+ - A Testable instance for Maybe prop (where Nothing means
'discard
+ the test case')
+ * Dependencies on C code removed:
+ - Use splitmix instead of tf-random for random number generation
+ - Remove dependency on 'erf' package
+ * Small changes:
+ - Say 'Falsified' instead of 'Falsifiable' when a property fails
+ * Compatibility improvements:
+ - Explicitly derive instance Typeable Args
+ - Lower bound on deepseq
+ - A script for building Hugs packages
+
QuickCheck 2.12.6 (released 2018-10-02)
* Make arbitrarySizedBoundedIntegral handle huge sizes correctly.
* Add changelog for QuickCheck 2.12.5 :)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/make-hugs
new/QuickCheck-2.13.1/make-hugs
--- old/QuickCheck-2.12.6.1/make-hugs 1970-01-01 01:00:00.000000000 +0100
+++ new/QuickCheck-2.13.1/make-hugs 2019-03-27 08:33:34.000000000 +0100
@@ -0,0 +1,18 @@
+#!/bin/bash
+cd $(dirname $0)
+for i in $(find Test -name '*.hs'); do
+ mkdir -p quickcheck-hugs/$(dirname $i)
+ # If you want to switch on and off other features, look in
+ # QuickCheck.cabal to see what's available, or submit a patch
+ # adding a new -DNO_... flag.
+ cpphs --noline -DNO_SPLITMIX -DNO_TEMPLATE_HASKELL \
+ -DNO_CTYPES_CONSTRUCTORS -DNO_FOREIGN_C_USECONDS -DNO_GENERICS \
+ -DNO_SAFE_HASKELL -DNO_POLYKINDS -DNO_MONADFAIL -DNO_TIMEOUT \
+ -DNO_NEWTYPE_DERIVING -DNO_TYPEABLE -DNO_GADTS -DNO_TRANSFORMERS \
+ -DNO_DEEPSEQ \
+ $i > quickcheck-hugs/$i
+done
+
+echo "A Hugs-compatible version of QuickCheck is now"
+echo "available in the quickcheck-hugs directory."
+echo "Load it with hugs -98."
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/tests/Generators.hs
new/QuickCheck-2.13.1/tests/Generators.hs
--- old/QuickCheck-2.12.6.1/tests/Generators.hs 1970-01-01 01:00:00.000000000
+0100
+++ new/QuickCheck-2.13.1/tests/Generators.hs 2019-03-22 16:01:07.000000000
+0100
@@ -105,8 +105,8 @@
Arbitrary (f (Extremal Word16)), Show (f (Extremal Word16)),
Arbitrary (f (Extremal Word32)), Show (f (Extremal Word32)),
Arbitrary (f (Extremal Word64)), Show (f (Extremal Word64))) =>
- (forall a. f a -> a) -> (forall a. Integral a => a -> Bool) -> Property
-pathInt f p =
+ Bool -> (forall a. f a -> a) -> (forall a. Integral a => a -> Bool) ->
Property
+pathInt word f p =
conjoin
[counterexample "Int" (path ((p :: Int -> Bool) . getExtremal . f)),
counterexample "Integer" (path ((p :: Integer -> Bool) . f)),
@@ -114,22 +114,28 @@
counterexample "Int16" (path ((p :: Int16 -> Bool) . getExtremal . f)),
counterexample "Int32" (path ((p :: Int32 -> Bool) . getExtremal . f)),
counterexample "Int64" (path ((p :: Int64 -> Bool) . getExtremal . f)),
- counterexample "Word" (path ((p :: Word -> Bool) . getExtremal . f)),
- counterexample "Word8" (path ((p :: Word8 -> Bool) . getExtremal . f)),
- counterexample "Word16" (path ((p :: Word16 -> Bool) . getExtremal . f)),
- counterexample "Word32" (path ((p :: Word32 -> Bool) . getExtremal . f)),
- counterexample "Word64" (path ((p :: Word64 -> Bool) . getExtremal . f))]
-somePathInt f p = expectFailure (pathInt f (not . p))
-
-prop_positive = pathInt getPositive (> 0)
-prop_positive_bound = somePathInt getPositive (== 1)
-
-prop_nonzero = pathInt getNonZero (/= 0)
-prop_nonzero_bound_1 = somePathInt getNonZero (== 1)
-prop_nonzero_bound_2 = somePathInt getNonZero (== -1)
+ counterexample "Word" (not word .||. path ((p :: Word -> Bool) .
getExtremal . f)),
+ counterexample "Word8" (not word .||. path ((p :: Word8 -> Bool) .
getExtremal . f)),
+ counterexample "Word16" (not word .||. path ((p :: Word16 -> Bool) .
getExtremal . f)),
+ counterexample "Word32" (not word .||. path ((p :: Word32 -> Bool) .
getExtremal . f)),
+ counterexample "Word64" (not word .||. path ((p :: Word64 -> Bool) .
getExtremal . f))]
+somePathInt word f p = expectFailure (pathInt word f (not . p))

-prop_nonnegative = pathInt getNonNegative (>= 0)
-prop_nonnegative_bound = somePathInt getNonNegative (== 0)
+prop_positive = pathInt True getPositive (> 0)
+prop_positive_bound = somePathInt True getPositive (== 1)
+
+prop_nonzero = pathInt True getNonZero (/= 0)
+prop_nonzero_bound_1 = somePathInt True getNonZero (== 1)
+prop_nonzero_bound_2 = somePathInt True getNonZero (== -1)
+
+prop_nonnegative = pathInt True getNonNegative (>= 0)
+prop_nonnegative_bound = somePathInt True getNonNegative (== 0)
+
+prop_negative = pathInt False getNegative (< 0)
+prop_negative_bound = somePathInt False getNegative (== -1)
+
+prop_nonpositive = pathInt True getNonPositive (<= 0)
+prop_nonpositive_bound = somePathInt True getNonPositive (== 0)

reachesBound :: (Bounded a, Integral a, Arbitrary a) =>
a -> Property
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/tests/Misc.hs
new/QuickCheck-2.13.1/tests/Misc.hs
--- old/QuickCheck-2.12.6.1/tests/Misc.hs 1970-01-01 01:00:00.000000000
+0100
+++ new/QuickCheck-2.13.1/tests/Misc.hs 2019-03-28 13:31:33.000000000 +0100
@@ -0,0 +1,26 @@
+-- Miscellaneous tests.
+
+{-# LANGUAGE TemplateHaskell #-}
+import Test.QuickCheck
+import Test.QuickCheck.Random
+
+prop_verbose :: Blind (Int -> Int -> Bool) -> Property
+prop_verbose (Blind p) =
+ forAll (mkQCGen <$> arbitrary) $ \g ->
+ ioProperty $ do
+ res1 <- quickCheckWithResult stdArgs{replay = Just (g, 100), chatty =
False} p
+ res2 <- quickCheckWithResult stdArgs{replay = Just (g, 100), chatty =
False} (verbose p)
+ return $
+ numTests res1 === numTests res2 .&&.
+ failingTestCase res1 === failingTestCase res2
+
+prop_failingTestCase :: Blind (Int -> Int -> Int -> Bool) -> Property
+prop_failingTestCase (Blind p) = ioProperty $ do
+ res <- quickCheckWithResult stdArgs{chatty = False} p
+ let [x, y, z] = failingTestCase res
+ return (not (p (read x) (read y) (read z)))
+
+return []
+main = do
+ True <- $quickCheckAll
+ return ()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/QuickCheck-2.12.6.1/tests/Split.hs
new/QuickCheck-2.13.1/tests/Split.hs
--- old/QuickCheck-2.12.6.1/tests/Split.hs 1970-01-01 01:00:00.000000000
+0100
+++ new/QuickCheck-2.13.1/tests/Split.hs 2019-03-27 08:42:06.000000000
+0100
@@ -0,0 +1,28 @@
+import Test.QuickCheck
+import Test.QuickCheck.Random
+import Data.List
+
+-- This type allows us to run integerVariant and get a list of bits out.
+newtype Splits = Splits { unSplits :: [Bool] } deriving (Eq, Ord, Show)
+
+instance Splittable Splits where
+ left (Splits xs) = Splits (xs ++ [False])
+ right (Splits xs) = Splits (xs ++ [True])
+
+-- Check that integerVariant gives a prefix-free code,
+-- i.e., if m /= n then integerVariant m is not a prefix of integerVariant n.
+prop_split_prefix :: Property
+prop_split_prefix =
+ once $ forAllShrink (return [-10000..10000]) shrink $ \ns ->
+ map head (group (sort ns)) == sort ns ==> -- no duplicates
+ let
+ codes :: [Splits]
+ codes = sort [integerVariant n (Splits []) | n <- ns]
+
+ ok (Splits xs) (Splits ys) = not (xs `isPrefixOf` ys)
+ in
+ -- After sorting, any prefix will end up immediately before
+ -- one of its suffixes
+ and (zipWith ok codes (drop 1 codes))
+
+main = do Success{} <- quickCheckResult prop_split_prefix; return ()


< Previous Next >
This Thread
  • No further messages