@@ -16,6 +16,7 @@ import Data.IORef ( newIORef, readIORef, writeIORef )
16import Data.Int (Int64)
16import Data.Int (Int64)
17import Data.List (intercalate)
17import Data.List (intercalate)
18import Data.Maybe ( isJust, fromJust )
18import Data.Maybe ( isJust, fromJust )
19+import Foreign.Storable (Storable)
19#if __GLASGOW_HASKELL__ < 808
20#if __GLASGOW_HASKELL__ < 808
20import Data.Semigroup ((<>))
21import Data.Semigroup ((<>))
@@ -23,7 +24,7 @@ import Test.Hspec.QuickCheck
23import Test.QuickCheck
24import Test.QuickCheck
25 , Property
26 , Property
26− , arbitrary
27+ , Arbitrary(..)
28 , elements
29 , elements
@@ -106,55 +107,108 @@ splitOnSuffixSeq = do
107 $ IS.splitOnSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
108 $ IS.splitOnSuffixSeq (A.fromList pat) (FL.toList) (S.fromList xs)
110+seqSplitterProperties ::
111+ forall a. (Arbitrary a, Eq a, Show a, Storable a, Enum a)
115+seqSplitterProperties sep desc = do
116+ describe (desc <> " splitOnSeq/intercalate")
119+ intercalateSplitEqId 0
120+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 0
122+ -- Single element seperator
123+ intercalateSplitEqId 1
124+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 1
127+ intercalateSplitEqId 2
128+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 2
131+ intercalateSplitEqId 4
132+ concatSplitIntercalateEqConcat splitOnSeq_ intercalate 4
135+ splitIntercalateEqId splitOnSeq_ intercalate
140+ S.toList $ IS.splitOnSeq (A.fromList ys) FL.toList (S.fromList xs)
143+ nonSepElem = suchThat arbitrary (/= sep)
145+ listWithSep :: Gen [a]
146+ listWithSep = listOf $ frequency [(3, arbitrary), (1, elements [sep])]
148+ listWithoutSep :: Gen [a]
149+ listWithoutSep = vectorOf 4 nonSepElem
151+ listsWithoutSep :: Gen [[a]]
152+ listsWithoutSep = listOf listWithoutSep
154+ listsWithoutSep1 :: Gen [[a]]
155+ listsWithoutSep1 = listOf1 listWithoutSep
157+ intercalateSplitEqId i =
159+ "intercalate . splitOnSeq == id ("
160+ <> show i <> " element separator)"
162+ $ forAll listWithSep
164+ withMaxSuccess maxTestCount
167+ ys <- splitOnSeq_ xs (replicate i sep)
170+ (intercalate (replicate i sep) ys)
173+ concatSplitIntercalateEqConcat splitter intercalater i =
175+ "concat . splitter . intercalater == "
177+ <> show i <> " element separator/possibly empty list)"
179+ $ forAll listsWithoutSep
181+ withMaxSuccess maxTestCount
184+ let xs = intercalater (replicate i sep) xss
185+ ys <- splitter xs (replicate i sep)
186+ listEquals (==) (concat ys) (concat xss)
188+ splitIntercalateEqId splitter intercalater =
190+ "splitter . intercalater == id"
191+ <> " (exclusive separator/non-empty list)"
193+ $ forAll listsWithoutSep1
195+ withMaxSuccess maxTestCount
198+ let xs = intercalater [sep] xss
199+ ys <- splitter xs [sep]
200+ listEquals (==) ys xss
109groupSplitOps :: String -> Spec
202groupSplitOps :: String -> Spec
110groupSplitOps desc = do
203groupSplitOps desc = do
111 -- splitting
204 -- splitting
112 splitOnSeq
205 splitOnSeq
113 splitOnSuffixSeq
206 splitOnSuffixSeq
114− -- XXX add tests with multichar separators too
116− let split xs ys =
208+ -- seq splitting
117− S.toList $ IS.splitOnSeq (A.fromList ys) FL.toList (S.fromList xs)
209+ seqSplitterProperties (0 :: Int) desc
118− prop (desc <> " intercalate . splitOnSeq == id (nil separator)") $
210+ -- XXX This will fail
119− forAll listWithZeroes $ \xs -> do
211+ -- seqSplitterProperties (0 :: Word8) desc
120− withMaxSuccess maxTestCount $
123− listEquals (==) (intercalate [] ys) xs
125− prop (desc <> " intercalate . splitOnSeq == id (single element separator)") $
126− forAll listWithZeroes $ \xs -> do
127− withMaxSuccess maxTestCount $
130− listEquals (==) (intercalate [0] ys) xs
132− prop (desc <> " concat . splitOnSeq . intercalate == concat "
133− <> "(nil separator/possibly empty list)") $
134− forAll listsWithoutZeroes $ \xss -> do
135− withMaxSuccess maxTestCount $
137− let xs = intercalate [] xss
139− listEquals (==) (concat ys) (concat xss)
141− prop (desc <> " concat . splitOnSeq . intercalate == "
142− <> "concat (non-nil separator/possibly empty list)") $
143− forAll listsWithoutZeroes $ \xss -> do
144− withMaxSuccess maxTestCount $
146− let xs = intercalate [0] xss
148− listEquals (==) (concat ys) (concat xss)
150− prop (desc <> " splitOnSeq . intercalate == id "
151− <> "(exclusive separator/non-empty list)") $
152− forAll listsWithoutZeroes1 $ \xss -> do
153− withMaxSuccess maxTestCount $
155− let xs = intercalate [0] xss
157− listEquals (==) ys xss
159 prop (desc <> " intercalate [x] . splitOn (== x) == id") $
213 prop (desc <> " intercalate [x] . splitOn (== x) == id") $
160 forAll listWithZeroes $ \xs -> do
214 forAll listWithZeroes $ \xs -> do
@@ -168,14 +222,6 @@ groupSplitOps desc = do
168 listWithZeroes :: Gen [Int]
222 listWithZeroes :: Gen [Int]
169 listWithZeroes = listOf $ frequency [(3, arbitrary), (1, elements [0])]
223 listWithZeroes = listOf $ frequency [(3, arbitrary), (1, elements [0])]
171− listWithoutZeroes = vectorOf 4 $ suchThat arbitrary (/= 0)
173− listsWithoutZeroes :: Gen [[Int]]
174− listsWithoutZeroes = listOf listWithoutZeroes
176− listsWithoutZeroes1 :: Gen [[Int]]
177− listsWithoutZeroes1 = listOf1 listWithoutZeroes
180-- After grouping (and folding) Int stream using @>@ operation,
226-- After grouping (and folding) Int stream using @>@ operation,
181-- the first @Int@ of every @[Int]@ in the @[Int]@ stream should be the minimum.
227-- the first @Int@ of every @[Int]@ in the @[Int]@ stream should be the minimum.