packages feed

smallcheck-series 0.1 → 0.2

raw patch · 7 files changed

+212/−199 lines, 7 files

Files

CHANGELOG.md view
@@ -4,9 +4,17 @@ CHANGELOG](http://keepachangelog.com/). This project adheres to [Semantic Versioning](http://semver.org/). +## [0.2] - 2015-4-28+### Changed+- General renaming to, hopefully, make functions more clear.+### Fixed+- Series don't repeat elements anymore. Kudos to Roman Cheplyaka for+  reporting this issue.+ ## [0.1] - 2015-4-27 ### Added - Initial set of utilities for creating `ByteString` and `Text` `Series`. - `Serial` `ByteString` and `Text` instances. +[0.2]: https://github.com/jdnavarro/smallcheck-series/compare/v0.1...v0.2 [0.1]: https://github.com/jdnavarro/smallcheck-series/compare/49b5b0...v0.1
Test/SmallCheck/Series/ByteString.hs view
@@ -7,81 +7,86 @@ module Test.SmallCheck.Series.ByteString   (   -- * Replication-    aaa-  , zzz-  , replicated+    replicateA+  , replicate0+  , replicateW8   -- * Enumeration-  , ascii-  , alpha-  , enumerated+  , enumW8s+  , enumAlphabet+  , enumList   -- * Printing   , jack   ) where -import Prelude hiding (replicate)-import Control.Applicative ((<$>)) import Data.Char (ord)+import Data.List (inits) import Data.Word (Word8)-import Data.ByteString (ByteString, pack, replicate)+import Data.ByteString (ByteString, pack) import qualified Data.ByteString.Char8 as B8 (pack) import Test.SmallCheck.Series --- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra---   /byte/ representing the 'a' 'Char' in @ASCII@.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by replicating+--   the @97@ 'Word8', which encodes the 'a' 'Char' in @ASCII@. ----- >>> list 4 aaa+-- >>> list 4 replicateA -- ["","a","aa","aaa","aaaa"] ----- Use this when you don't care about the /byte/ inside 'Data.ByteString.ByteString'.-aaa :: Series m ByteString-aaa = replicated . fromIntegral $ ord 'a'+-- Use this when you don't care about the 'Word8' inside 'Data.ByteString.ByteString'.+replicateA :: Series m ByteString+replicateA = replicateW8 97 --- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra @NUL@ byte.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by replicating+--   the @0@ 'Word8'. ----- >>> list 4 zzz+-- >>> list 4 replicate0 -- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]-zzz :: Series m ByteString-zzz = replicated 0+replicate0 :: Series m ByteString+replicate0 = replicateW8 0 --- | Create a 'Data.ByteString.ByteString' 'Series' growing with an extra custom byte.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by replicating+--   the given 'Word8'. ----- >>> list 4 . replicated . fromIntegral $ ord '@'+-- >>> list 4 $ replicateW8 64 -- ["","@","@@","@@@","@@@@"]-replicated :: Word8 -> Series m ByteString-replicated c = generate $ \d -> (`replicate` c) <$> [0..d]+replicateW8 :: Word8 -> Series m ByteString+replicateW8 b =+    generate $ \d -> fmap pack . inits $ replicate d b --- | Create a 'Data.ByteString.ByteString' 'Series' growing with the @ASCII@---   representation of the alphabet.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by enumerating+--   every 'Word8'. ----- >>> list 4 alpha--- ["","a","ab","abc","abcd"]-alpha :: Series m ByteString-alpha = enumerated $ fromIntegral . ord <$> ['a'..'z']+-- >>> list 4 enumW8s+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]+enumW8s :: Series m ByteString+enumW8s = enumList [0..255] --- | Create a 'Data.ByteString.ByteString' 'Series' growing by counting bytes.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by enumerating+--   the 'Word8's which encode the latin alphabet in @ASCII@. ----- >>> list 4 ascii--- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]-ascii :: Series m ByteString-ascii = enumerated [0..255]+-- >>> list 4 enumAlphabet+-- ["","a","ab","abc","abcd"]+enumAlphabet :: Series m ByteString+enumAlphabet = enumList $ fmap (fromIntegral . ord) ['a'..'z'] --- | Create a 'Data.ByteString.ByteString' 'Series' growing with the given byte set.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by enumerating+--   every 'Word8' in the given list. ----- >>> list 4 . enumerated $ fromIntegral . ord <$> "abc"--- ["","a","ab","abc","abc"]-enumerated  :: [Word8] -> Series m ByteString-enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]+-- >>> list 4 . enumList $ fmap (fromIntegral . ord) "abc"+-- ["","a","ab","abc"]+enumList  :: [Word8] -> Series m ByteString+enumList cs = generate $ \d -> fmap pack . inits $ take d cs --- | Create a 'Data.ByteString.ByteString' 'Series' with a dummy @ASCII@ sentence.---   This can be used when you want to print a 'Series' to the screen.+-- | A 'Data.ByteString.ByteString' 'Series' that grows with @ASCII@+--   dummy English words encoded in @ASCII@. --+--   This is useful when you want to print 'Series'.+-- -- >>> let s = list 20 jack -- >>> take 3 s -- ["","All","All work"]--- >>> s !! 10--- "All work and no play makes Jack a dull boy"+-- >>> last s+-- "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy." jack :: Series m ByteString jack = generate $ \d ->-    (\n -> B8.pack . unwords . take n . words $ sentence) <$> [0..d]-  where-    sentence = "All work and no play makes Jack a dull boy"+    fmap (B8.pack . unwords) . inits . take d . cycle . words $+        "All work and no play makes Jack a dull boy."
Test/SmallCheck/Series/ByteString/Lazy.hs view
@@ -7,84 +7,86 @@ module Test.SmallCheck.Series.ByteString.Lazy   (   -- * Replication-    aaa-  , zzz-  , replicated+    replicateA+  , replicate0+  , replicateW8   -- * Enumeration-  , ascii-  , alpha-  , enumerated+  , enumW8s+  , enumAlphabet+  , enumList   -- * Printing   , jack   ) where -import Prelude hiding (replicate)-import Control.Applicative ((<$>)) import Data.Char (ord)+import Data.List (inits) import Data.Word (Word8)-import Data.ByteString.Lazy (ByteString, pack, replicate)+import Data.ByteString.Lazy (ByteString, pack) import qualified Data.ByteString.Lazy.Char8 as L8 (pack) import Test.SmallCheck.Series --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra---   /byte/ representing the 'a' 'Char' in @ASCII@.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows by replicating+--   the @97@ 'Word8', which encodes the 'a' 'Char' in @ASCII@. ----- >>> list 4 aaa+-- >>> list 4 replicateA -- ["","a","aa","aaa","aaaa"] ----- Use this when you don't care about the /byte/ inside 'Data.ByteString.Lazy.ByteString'.-aaa :: Series m ByteString-aaa = replicated . fromIntegral $ ord 'a'+-- Use this when you don't care about the 'Word8' inside 'Data.ByteString.Lazy.ByteString'.+replicateA :: Series m ByteString+replicateA = replicateW8 97 --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra @NUL@ byte.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows by replicating+--   the @0@ 'Word8'. ----- >>> list 4 zzz+-- >>> list 4 replicate0 -- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]-zzz :: Series m ByteString-zzz = replicated 0--replicated :: Word8 -> Series m ByteString-replicated c = generate $ \d -> (`rep` c) <$> [0..d]-  where-    rep = replicate . fromIntegral+replicate0 :: Series m ByteString+replicate0 = replicateW8 0 --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with an extra custom byte.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows by replicating+--   the given 'Word8'. ----- >>> list 4 . replicated . fromIntegral $ ord '@'+-- >>> list 4 $ replicateW8 64 -- ["","@","@@","@@@","@@@@"]+replicateW8 :: Word8 -> Series m ByteString+replicateW8 b =+    generate $ \d -> fmap pack . inits $ (replicate . fromIntegral) d b --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with the @ASCII@---   representation of the alphabet.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows by enumerating+--   every 'Word8'. ----- >>> list 4 alpha--- ["","a","ab","abc","abcd"]-alpha :: Series m ByteString-alpha = enumerated $ fromIntegral . ord <$> ['a'..'z']+-- >>> list 4 enumW8s+-- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]+enumW8s :: Series m ByteString+enumW8s = enumList [0..255] --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing by counting bytes.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows by enumerating+--   the 'Word8's which encode the latin alphabet in @ASCII@. ----- >>> list 4 ascii--- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]-ascii :: Series m ByteString-ascii = enumerated [0..255]+-- >>> list 4 enumAlphabet+-- ["","a","ab","abc","abcd"]+enumAlphabet :: Series m ByteString+enumAlphabet = enumList $ fmap (fromIntegral . ord) ['a'..'z'] --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' growing with the given byte set.+-- | A 'Data.ByteString.ByteString' 'Series' that grows by enumerating+--   every 'Word8' in the given list. ----- >>> list 4 . enumerated $ fromIntegral . ord <$> "abc"--- ["","a","ab","abc","abc"]-enumerated  :: [Word8] -> Series m ByteString-enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]+-- >>> list 4 . enumList $ fmap (fromIntegral . ord) "abc"+-- ["","a","ab","abc"]+enumList  :: [Word8] -> Series m ByteString+enumList cs = generate $ \d -> fmap pack . inits $ take d cs --- | Create a 'Data.ByteString.Lazy.ByteString' 'Series' with a dummy @ASCII@ sentence.---   This can be used when you want to print a 'Series' to the screen.+-- | A 'Data.ByteString.Lazy.ByteString' 'Series' that grows with @ASCII@+--   dummy English words encoded in @ASCII@. --+--   This is useful when you want to print 'Series'.+-- -- >>> let s = list 20 jack -- >>> take 3 s -- ["","All","All work"]--- >>> s !! 10--- "All work and no play makes Jack a dull boy"+-- >>> last s+-- "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy." jack :: Series m ByteString jack = generate $ \d ->-    (\n -> L8.pack . unwords . take n . words $ sentence) <$> [0..d]-  where-    sentence = "All work and no play makes Jack a dull boy"+    fmap (L8.pack . unwords) . inits . take d . cycle . words $+        "All work and no play makes Jack a dull boy."
Test/SmallCheck/Series/Instances.hs view
@@ -31,13 +31,13 @@ import Test.SmallCheck.Series.Text.Lazy as Series.Text.Lazy  instance Monad m => Serial m B.ByteString where-    series = Series.ByteString.aaa+    series = Series.ByteString.replicateA  instance Monad m => Serial m BL.ByteString where-    series = Series.ByteString.Lazy.aaa+    series = Series.ByteString.Lazy.replicateA  instance Monad m => Serial m T.Text where-    series = Series.Text.aaa+    series = Series.Text.replicateA  instance Monad m => Serial m TL.Text where-    series = Series.Text.Lazy.aaa+    series = Series.Text.Lazy.replicateA
Test/SmallCheck/Series/Text.hs view
@@ -7,91 +7,91 @@ module Test.SmallCheck.Series.Text   (   -- * Replication-    aaa-  , zzz-  , replicated+    replicateA+  , replicateNull+  , replicateChar   -- * Enumeration-  , ascii-  , alpha-  , enumerated+  , enumAlphabet+  , enumChars+  , enumString   -- * Printing   , jack   -- * Extra Unicode planes-  , nonBmp+  , enumNonBmp   ) where -import Prelude hiding (replicate)-import Control.Applicative ((<$>))-import Data.Text (Text, pack, singleton, replicate)+import Data.List (inits)+import Data.Text (Text, pack) import Test.SmallCheck.Series --- | Create a 'Data.Text.Text' 'Series' growing with an extra 'a' 'Char'.+-- | A 'Data.Text.Text' 'Series' that grows by replicating the @a@ 'Char'. ----- >>> list 4 aaa+-- >>> list 4 replicateA -- ["","a","aa","aaa","aaaa"] -- -- Use this when you don't care about the 'Char's inside 'Data.Text.Text'.-aaa :: Series m Text-aaa = replicated 'a'+replicateA :: Series m Text+replicateA = replicateChar 'a' --- | Create a 'Data.Text.Text' 'Series' growing with an extra @NUL@ 'Char'.+-- | A 'Data.Text.Text' 'Series' that grows by replicating the @NUL@ 'Char'. ----- >>> list 4 zzz+-- >>> list 4 replicateNull -- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]-zzz :: Series m Text-zzz = replicated '\0'+replicateNull :: Series m Text+replicateNull = replicateChar '\0' --- | Create a 'Data.Text.Text' 'Series' growing with an extra custom 'Char'.+-- | A 'Data.Text.Text' 'Series' that grows by replicating the given 'Char'. ----- >>> list 4 $ replicated '☃'+-- >>> list 4 $ replicateChar '☃' -- ["","\9731","\9731\9731","\9731\9731\9731","\9731\9731\9731\9731"]-replicated :: Char -> Series m Text-replicated c = generate $ \d -> (`replicate` singleton c) <$> [0..d]+replicateChar :: Char -> Series m Text+replicateChar c = generate $ \d -> fmap pack . inits $ replicate d c --- | Create a 'Data.Text.Text' 'Series' growing with the alphabet.+-- | A 'Data.Text.Text' 'Series' that grows by enumerating the latin alphabet. ----- >>> list 4 alpha+-- >>> list 4 enumAlphabet -- ["","a","ab","abc","abcd"]-alpha :: Series m Text-alpha = enumerated ['a'..'z']+enumAlphabet :: Series m Text+enumAlphabet = enumString ['a'..'z'] --- | Create a 'Data.Text.Text' 'Series' growing with @ASCII@ 'Char's set.+-- | A 'Data.Text.Text' 'Series' that grows by enumerating every 'Char'. ----- >>> list 4 ascii+-- >>> list 4 enumChars -- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]-ascii :: Series m Text-ascii = enumerated ['\0'..'\255']+enumChars :: Series m Text+enumChars = enumString ['\0'..] --- | Create a 'Data.Text.Text' 'Series' growing with the given 'Char' set.+-- | A 'Data.Text.Text' 'Series' that grows by enumerating every 'Char' in the+--   given 'String'. Notice that the 'String' can be infinite. ----- >>> list 4 $ enumerated "abc"--- ["","a","ab","abc","abc"]-enumerated :: String -> Series m Text-enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]+-- >>> list 5 $ enumString "xyz"+-- ["","x","xy","xyz"]+enumString :: String -> Series m Text+enumString cs = generate $ \d -> fmap pack . inits $ take d cs --- | Create a 'Data.Text.Text' 'Series' with a dummy sentence. This can---   be used when you want to print a 'Series' to the screen.+-- | A 'Data.Text.Text' 'Series' that grows with English words. --+--   This is useful when you want to print 'Series'.+-- -- >>> let s = list 20 jack -- >>> take 3 s -- ["","All","All work"]--- >>> s !! 10--- "All work and no play makes Jack a dull boy"+-- >>> last s+-- "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy." jack :: Series m Text jack = generate $ \d ->-    (\n -> pack . unwords . take n . words $ sentence) <$> [0..d]-  where-    sentence = "All work and no play makes Jack a dull boy"+    fmap (pack . unwords) . inits . take d . cycle . words $+        "All work and no play makes Jack a dull boy." --- | Create a 'Data.Text.Text' 'Series' with the first character of each+-- | A 'Data.Text.Text' 'Series' that grows with the first character of each --   <https://en.wikipedia.org/wiki/Plane_(Unicode) Unicode plane>. ----- >>> list 3 nonBmp+-- >>> list 3 enumNonBmp -- ["","\NUL","\NUL\65536","\NUL\65536\131072"] -- -- Notice that this covers the 16 unicode planes. ----- >>> last (list 16 nonBmp) == last (list 17 nonBmp)+-- >>> last (list 16 enumNonBmp) == last (list 17 enumNonBmp) -- True-nonBmp :: Series m Text-nonBmp = enumerated ['\0','\x10000'..'\xF0000']+enumNonBmp :: Series m Text+enumNonBmp = enumString ['\0','\x10000'..'\xF0000']
Test/SmallCheck/Series/Text/Lazy.hs view
@@ -7,93 +7,91 @@ module Test.SmallCheck.Series.Text.Lazy   (   -- * Replication-    aaa-  , zzz-  , replicated+    replicateA+  , replicateNull+  , replicateChar   -- * Enumeration-  , ascii-  , alpha-  , enumerated+  , enumAlphabet+  , enumChars+  , enumString   -- * Printing   , jack   -- * Extra Unicode planes-  , nonBmp+  , enumNonBmp   ) where -import Prelude hiding (replicate)-import Control.Applicative ((<$>))-import Data.Text.Lazy (Text, pack, singleton, replicate)+import Data.List (inits)+import Data.Text.Lazy (Text, pack) import Test.SmallCheck.Series --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra 'a' 'Char'.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by replicating the @a@ 'Char'. ----- >>> list 4 aaa+-- >>> list 4 replicateA -- ["","a","aa","aaa","aaaa"] -- -- Use this when you don't care about the 'Char's inside 'Data.Text.Lazy.Text'.-aaa :: Series m Text-aaa = replicated 'a'+replicateA :: Series m Text+replicateA = replicateChar 'a' --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra @NUL@ 'Char'.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by replicating the @NUL@ 'Char'. ----- >>> list 4 zzz+-- >>> list 4 replicateNull -- ["","\NUL","\NUL\NUL","\NUL\NUL\NUL","\NUL\NUL\NUL\NUL"]-zzz :: Series m Text-zzz = replicated '\0'+replicateNull :: Series m Text+replicateNull = replicateChar '\0' --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with an extra custom 'Char'.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by replicating the given 'Char'. ----- >>> list 4 $ replicated '☃'+-- >>> list 4 $ replicateChar '☃' -- ["","\9731","\9731\9731","\9731\9731\9731","\9731\9731\9731\9731"]-replicated :: Char -> Series m Text-replicated c = generate $ \d -> (`rep` singleton c) <$> [0..d]-  where-    rep = replicate . fromIntegral+replicateChar :: Char -> Series m Text+replicateChar c = generate $ \d -> fmap pack . inits $ replicate d c --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with the alphabet.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by enumerating the latin alphabet. ----- >>> list 4 alpha+-- >>> list 4 enumAlphabet -- ["","a","ab","abc","abcd"]-alpha :: Series m Text-alpha = enumerated ['a'..'z']+enumAlphabet :: Series m Text+enumAlphabet = enumString ['a'..'z'] --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with @ASCII@ 'Char's set.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by enumerating every 'Char'. ----- >>> list 4 ascii+-- >>> list 4 enumChars -- ["","\NUL","\NUL\SOH","\NUL\SOH\STX","\NUL\SOH\STX\ETX"]-ascii :: Series m Text-ascii = enumerated ['\0'..'\255']+enumChars :: Series m Text+enumChars = enumString ['\0'..] --- | Create a 'Data.Text.Lazy.Text' 'Series' growing with the given 'Char' set.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows by enumerating every+--   'Char' in the given 'String'. Notice that the 'String' can be infinite. ----- >>> list 4 $ enumerated "abc"--- ["","a","ab","abc","abc"]-enumerated :: String -> Series m Text-enumerated cs = generate $ \d -> (\n -> pack $ take n cs) <$> [0..d]+-- >>> list 5 $ enumString "xyz"+-- ["","x","xy","xyz"]+enumString :: String -> Series m Text+enumString cs = generate $ \d -> fmap pack . inits $ take d cs --- | Create a 'Data.Text.Lazy.Text' 'Series' with a dummy sentence. This can---   be used when you want to print a 'Series' to the screen.+-- | A 'Data.Text.Lazy.Text' 'Series' that grows with English words. --+--   This is useful when you want to print 'Series'.+-- -- >>> let s = list 20 jack -- >>> take 3 s -- ["","All","All work"]--- >>> s !! 10--- "All work and no play makes Jack a dull boy"+-- >>> last s+-- "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy." jack :: Series m Text jack = generate $ \d ->-    (\n -> pack . unwords . take n . words $ sentence) <$> [0..d]-  where-    sentence = "All work and no play makes Jack a dull boy"+    fmap (pack . unwords) . inits . take d . cycle . words $+        "All work and no play makes Jack a dull boy." --- | Create a 'Data.Text.Lazy.Text' 'Series' with the first character of each+-- | A 'Data.Text.Lazy.Text' 'Series' that grows with the first character of each --   <https://en.wikipedia.org/wiki/Plane_(Unicode) Unicode plane>. ----- >>> list 3 nonBmp+-- >>> list 3 enumNonBmp -- ["","\NUL","\NUL\65536","\NUL\65536\131072"] -- -- Notice that this covers the 16 unicode planes. ----- >>> last (list 16 nonBmp) == last (list 17 nonBmp)+-- >>> last (list 16 enumNonBmp) == last (list 17 enumNonBmp) -- True-nonBmp :: Series m Text-nonBmp = enumerated ['\0','\x10000'..'\xF0000']+enumNonBmp :: Series m Text+enumNonBmp = enumString ['\0','\x10000'..'\xF0000']
smallcheck-series.cabal view
@@ -1,9 +1,9 @@ name:                smallcheck-series-version:             0.1-synopsis:            Extra series for smallcheck+version:             0.2+synopsis:            Extra SmallCheck series description:-  Utilities for creating @SmallCheck@ @Series@ and orphan @Serial@-  instances for frequently used types coming with GHC core libraries.+  Orphan @Serial@ instances and utilities to create custom @Series@ for+  common types. homepage:            https://github.com/jdnavarro/smallcheck-series bug-reports:         https://github.com/jdnavarro/smallcheck-series/issues license:             BSD3