packages feed

genvalidity 0.9.0.1 → 0.9.1.0

raw patch · 4 files changed

+156/−88 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.GenValidity: genNonEmptyOf :: Gen a -> Gen (NonEmpty a)
+ Data.GenValidity: genSplit6 :: Int -> Gen (Int, Int, Int, Int, Int, Int)
+ Data.GenValidity: genSplit7 :: Int -> Gen (Int, Int, Int, Int, Int, Int, Int)
+ Data.GenValidity: genSplit8 :: Int -> Gen (Int, Int, Int, Int, Int, Int, Int, Int)

Files

genvalidity.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: f4100c2ff93efc9358e859fdff17d5b68f1a71aed4f88e4bcf2dd2e57ae0a795+-- hash: ba44fb99e6f91291452e903b6e2cb6d5b566b8e667c27442668d66fa1abff13f  name:           genvalidity-version:        0.9.0.1+version:        0.9.1.0 synopsis:       Testing utilities for the validity library description:    Note: There are companion instance packages for this library:                 .
src/Data/GenValidity.hs view
@@ -101,7 +101,6 @@ import Data.Fixed (Fixed(..), HasResolution) #if MIN_VERSION_base(4,9,0) import Data.List.NonEmpty (NonEmpty((:|)))-import qualified Data.List.NonEmpty as NE #endif #if MIN_VERSION_base(4,8,0) import Data.Word (Word8, Word16, Word32, Word64)@@ -515,27 +514,15 @@  #if MIN_VERSION_base(4,9,0) instance GenUnchecked a => GenUnchecked (NonEmpty a) where-    genUnchecked = do-      l <- genUnchecked-      case NE.nonEmpty l of-        Nothing -> scale (+1) genUnchecked-        Just ne -> pure ne+    genUnchecked = genNonEmptyOf genUnchecked     shrinkUnchecked (v :| vs) = [ e :| es | (e, es) <- shrinkUnchecked (v, vs)]  instance GenValid a => GenValid (NonEmpty a) where-    genValid = do-      l <- genValid-      case NE.nonEmpty l of-        Nothing -> scale (+1) genValid-        Just ne -> pure ne+    genValid = genNonEmptyOf genValid     shrinkValid (v :| vs) = [ e :| es | (e, es) <- shrinkValid (v, vs)]  instance (GenUnchecked a, GenInvalid a) => GenInvalid (NonEmpty a) where-    genInvalid = do-      l <- genInvalid-      case NE.nonEmpty l of-        Nothing -> scale (+1) genInvalid-        Just ne -> pure ne+    genInvalid = genNonEmptyOf genInvalid #endif  instance GenUnchecked a => GenUnchecked [a] where
src/Data/GenValidity/Utils.hs view
@@ -21,9 +21,15 @@     , genSplit3     , genSplit4     , genSplit5+    , genSplit6+    , genSplit7+    , genSplit8     , arbPartition     , shuffle     , genListOf+#if MIN_VERSION_base(4,9,0)+    , genNonEmptyOf+#endif       -- ** Helper functions for implementing shrinking functions     , shrinkTuple     , shrinkT2@@ -36,12 +42,16 @@ import Data.List (sortBy) import Data.Ord (comparing) #endif+#if MIN_VERSION_base(4,9,0)+import Data.List.NonEmpty(NonEmpty(..))+import qualified Data.List.NonEmpty as NE+#endif  #if MIN_VERSION_base(4,8,0)-import Control.Monad (forM)+import Control.Monad (forM, replicateM) #else import Control.Applicative ((<$>), (<*>), pure)-import Control.Monad (forM)+import Control.Monad (forM, replicateM) #endif -- | 'upTo' generates an integer between 0 (inclusive) and 'n'. upTo :: Int -> Gen Int@@ -87,16 +97,72 @@         (d, e) <- genSplit z         return (a, b, c, d, e) --- | 'arbPartition n' generates a list 'ls' such that 'sum ls' equals 'n'.+-- | 'genSplit6 a' generates a sextuple '(b, c, d, e, f, g)' such that 'b + c + d + e + f + g' equals 'a'.+genSplit6 :: Int -> Gen (Int, Int, Int, Int, Int, Int)+genSplit6 n+    | n < 0 = pure (0, 0, 0, 0, 0, 0)+    | otherwise = do+        (y, z) <- genSplit n+        (a, b, c) <- genSplit3 y+        (d, e, f) <- genSplit3 z+        return (a, b, c, d, e, f)++-- | 'genSplit7 a' generates a septtuple '(b, c, d, e, f, g)' such that 'b + c + d + e + f + g' equals 'a'.+genSplit7 :: Int -> Gen (Int, Int, Int, Int, Int, Int, Int)+genSplit7 n+    | n < 0 = pure (0, 0, 0, 0, 0, 0, 0)+    | otherwise = do+        (y, z) <- genSplit n+        (a, b, c) <- genSplit3 y+        (d, e, f, g) <- genSplit4 z+        return (a, b, c, d, e, f, g)++-- | 'genSplit8 a' generates a octtuple '(b, c, d, e, f, g, h)' such that 'b + c + d + e + f + g + h' equals 'a'.+genSplit8 :: Int -> Gen (Int, Int, Int, Int, Int, Int, Int, Int)+genSplit8 n+    | n < 0 = pure (0, 0, 0, 0, 0, 0, 0, 0)+    | otherwise = do+        (y, z) <- genSplit n+        (a, b, c, d) <- genSplit4 y+        (e, f, g, h) <- genSplit4 z+        return (a, b, c, d, e, f, g, h)+++-- | 'arbPartition n' generates a list 'ls' such that 'sum ls' equals 'n', approximately. arbPartition :: Int -> Gen [Int]-arbPartition i = go i >>= shuffle+arbPartition 0 = pure []+arbPartition i = genLen i >>= go i   where-    go k-        | k <= 0 = pure []-        | otherwise = do-            first <- choose (1, k)-            rest <- arbPartition $ k - first-            return $ first : rest+    genLen :: Int -> Gen Int+    genLen maxLen = round . invT (fromIntegral maxLen) <$> choose (0, 1)++    -- Use a triangle distribution for generating the+    -- length of the list+    -- with minimum length '0', mode length '2'+    -- and given max length.+    invT :: Double -> Double -> Double+    invT maxLen u =+      let a = 0+          b = maxLen+          c = 2+          fc = (c - a) / (b - a)+      in if u < fc+        then a + sqrt (u * (b - a) * (c - a) )+        else b - sqrt ((1 - u) * (b - a) * (b - c))+++    go :: Int -> Int -> Gen [Int]+    go size len = do+      us <- replicateM len $ choose (0, 1)+      let invs = map (invE 0.25) us+      -- Rescale the sizes to (approximately) sum to the given size.+      pure $ map (round . (* (fromIntegral size / sum invs))) invs++    -- Use an exponential distribution for generating the+    -- sizes in the partition.+    invE :: Double -> Double -> Double+    invE lambda u = - log (1 - u) / lambda+ #if !MIN_VERSION_QuickCheck(2,8,0) -- | Generates a random permutation of the given list. shuffle :: [a] -> Gen [a]@@ -104,6 +170,16 @@     ns <- vectorOf (length xs) (choose (minBound :: Int, maxBound))     return (map snd (sortBy (comparing fst) (zip ns xs))) #endif++#if MIN_VERSION_base(4,9,0)+genNonEmptyOf :: Gen a -> Gen (NonEmpty a)+genNonEmptyOf gen = do+  l <- genListOf gen+  case NE.nonEmpty l of+    Nothing -> scale (+1) $ genNonEmptyOf gen+    Just ne -> pure ne+#endif+ -- | A version of @listOf@ that takes size into account more accurately. -- -- This generator distributes the size that is is given among the values@@ -111,8 +187,7 @@ genListOf :: Gen a -> Gen [a] genListOf func =     sized $ \n -> do-        size <- upTo n-        pars <- arbPartition size+        pars <- arbPartition n         forM pars $ \i -> resize i func  shrinkTuple :: (a -> [a]) -> (b -> [b]) -> (a, b) -> [(a, b)]
test/Data/GenValiditySpec.hs view
@@ -1,6 +1,6 @@ module Data.GenValiditySpec-  ( spec-  ) where+    ( spec+    ) where  import Test.Hspec import Test.QuickCheck@@ -9,59 +9,65 @@  spec :: Spec spec = do-  describe "genUtf16SurrogateCodePoint" $-    it "generates Utf16 surrogate codepoints" $-    forAll genUtf16SurrogateCodePoint $ (`shouldSatisfy` isUtf16SurrogateCodePoint)-  describe "upTo" $ do-    it "returns only positive integers" $-      forAll arbitrary $ \n -> forAll (upTo n) (`shouldSatisfy` (>= 0))-    it "returns only integers smaller than or equal to the given number" $-      forAll arbitrary $ \n -> forAll (upTo n) (`shouldSatisfy` (<= (max n 0)))-  describe "genSplit" $ do-    it "returns positive integers" $-      forAll arbitrary $ \i ->-        forAll (genSplit i) $ \(a, b) -> do-          a `shouldSatisfy` (>= 0)-          b `shouldSatisfy` (>= 0)-    it "returns two integers such that the sum is the original integer" $-      forAll arbitrary $ \i -> forAll (genSplit i) $ \(a, b) -> a + b `shouldBe` max 0 i-  describe "genSplit3" $ do-    it "returns positive integers" $-      forAll arbitrary $ \i ->-        forAll (genSplit3 i) $ \(a, b, c) -> do-          a `shouldSatisfy` (>= 0)-          b `shouldSatisfy` (>= 0)-          c `shouldSatisfy` (>= 0)-    it "returns three integers such that the sum is the original integer" $-      forAll arbitrary $ \i -> forAll (genSplit3 i) $ \(a, b, c) -> a + b + c `shouldBe` max 0 i-  describe "genSplit4" $ do-    it "returns positive integers" $-      forAll arbitrary $ \i ->-        forAll (genSplit4 i) $ \(a, b, c, d) -> do-          a `shouldSatisfy` (>= 0)-          b `shouldSatisfy` (>= 0)-          c `shouldSatisfy` (>= 0)-          d `shouldSatisfy` (>= 0)-    it "returns four integers such that the sum is the original integer" $-      forAll arbitrary $ \i ->-        forAll (genSplit4 i) $ \(a, b, c, d) -> a + b + c + d `shouldBe` max 0 i-  describe "genSplit5" $ do-    it "returns positive integers" $-      forAll arbitrary $ \i ->-        forAll (genSplit5 i) $ \(a, b, c, d, e) -> do-          a `shouldSatisfy` (>= 0)-          b `shouldSatisfy` (>= 0)-          c `shouldSatisfy` (>= 0)-          d `shouldSatisfy` (>= 0)-          e `shouldSatisfy` (>= 0)-    it "returns four integers such that the sum is the original integer" $-      forAll arbitrary $ \i ->-        forAll (genSplit5 i) $ \(a, b, c, d, e) -> a + b + c + d + e `shouldBe` max 0 i-  describe "arbPartition" $ do-    it "returns an empty list upon strictly negative input" $-      forAll (arbitrary `suchThat` (< 0)) $ \n -> forAll (arbPartition n) (`shouldBe` [])-    it "returns a list of strictly positive integers" $-      forAll arbitrary $ \n -> forAll (arbPartition n) $ \p -> p `shouldSatisfy` all (> 0)-    it "returns a list of integers that sum to the original positive integer" $-      forAll (arbitrary `suchThat` (>= 0)) $ \n ->-        forAll (arbPartition n) $ \p -> sum p `shouldBe` n+    describe "genUtf16SurrogateCodePoint" $+        it "generates Utf16 surrogate codepoints" $+            forAll genUtf16SurrogateCodePoint $ (`shouldSatisfy` isUtf16SurrogateCodePoint)++    describe "upTo" $ do+        it "returns only positive integers" $+            forAll arbitrary $ \n -> forAll (upTo n) (`shouldSatisfy` (>= 0))+        it "returns only integers smaller than or equal to the given number" $+            forAll arbitrary $ \n ->+                forAll (upTo n) (`shouldSatisfy` (<= (max n 0)))+    describe "genSplit" $ do+        it "returns positive integers" $+            forAll arbitrary $ \i ->+                forAll (genSplit i) $ \(a, b) -> do+                    a `shouldSatisfy` (>= 0)+                    b `shouldSatisfy` (>= 0)+        it "returns two integers such that the sum is the original integer" $+            forAll arbitrary $ \i ->+                forAll (genSplit i) $ \(a, b) -> a + b `shouldBe` max 0 i+    describe "genSplit3" $ do+        it "returns positive integers" $+            forAll arbitrary $ \i ->+                forAll (genSplit3 i) $ \(a, b, c) -> do+                    a `shouldSatisfy` (>= 0)+                    b `shouldSatisfy` (>= 0)+                    c `shouldSatisfy` (>= 0)+        it "returns three integers such that the sum is the original integer" $+            forAll arbitrary $ \i ->+                forAll (genSplit3 i) $ \(a, b, c) ->+                    a + b + c `shouldBe` max 0 i+    describe "genSplit4" $ do+        it "returns positive integers" $+            forAll arbitrary $ \i ->+                forAll (genSplit4 i) $ \(a, b, c, d) -> do+                    a `shouldSatisfy` (>= 0)+                    b `shouldSatisfy` (>= 0)+                    c `shouldSatisfy` (>= 0)+                    d `shouldSatisfy` (>= 0)+        it "returns four integers such that the sum is the original integer" $+            forAll arbitrary $ \i ->+                forAll (genSplit4 i) $ \(a, b, c, d) ->+                    a + b + c + d `shouldBe` max 0 i+    describe "genSplit5" $ do+        it "returns positive integers" $+            forAll arbitrary $ \i ->+                forAll (genSplit5 i) $ \(a, b, c, d, e) -> do+                    a `shouldSatisfy` (>= 0)+                    b `shouldSatisfy` (>= 0)+                    c `shouldSatisfy` (>= 0)+                    d `shouldSatisfy` (>= 0)+                    e `shouldSatisfy` (>= 0)+        it "returns four integers such that the sum is the original integer" $+            forAll arbitrary $ \i ->+                forAll (genSplit5 i) $ \(a, b, c, d, e) ->+                    a + b + c + d + e `shouldBe` max 0 i+    describe "arbPartition" $ do+        it "returns an empty list upon strictly negative input" $+            forAll (arbitrary `suchThat` (< 0)) $ \n ->+                forAll (arbPartition n) (`shouldBe` [])+        it "returns a list of positive integers" $+            forAll arbitrary $ \n ->+                forAll (arbPartition n) $ \p -> p `shouldSatisfy` all (>= 0)