on master help sign in
Abstract out the splitOnSeq property tests
commitaaae284415ee68bac3a91a4b95eddc15d8360e42 authoradithyaov <adithya@composewell.com> dateWed 4 Nov 2020, 03:59 (6 years ago) parent6c27236
1 file changed+98−52
test/Streamly/Test/Prelude/Serial.hs+98−52
test/Streamly/Test/Prelude/Serial.hs+98−52
@@ -16,6 +16,7 @@ import Data.IORef ( newIORef, readIORef, writeIORef )
1616import Data.Int (Int64)
1717import Data.List (intercalate)
1818import Data.Maybe ( isJust, fromJust )
19+import Foreign.Storable (Storable)
1920#if __GLASGOW_HASKELL__ < 808
2021import Data.Semigroup ((<>))
2122#endif
@@ -23,7 +24,7 @@ import Test.Hspec.QuickCheck
2324import Test.QuickCheck
2425 ( Gen
2526 , Property
26− , arbitrary
27+ , Arbitrary(..)
2728 , choose
2829 , elements
2930 , forAll
@@ -106,55 +107,108 @@ splitOnSuffixSeq = do
106107 S.toList
107108 $ IS.splitOnSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
108109
110+seqSplitterProperties ::
111+ forall a. (Arbitrary a, Eq a, Show a, Storable a, Enum a)
112+ => a
113+ -> String
114+ -> Spec
115+seqSplitterProperties sep desc = do
116+ describe (desc <> " splitOnSeq/intercalate")
117+ $ do
118+ -- Empty seperator
119+ intercalateSplitEqId 0
120+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 0
121+
122+ -- Single element seperator
123+ intercalateSplitEqId 1
124+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 1
125+
126+ -- Shift Or
127+ intercalateSplitEqId 2
128+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 2
129+
130+ -- Karp-Rabin
131+ intercalateSplitEqId 4
132+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 4
133+
134+ -- Exclusive case
135+ splitIntercalateEqId splitOnSeq_ intercalate
136+
137+ where
138+
139+ splitOnSeq_ xs ys =
140+ S.toList $ IS.splitOnSeq (A.fromList ys) FL.toList (S.fromList xs)
141+
142+ nonSepElem :: Gen a
143+ nonSepElem = suchThat arbitrary (/= sep)
144+
145+ listWithSep :: Gen [a]
146+ listWithSep = listOf $ frequency [(3, arbitrary), (1, elements [sep])]
147+
148+ listWithoutSep :: Gen [a]
149+ listWithoutSep = vectorOf 4 nonSepElem
150+
151+ listsWithoutSep :: Gen [[a]]
152+ listsWithoutSep = listOf listWithoutSep
153+
154+ listsWithoutSep1 :: Gen [[a]]
155+ listsWithoutSep1 = listOf1 listWithoutSep
156+
157+ intercalateSplitEqId i =
158+ let name =
159+ "intercalate . splitOnSeq == id ("
160+ <> show i <> " element separator)"
161+ in prop name
162+ $ forAll listWithSep
163+ $ \xs -> do
164+ withMaxSuccess maxTestCount
165+ $ monadicIO
166+ $ do
167+ ys <- splitOnSeq_ xs (replicate i sep)
168+ listEquals
169+ (==)
170+ (intercalate (replicate i sep) ys)
171+ xs
172+
173+ concatSplitIntercalateEqConcat splitter intercalater i =
174+ let name =
175+ "concat . splitter . intercalater == "
176+ <> "concat ("
177+ <> show i <> " element separator/possibly empty list)"
178+ in prop name
179+ $ forAll listsWithoutSep
180+ $ \xss -> do
181+ withMaxSuccess maxTestCount
182+ $ monadicIO
183+ $ do
184+ let xs = intercalater (replicate i sep) xss
185+ ys <- splitter xs (replicate i sep)
186+ listEquals (==) (concat ys) (concat xss)
187+
188+ splitIntercalateEqId splitter intercalater =
189+ let name =
190+ "splitter . intercalater == id"
191+ <> " (exclusive separator/non-empty list)"
192+ in prop name
193+ $ forAll listsWithoutSep1
194+ $ \xss -> do
195+ withMaxSuccess maxTestCount
196+ $ monadicIO
197+ $ do
198+ let xs = intercalater [sep] xss
199+ ys <- splitter xs [sep]
200+ listEquals (==) ys xss
201+
109202groupSplitOps :: String -> Spec
110203groupSplitOps desc = do
111204 -- splitting
112205 splitOnSeq
113206 splitOnSuffixSeq
114− -- XXX add tests with multichar separators too
115207
116− let split xs ys =
117− S.toList $ IS.splitOnSeq (A.fromList ys) FL.toList (S.fromList xs)
118− prop (desc <> " intercalate . splitOnSeq == id (nil separator)") $
119− forAll listWithZeroes $ \xs -> do
120− withMaxSuccess maxTestCount $
121− monadicIO $ do
122− ys <- split xs []
123− listEquals (==) (intercalate [] ys) xs
124−
125− prop (desc <> " intercalate . splitOnSeq == id (single element separator)") $
126− forAll listWithZeroes $ \xs -> do
127− withMaxSuccess maxTestCount $
128− monadicIO $ do
129− ys <- split xs [0]
130− listEquals (==) (intercalate [0] ys) xs
131−
132− prop (desc <> " concat . splitOnSeq . intercalate == concat "
133− <> "(nil separator/possibly empty list)") $
134− forAll listsWithoutZeroes $ \xss -> do
135− withMaxSuccess maxTestCount $
136− monadicIO $ do
137− let xs = intercalate [] xss
138− ys <- split xs [0]
139− listEquals (==) (concat ys) (concat xss)
140−
141− prop (desc <> " concat . splitOnSeq . intercalate == "
142− <> "concat (non-nil separator/possibly empty list)") $
143− forAll listsWithoutZeroes $ \xss -> do
144− withMaxSuccess maxTestCount $
145− monadicIO $ do
146− let xs = intercalate [0] xss
147− ys <- split xs [0]
148− listEquals (==) (concat ys) (concat xss)
149−
150− prop (desc <> " splitOnSeq . intercalate == id "
151− <> "(exclusive separator/non-empty list)") $
152− forAll listsWithoutZeroes1 $ \xss -> do
153− withMaxSuccess maxTestCount $
154− monadicIO $ do
155− let xs = intercalate [0] xss
156− ys <- split xs [0]
157− listEquals (==) ys xss
208+ -- seq splitting
209+ seqSplitterProperties (0 :: Int) desc
210+ -- XXX This will fail
211+ -- seqSplitterProperties (0 :: Word8) desc
158212
159213 prop (desc <> " intercalate [x] . splitOn (== x) == id") $
160214 forAll listWithZeroes $ \xs -> do
@@ -168,14 +222,6 @@ groupSplitOps desc = do
168222 listWithZeroes :: Gen [Int]
169223 listWithZeroes = listOf $ frequency [(3, arbitrary), (1, elements [0])]
170224
171− listWithoutZeroes = vectorOf 4 $ suchThat arbitrary (/= 0)
172−
173− listsWithoutZeroes :: Gen [[Int]]
174− listsWithoutZeroes = listOf listWithoutZeroes
175−
176− listsWithoutZeroes1 :: Gen [[Int]]
177− listsWithoutZeroes1 = listOf1 listWithoutZeroes
178−
179225-- |
180226-- After grouping (and folding) Int stream using @>@ operation,
181227-- the first @Int@ of every @[Int]@ in the @[Int]@ stream should be the minimum.