1{-# LANGUAGE BangPatterns, FlexibleInstances, ScopedTypeVariables,
2 TypeSynonymInstances #-}
3{-# OPTIONS_GHC -fno-enable-rewrite-rules #-}
6import Text.Show.Functions ()
8import qualified Data.Bits as Bits (shiftL, shiftR)
9import Data.Char (chr, isLower, isSpace, isUpper, ord)
10import Data.Monoid (Monoid(..))
11import Data.String (fromString)
12import Debug.Trace (trace)
13import Control.Arrow ((***), second)
14import Data.Word (Word8, Word16, Word32)
15import qualified Data.Text as T
16import qualified Data.Text.Lazy as TL
17import qualified Data.Text.Encoding as E
18import Control.Exception (SomeException, try)
19import qualified Data.Text.Fusion as S
20import qualified Data.Text.Fusion.Common as S
21import qualified Data.Text.Lazy.Encoding as EL
22import qualified Data.Text.Lazy.Fusion as SL
23import qualified Data.Text.UnsafeShift as U
24import qualified Data.List as L
25import Prelude hiding (replicate)
26import System.IO.Unsafe (unsafePerformIO)
27import Test.Framework (defaultMain, testGroup)
28import Test.Framework.Providers.QuickCheck (testProperty)
30import QuickCheckUtils (NotEmpty(..))
32-- Ensure that two potentially bottom values (in the sense of crashing
33-- for some inputs, not looping infinitely) either both crash, or both
34-- give comparable results for some input.
35(=^=) :: (Eq a, Show a) => a -> a -> Bool
37i =^= j = unsafePerformIO $ do
38 x <- try (return $! i)
39 y <- try (return $! j)
41 (Left (_ :: SomeException), Left (_ :: SomeException))
43 (Right a, Right b) -> return (a == b)
44 e -> trace ("*** Divergence: " ++ show e) return False
47t_pack_unpack = (T.unpack . T.pack) `eq` id
48tl_pack_unpack = (TL.unpack . TL.pack) `eq` id
49t_stream_unstream = (S.unstream . S.stream) `eq` id
50tl_stream_unstream = (SL.unstream . SL.stream) `eq` id
51t_reverse_stream t = (S.reverse . S.reverseStream) t == t
52t_singleton c = [c] == (T.unpack . T.singleton) c
53tl_singleton c = [c] == (TL.unpack . TL.singleton) c
54tl_unstreamChunks x = f 11 x == f 1000 x
55 where f n = SL.unstreamChunks n . S.streamList
56tl_chunk_unchunk = (TL.fromChunks . TL.toChunks) `eq` id
58t_ascii t = E.decodeASCII (E.encodeUtf8 a) == a
59 where a = T.map (\c -> chr (ord c `mod` 128)) t
60t_utf8 = (E.decodeUtf8 . E.encodeUtf8) `eq` id
61tl_utf8 = (EL.decodeUtf8 . EL.encodeUtf8) `eq` id
62t_utf16LE = (E.decodeUtf16LE . E.encodeUtf16LE) `eq` id
63t_utf16BE = (E.decodeUtf16BE . E.encodeUtf16BE) `eq` id
64t_utf32LE = (E.decodeUtf32LE . E.encodeUtf32LE) `eq` id
65t_utf32BE = (E.decodeUtf32BE . E.encodeUtf32BE) `eq` id
69 unpackS :: s -> String
70 splitAtS :: Int -> s -> (s,s)
71 packSChunkSize :: Int -> String -> s
72 packSChunkSize _ = packS
74instance Stringy String where
79instance Stringy (S.Stream Char) where
81 unpackS = S.unstreamList
82 splitAtS n s = (S.take n s, S.drop n s)
84instance Stringy T.Text where
89instance Stringy TL.Text where
90 packSChunkSize k = SL.unstreamChunks k . S.streamList
93 splitAtS = TL.splitAt . fromIntegral
95-- Do two functions give the same answer?
96eq :: (Eq a, Show a) => (t -> a) -> (t -> a) -> t -> Bool
99-- What about with the RHS packed?
100eqP :: (Eq a, Show a, Stringy s) =>
101 (String -> a) -> (s -> a) -> String -> Word8 -> Bool
102eqP f g s w = eql "orig" (f s) (g t) &&
103 eql "mini" (f s) (g mini) &&
104 eql "head" (f sa) (g ta) &&
105 eql "tail" (f sb) (g tb)
107 mini = packSChunkSize 10 s
108 (sa,sb) = splitAt m s
109 (ta,tb) = splitAtS m t
112 | otherwise = n `mod` l
114 eql d a b | a =^= b = True
115 | otherwise = trace (d ++ ": " ++ show a ++ " /= " ++ show b) False
117-- For tests that have O(n^2) running times or input sizes, resize
118-- their inputs to the square root of the originals.
119unsquare :: (Arbitrary a, Show a, Testable b) => (a -> b) -> Property
120unsquare = forAll . sized $ \n -> resize (smaller n) arbitrary
121 where smaller = round . (sqrt :: Double -> Double) . fromIntegral
123s_Eq s = (s==) `eq` ((S.streamList s==) . S.streamList)
124 where _types = s :: String
126 ((L.filter p s==) . L.filter p) `eq`
127 (((S.filter p $ S.streamList s)==) . S.filter p . S.streamList)
128t_Eq s = (s==) `eq` ((T.pack s==) . T.pack)
129tl_Eq s = (s==) `eq` ((TL.pack s==) . TL.pack)
130s_Ord s = (compare s) `eq` (compare (S.streamList s) . S.streamList)
131 where _types = s :: String
133 ((compare $ L.filter p s) . L.filter p) `eq`
134 (compare (S.filter p $ S.streamList s) . S.filter p . S.streamList)
135t_Ord s = (compare s) `eq` (compare (T.pack s) . T.pack)
136tl_Ord s = (compare s) `eq` (compare (TL.pack s) . TL.pack)
137t_Read = id `eq` (T.unpack . read . show)
138tl_Read = id `eq` (TL.unpack . read . show)
139t_Show = show `eq` (show . T.pack)
140tl_Show = show `eq` (show . TL.pack)
141t_mappend s = mappend s`eqP` (unpackS . mappend (T.pack s))
142tl_mappend s = mappend s`eqP` (unpackS . mappend (TL.pack s))
143t_mconcat = unsquare (mconcat `eq` (unpackS . mconcat . L.map T.pack))
144tl_mconcat = unsquare (mconcat `eq` (unpackS . mconcat . L.map TL.pack))
145t_IsString = fromString `eqP` (T.unpack . fromString)
146tl_IsString = fromString `eqP` (TL.unpack . fromString)
148s_cons x = (x:) `eqP` (unpackS . S.cons x)
149sf_cons p x = ((x:) . L.filter p) `eqP` (unpackS . S.cons x . S.filter p)
150t_cons x = (x:) `eqP` (unpackS . T.cons x)
151tl_cons x = (x:) `eqP` (unpackS . TL.cons x)
152s_snoc x = (++ [x]) `eqP` (unpackS . (flip S.snoc) x)
153t_snoc x = (++ [x]) `eqP` (unpackS . (flip T.snoc) x)
154tl_snoc x = (++ [x]) `eqP` (unpackS . (flip TL.snoc) x)
155s_append s = (s++) `eqP` (unpackS . S.append (S.streamList s))
156sf_append p s = (L.filter p s++) `eqP` (unpackS . S.append (S.filter p $ S.streamList s))
157t_append s = (s++) `eqP` (unpackS . T.append (packS s))
159uncons (x:xs) = Just (x,xs)
162s_uncons = uncons `eqP` (fmap (second unpackS) . S.uncons)
163sf_uncons p = (uncons . L.filter p) `eqP` (fmap (second unpackS) . S.uncons . S.filter p)
164t_uncons = uncons `eqP` (fmap (second unpackS) . T.uncons)
165tl_uncons = uncons `eqP` (fmap (second unpackS) . TL.uncons)
166s_head = head `eqP` S.head
167sf_head p = (head . L.filter p) `eqP` (S.head . S.filter p)
168t_head = head `eqP` T.head
169tl_head = head `eqP` TL.head
170s_last = last `eqP` S.last
171sf_last p = (last . L.filter p) `eqP` (S.last . S.filter p)
172t_last = last `eqP` T.last
173tl_last = last `eqP` TL.last
174s_tail = tail `eqP` (unpackS . S.tail)
175sf_tail p = (tail . L.filter p) `eqP` (unpackS . S.tail . S.filter p)
176t_tail = tail `eqP` (unpackS . T.tail)
177tl_tail = tail `eqP` (unpackS . TL.tail)
178s_init = init `eqP` (unpackS . S.init)
179sf_init p = (init . L.filter p) `eqP` (unpackS . S.init . S.filter p)
180t_init = init `eqP` (unpackS . T.init)
181tl_init = init `eqP` (unpackS . TL.init)
182s_null = null `eqP` S.null
183sf_null p = (null . L.filter p) `eqP` (S.null . S.filter p)
184t_null = null `eqP` T.null
185tl_null = null `eqP` TL.null
186s_length = length `eqP` S.length
187sf_length p = (length . L.filter p) `eqP` (S.length . S.filter p)
188t_length = length `eqP` T.length
189tl_length = length `eqP` (fromIntegral . TL.length)
191s_map f = map f `eqP` (unpackS . S.map f)
192sf_map p f = (map f . L.filter p) `eqP` (unpackS . S.map f . S.filter p)
193t_map f = map f `eqP` (unpackS . T.map f)
194tl_map f = map f `eqP` (unpackS . TL.map f)
195t_intercalate c = unsquare (L.intercalate c `eq` (unpackS . T.intercalate (packS c) . map packS))
196tl_intercalate c = unsquare (L.intercalate c `eq` (unpackS . TL.intercalate (TL.pack c) . map TL.pack))
197s_intersperse c = L.intersperse c `eqP` (unpackS . S.intersperse c)
198sf_intersperse p c= (L.intersperse c . L.filter p) `eqP` (unpackS . S.intersperse c . S.filter p)
199t_intersperse c = L.intersperse c `eqP` (unpackS . T.intersperse c)
200tl_intersperse c = L.intersperse c `eqP` (unpackS . TL.intersperse c)
201t_transpose = unsquare (L.transpose `eq` (map unpackS . T.transpose . map packS))
202tl_transpose = unsquare (L.transpose `eq` (map unpackS . TL.transpose . map TL.pack))
203t_reverse = L.reverse `eqP` (unpackS . T.reverse)
204tl_reverse = L.reverse `eqP` (unpackS . TL.reverse)
205t_reverse_short n = L.reverse `eqP` (unpackS . S.reverse . shorten n . S.stream)
207t_replace s d = (L.intercalate d . split s) `eqP` (unpackS . T.replace (T.pack s) (T.pack d))
208tl_replace s d = (L.intercalate d . split s) `eqP` (unpackS . TL.replace (TL.pack s) (TL.pack d))
210split :: (Eq a) => [a] -> [a] -> [[a]]
212 | l == 0 = error "empty"
213 | otherwise = go src0
216 go src = search 0 src
220 | pat `L.isPrefixOf` s = take n src : go (drop l s)
221 | otherwise = search (n+1) s'
223s_toCaseFold_length xs = S.length (S.toCaseFold s) >= length xs
224 where s = S.streamList xs
225sf_toCaseFold_length p xs =
226 (S.length . S.toCaseFold . S.filter p $ s) >= (length . L.filter p $ xs)
227 where s = S.streamList xs
228t_toCaseFold_length t = T.length (T.toCaseFold t) >= T.length t
229tl_toCaseFold_length t = TL.length (TL.toCaseFold t) >= TL.length t
230t_toLower_length t = T.length (T.toLower t) >= T.length t
231t_toLower_lower t = p (T.toLower t) >= p t
232 where p = T.length . T.filter isLower
233tl_toLower_lower t = p (TL.toLower t) >= p t
234 where p = TL.length . TL.filter isLower
235t_toUpper_length t = T.length (T.toUpper t) >= T.length t
236t_toUpper_upper t = p (T.toUpper t) >= p t
237 where p = T.length . T.filter isUpper
238tl_toUpper_upper t = p (TL.toUpper t) >= p t
239 where p = TL.length . TL.filter isUpper
241justifyLeft k c s = s ++ L.replicate (k - length s) c
242justifyRight m n s = L.replicate (m - length s) n ++ s
244s_justifyLeft k c = justifyLeft k c `eqP` (unpackS . S.justifyLeftI k c)
245sf_justifyLeft p k c =
246 (justifyLeft k c . L.filter p) `eqP` (unpackS . S.justifyLeftI k c . S.filter p)
247t_justifyLeft k c = justifyLeft k c `eqP` (unpackS . T.justifyLeft k c)
248tl_justifyLeft k c = justifyLeft k c `eqP` (unpackS . TL.justifyLeft (fromIntegral k) c)
249t_justifyRight k c = justifyRight k c `eqP` (unpackS . T.justifyRight k c)
250tl_justifyRight k c = justifyRight k c `eqP` (unpackS . TL.justifyRight (fromIntegral k) c)
252sf_foldl p f z = (L.foldl f z . L.filter p) `eqP` (S.foldl f z . S.filter p)
253 where _types = f :: Char -> Char -> Char
254t_foldl f z = L.foldl f z `eqP` (T.foldl f z)
255 where _types = f :: Char -> Char -> Char
256tl_foldl f z = L.foldl f z `eqP` (TL.foldl f z)
257 where _types = f :: Char -> Char -> Char
258sf_foldl' p f z = (L.foldl' f z . L.filter p) `eqP` (S.foldl' f z . S.filter p)
259 where _types = f :: Char -> Char -> Char
260t_foldl' f z = L.foldl' f z `eqP` T.foldl' f z
261 where _types = f :: Char -> Char -> Char
262tl_foldl' f z = L.foldl' f z `eqP` TL.foldl' f z
263 where _types = f :: Char -> Char -> Char
264sf_foldl1 p f = (L.foldl1 f . L.filter p) `eqP` (S.foldl1 f . S.filter p)
265t_foldl1 f = L.foldl1 f `eqP` T.foldl1 f
266tl_foldl1 f = L.foldl1 f `eqP` TL.foldl1 f
267sf_foldl1' p f = (L.foldl1' f . L.filter p) `eqP` (S.foldl1' f . S.filter p)
268t_foldl1' f = L.foldl1' f `eqP` T.foldl1' f
269tl_foldl1' f = L.foldl1' f `eqP` TL.foldl1' f
270sf_foldr p f z = (L.foldr f z . L.filter p) `eqP` (S.foldr f z . S.filter p)
271 where _types = f :: Char -> Char -> Char
272t_foldr f z = L.foldr f z `eqP` T.foldr f z
273 where _types = f :: Char -> Char -> Char
274tl_foldr f z = L.foldr f z `eqP` TL.foldr f z
275 where _types = f :: Char -> Char -> Char
276sf_foldr1 p f = (L.foldr1 f . L.filter p) `eqP` (S.foldr1 f . S.filter p)
277t_foldr1 f = L.foldr1 f `eqP` T.foldr1 f
278tl_foldr1 f = L.foldr1 f `eqP` TL.foldr1 f
280sf_concat p = unsquare ((L.concat . map (L.filter p)) `eq` (unpackS . S.concat . map (S.filter p . packS)))
281t_concat = unsquare (L.concat `eq` (unpackS . T.concat . map packS))
282tl_concat = unsquare (L.concat `eq` (unpackS . TL.concat . map TL.pack))
283sf_concatMap p f = unsquare ((L.concatMap f . L.filter p) `eqP` (unpackS . S.concatMap (packS . f) . S.filter p))
284t_concatMap f = unsquare (L.concatMap f `eqP` (unpackS . T.concatMap (packS . f)))
285tl_concatMap f = unsquare (L.concatMap f `eqP` (unpackS . TL.concatMap (TL.pack . f)))
286sf_any q p = (L.any p . L.filter q) `eqP` (S.any p . S.filter q)
287t_any p = L.any p `eqP` T.any p
288tl_any p = L.any p `eqP` TL.any p
289sf_all q p = (L.all p . L.filter q) `eqP` (S.all p . S.filter q)
290t_all p = L.all p `eqP` T.all p
291tl_all p = L.all p `eqP` TL.all p
292sf_maximum p = (L.maximum . L.filter p) `eqP` (S.maximum . S.filter p)
293t_maximum = L.maximum `eqP` T.maximum
294tl_maximum = L.maximum `eqP` TL.maximum
295sf_minimum p = (L.minimum . L.filter p) `eqP` (S.minimum . S.filter p)
296t_minimum = L.minimum `eqP` T.minimum
297tl_minimum = L.minimum `eqP` TL.minimum
299sf_scanl p f z = (L.scanl f z . L.filter p) `eqP` (unpackS . S.scanl f z . S.filter p)
300t_scanl f z = L.scanl f z `eqP` (unpackS . T.scanl f z)
301tl_scanl f z = L.scanl f z `eqP` (unpackS . TL.scanl f z)
302t_scanl1 f = L.scanl1 f `eqP` (unpackS . T.scanl1 f)
303tl_scanl1 f = L.scanl1 f `eqP` (unpackS . TL.scanl1 f)
304t_scanr f z = L.scanr f z `eqP` (unpackS . T.scanr f z)
305tl_scanr f z = L.scanr f z `eqP` (unpackS . TL.scanr f z)
306t_scanr1 f = L.scanr1 f `eqP` (unpackS . T.scanr1 f)
307tl_scanr1 f = L.scanr1 f `eqP` (unpackS . TL.scanr1 f)
309t_mapAccumL f z = unsquare (L.mapAccumL f z `eqP` (second unpackS . T.mapAccumL f z))
310 where _types = f :: Int -> Char -> (Int,Char)
311tl_mapAccumL f z = unsquare (L.mapAccumL f z `eqP` (second unpackS . TL.mapAccumL f z))
312 where _types = f :: Int -> Char -> (Int,Char)
313t_mapAccumR f z = unsquare (L.mapAccumR f z `eqP` (second unpackS . T.mapAccumR f z))
314 where _types = f :: Int -> Char -> (Int,Char)
315tl_mapAccumR f z = unsquare (L.mapAccumR f z `eqP` (second unpackS . TL.mapAccumR f z))
316 where _types = f :: Int -> Char -> (Int,Char)
318replicate n l = concat (L.replicate n l)
320t_replicate n = replicate n `eq` (unpackS . T.replicate n . packS)
321tl_replicate n = replicate n `eq` (unpackS . TL.replicate (fromIntegral n) . packS)
322t_replicateChar n = L.replicate n `eq` (unpackS . T.replicateChar n)
323tl_replicateChar n= L.replicate n `eq` (unpackS . TL.replicateChar (fromIntegral n))
325unf :: Int -> Char -> Maybe (Char, Char)
326unf n c | fromEnum c * 100 > n = Nothing
327 | otherwise = Just (c, succ c)
329t_unfoldr n = L.unfoldr (unf n) `eq` (unpackS . T.unfoldr (unf n))
330tl_unfoldr n = L.unfoldr (unf n) `eq` (unpackS . TL.unfoldr (unf n))
331t_unfoldrN n m = (L.take n . L.unfoldr (unf m)) `eq`
332 (unpackS . T.unfoldrN n (unf m))
333tl_unfoldrN n m = (L.take n . L.unfoldr (unf m)) `eq`
334 (unpackS . TL.unfoldrN (fromIntegral n) (unf m))
336unpack2 :: (Stringy s) => (s,s) -> (String,String)
337unpack2 = unpackS *** unpackS
339s_take n = L.take n `eqP` (unpackS . S.take n)
340sf_take p n = (L.take n . L.filter p) `eqP` (unpackS . S.take n . S.filter p)
341t_take n = L.take n `eqP` (unpackS . T.take n)
342tl_take n = L.take n `eqP` (unpackS . TL.take (fromIntegral n))
343s_drop n = L.drop n `eqP` (unpackS . S.drop n)
344sf_drop p n = (L.drop n . L.filter p) `eqP` (unpackS . S.drop n . S.filter p)
345t_drop n = L.drop n `eqP` (unpackS . T.drop n)
346tl_drop n = L.drop n `eqP` (unpackS . TL.drop (fromIntegral n))
347s_takeWhile p = L.takeWhile p `eqP` (unpackS . S.takeWhile p)
348sf_takeWhile q p = (L.takeWhile p . L.filter q) `eqP` (unpackS . S.takeWhile p . S.filter q)
349t_takeWhile p = L.takeWhile p `eqP` (unpackS . T.takeWhile p)
350tl_takeWhile p = L.takeWhile p `eqP` (unpackS . TL.takeWhile p)
351s_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
352sf_dropWhile q p = (L.dropWhile p . L.filter q) `eqP` (unpackS . S.dropWhile p . S.filter q)
353t_dropWhile p = L.dropWhile p `eqP` (unpackS . T.dropWhile p)
354tl_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
355t_dropWhileEnd p = (L.reverse . L.dropWhile p . L.reverse) `eqP` (unpackS . T.dropWhileEnd p)
356tl_dropWhileEnd p = (L.reverse . L.dropWhile p . L.reverse) `eqP` (unpackS . TL.dropWhileEnd p)
357t_dropAround p = (L.dropWhile p . L.reverse . L.dropWhile p . L.reverse) `eqP` (unpackS . T.dropAround p)
358tl_dropAround p = (L.dropWhile p . L.reverse . L.dropWhile p . L.reverse) `eqP` (unpackS . TL.dropAround p)
359t_stripStart = T.dropWhile isSpace `eq` T.stripStart
360tl_stripStart = TL.dropWhile isSpace `eq` TL.stripStart
361t_stripEnd = T.dropWhileEnd isSpace `eq` T.stripEnd
362tl_stripEnd = TL.dropWhileEnd isSpace `eq` TL.stripEnd
363t_strip = T.dropAround isSpace `eq` T.strip
364tl_strip = TL.dropAround isSpace `eq` TL.strip
365t_splitAt n = L.splitAt n `eqP` (unpack2 . T.splitAt n)
366tl_splitAt n = L.splitAt n `eqP` (unpack2 . TL.splitAt (fromIntegral n))
367t_span p = L.span p `eqP` (unpack2 . T.span p)
368tl_span p = L.span p `eqP` (unpack2 . TL.span p)
369t_break p = L.break p `eqP` (unpack2 . T.break p)
370tl_break p = L.break p `eqP` (unpack2 . TL.break p)
371t_group = L.group `eqP` (map unpackS . T.group)
372tl_group = L.group `eqP` (map unpackS . TL.group)
373t_groupBy p = L.groupBy p `eqP` (map unpackS . T.groupBy p)
374tl_groupBy p = L.groupBy p `eqP` (map unpackS . TL.groupBy p)
375t_inits = L.inits `eqP` (map unpackS . T.inits)
376tl_inits = L.inits `eqP` (map unpackS . TL.inits)
377t_tails = L.tails `eqP` (map unpackS . T.tails)
378tl_tails = L.tails `eqP` (map unpackS . TL.tails)
380t_split_i (NotEmpty t) = id `eq` (T.intercalate t . T.split t)
381tl_split_i (NotEmpty t) = id `eq` (TL.intercalate t . TL.split t)
382t_splitTimes_i k (NotEmpty t) = id `eq` (T.intercalate t . T.splitTimes k t)
383tl_splitTimes_i k (NotEmpty t) = id `eq` (TL.intercalate t . TL.splitTimes k t)
384t_splitTimes_split k (NotEmpty t) =
385 T.splitTimes k t `eq` \u ->
386 case L.splitAt k (T.split t u) of
388 (a,b) -> a ++ [T.intercalate t b]
389tl_splitTimes_split k (NotEmpty t) =
390 TL.splitTimes k t `eq` \u ->
391 case L.splitAt (fromIntegral k) (TL.split t u) of
393 (a,b) -> a ++ [TL.intercalate t b]
394t_splitTimesEnd_i k (NotEmpty t) = id `eq` (T.intercalate t . T.splitTimesEnd k t)
395tl_splitTimesEnd_i k (NotEmpty t) = id `eq` (TL.intercalate t . TL.splitTimesEnd k t)
396t_splitTimesEnd_split (NotEmpty t) = T.splitTimesEnd maxBound t `eq` T.split t
397tl_splitTimesEnd_split (NotEmpty t) = TL.splitTimesEnd maxBound t `eq` TL.split t
399t_splitWith p = splitWith p `eqP` (map unpackS . T.splitWith p)
400t_splitWith_count c = (L.length . T.splitWith (==c)) `eq` ((1+) . T.count (T.singleton c))
401t_splitWith_split c = T.splitWith (==c) `eq` T.split (T.singleton c)
402tl_splitWith p = splitWith p `eqP` (map unpackS . TL.splitWith p)
404splitWith :: (a -> Bool) -> [a] -> [[a]]
406splitWith p xs = loop xs
407 where loop s | null s' = [l]
408 | otherwise = l : loop (tail s')
409 where (l, s') = break p s
411t_chunksOf_same_lengths k = all ((==k) . T.length) . ini . T.chunksOf k
415t_chunksOf_length k t = len == T.length t || (k <= 0 && len == 0)
416 where len = L.sum . L.map T.length $ T.chunksOf k t
418tl_chunksOf k = T.chunksOf k `eq` (map (T.concat . TL.toChunks) . TL.chunksOf (fromIntegral k) . TL.fromChunks . (:[]))
420t_lines = L.lines `eqP` (map unpackS . T.lines)
421tl_lines = L.lines `eqP` (map unpackS . TL.lines)
423t_lines' = lines' `eqP` (map unpackS . T.lines')
425 lines' s = let (l, s') = break eol s
428 ('\r':'\n':s'') -> lines' s''
429 (_:s'') -> lines' s''
430 eol c = c == '\r' || c == '\n'
432t_words = L.words `eqP` (map unpackS . T.words)
434tl_words = L.words `eqP` (map unpackS . TL.words)
435t_unlines = unsquare (L.unlines `eq` (unpackS . T.unlines . map packS))
436tl_unlines = unsquare (L.unlines `eq` (unpackS . TL.unlines . map packS))
437t_unwords = unsquare (L.unwords `eq` (unpackS . T.unwords . map packS))
438tl_unwords = unsquare (L.unwords `eq` (unpackS . TL.unwords . map packS))
440s_isPrefixOf s = L.isPrefixOf s `eqP` (S.isPrefixOf (S.stream $ packS s) . S.stream)
441sf_isPrefixOf p s = (L.isPrefixOf s . L.filter p) `eqP` (S.isPrefixOf (S.stream $ packS s) . S.filter p . S.stream)
442t_isPrefixOf s = L.isPrefixOf s`eqP` T.isPrefixOf (packS s)
443tl_isPrefixOf s = L.isPrefixOf s`eqP` TL.isPrefixOf (packS s)
444t_isSuffixOf s = L.isSuffixOf s`eqP` T.isSuffixOf (packS s)
445tl_isSuffixOf s = L.isSuffixOf s`eqP` TL.isSuffixOf (packS s)
446t_isInfixOf s = L.isInfixOf s `eqP` T.isInfixOf (packS s)
447tl_isInfixOf s = L.isInfixOf s `eqP` TL.isInfixOf (packS s)
449sf_elem p c = (L.elem c . L.filter p) `eqP` (S.elem c . S.filter p)
450t_elem c = L.elem c `eqP` T.elem c
451tl_elem c = L.elem c `eqP` TL.elem c
452sf_filter q p = (L.filter p . L.filter q) `eqP` (unpackS . S.filter p . S.filter q)
453t_filter p = L.filter p `eqP` (unpackS . T.filter p)
454tl_filter p = L.filter p `eqP` (unpackS . TL.filter p)
455sf_find q p = (L.find p . L.filter q) `eqP` (S.find p . S.filter q)
456t_find p = L.find p `eqP` T.find p
457tl_find p = L.find p `eqP` TL.find p
458t_partition p = L.partition p `eqP` (unpack2 . T.partition p)
459tl_partition p = L.partition p `eqP` (unpack2 . TL.partition p)
461sf_index p s = forAll (choose (-l,l*2)) ((L.filter p s L.!!) `eq` S.index (S.filter p $ packS s))
463t_index s = forAll (choose (-l,l*2)) ((s L.!!) `eq` T.index (packS s))
466tl_index s = forAll (choose (-l,l*2)) ((s L.!!) `eq` (TL.index (packS s) . fromIntegral))
469sf_findIndex q p = (L.findIndex p . L.filter q) `eqP` (S.findIndex p . S.filter q)
470t_findIndex p = L.findIndex p `eqP` T.findIndex p
471tl_findIndex p = (fmap fromIntegral . L.findIndex p) `eqP` TL.findIndex p
472sf_findIndices q p= (L.findIndices p . L.filter q) `eqP` (S.findIndices p . S.filter q)
473t_findIndices p = L.findIndices p `eqP` T.findIndices p
474tl_findIndices p = (fmap fromIntegral . L.findIndices p) `eqP` TL.findIndices p
475sf_elemIndex p c = (L.elemIndex c . L.filter p) `eqP` (S.elemIndex c . S.filter p)
476t_elemIndex c = L.elemIndex c `eqP` T.elemIndex c
477tl_elemIndex c = (fmap fromIntegral . L.elemIndex c) `eqP` TL.elemIndex c
478sf_elemIndices p c= (L.elemIndices c . L.filter p) `eqP` (S.elemIndices c . S.filter p)
479t_elemIndices c = L.elemIndices c`eqP` T.elemIndices c
480tl_elemIndices c = (fmap fromIntegral . L.elemIndices c) `eqP` TL.elemIndices c
481t_count t = (subtract 1 . L.length . T.split t) `eq` T.count t
482tl_count t = (subtract 1 . L.genericLength . TL.split t) `eq` TL.count t
483t_zip s = L.zip s `eqP` T.zip (packS s)
484tl_zip s = L.zip s `eqP` TL.zip (packS s)
485sf_zipWith p c s = (L.zipWith c (L.filter p s) . L.filter p) `eqP` (unpackS . S.zipWith c (S.filter p $ packS s) . S.filter p)
486t_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
487tl_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
490shiftL w = forAll (choose (0,width-1)) $ \k -> Bits.shiftL w k == U.shiftL w k
491 where width = round (log (fromIntegral m) / log 2 :: Double)
492 (m,_) = (maxBound, m == w)
493shiftR w = forAll (choose (0,width-1)) $ \k -> Bits.shiftR w k == U.shiftR w k
494 where width = round (log (fromIntegral m) / log 2 :: Double)
495 (m,_) = (maxBound, m == w)
497shiftL_Int = shiftL :: Int -> Property
498shiftL_Word16 = shiftL :: Word16 -> Property
499shiftL_Word32 = shiftL :: Word32 -> Property
500shiftR_Int = shiftR :: Int -> Property
501shiftR_Word16 = shiftR :: Word16 -> Property
502shiftR_Word32 = shiftR :: Word32 -> Property
505s_filter_eq s = S.filter p t == S.streamList (filter p s)
506 where p = (/= S.last t)
509-- Make a stream appear shorter than it really is, to ensure that
510-- functions that consume inaccurately sized streams behave
512shorten :: Int -> S.Stream a -> S.Stream a
513shorten n t@(S.Stream arr off len)
514 | n < len && n > 0 = S.Stream arr off n
517main = defaultMain tests
520 testGroup "creation/elimination" [
521 testProperty "t_pack_unpack" t_pack_unpack,
522 testProperty "tl_pack_unpack" tl_pack_unpack,
523 testProperty "t_stream_unstream" t_stream_unstream,
524 testProperty "tl_stream_unstream" tl_stream_unstream,
525 testProperty "t_reverse_stream" t_reverse_stream,
526 testProperty "t_singleton" t_singleton,
527 testProperty "tl_singleton" tl_singleton,
528 testProperty "tl_unstreamChunks" tl_unstreamChunks,
529 testProperty "tl_chunk_unchunk" tl_chunk_unchunk
532 testGroup "transcoding" [
533 testProperty "t_ascii" t_ascii,
534 testProperty "t_utf8" t_utf8,
535 testProperty "tl_utf8" tl_utf8,
536 testProperty "t_utf16LE" t_utf16LE,
537 testProperty "t_utf16BE" t_utf16BE,
538 testProperty "t_utf32LE" t_utf32LE,
539 testProperty "t_utf32BE" t_utf32BE
542 testGroup "instances" [
543 testProperty "s_Eq" s_Eq,
544 testProperty "sf_Eq" sf_Eq,
545 testProperty "t_Eq" t_Eq,
546 testProperty "tl_Eq" tl_Eq,
547 testProperty "s_Ord" s_Ord,
548 testProperty "sf_Ord" sf_Ord,
549 testProperty "t_Ord" t_Ord,
550 testProperty "tl_Ord" tl_Ord,
551 testProperty "t_Read" t_Read,
552 testProperty "tl_Read" tl_Read,
553 testProperty "t_Show" t_Show,
554 testProperty "tl_Show" tl_Show,
555 testProperty "t_mappend" t_mappend,
556 testProperty "tl_mappend" tl_mappend,
557 testProperty "t_mconcat" t_mconcat,
558 testProperty "tl_mconcat" tl_mconcat,
559 testProperty "t_IsString" t_IsString,
560 testProperty "tl_IsString" tl_IsString
564 testProperty "s_cons" s_cons,
565 testProperty "sf_cons" sf_cons,
566 testProperty "t_cons" t_cons,
567 testProperty "tl_cons" tl_cons,
568 testProperty "s_snoc" s_snoc,
569 testProperty "t_snoc" t_snoc,
570 testProperty "tl_snoc" tl_snoc,
571 testProperty "s_append" s_append,
572 testProperty "sf_append" sf_append,
573 testProperty "t_append" t_append,
574 testProperty "s_uncons" s_uncons,
575 testProperty "sf_uncons" sf_uncons,
576 testProperty "t_uncons" t_uncons,
577 testProperty "tl_uncons" tl_uncons,
578 testProperty "s_head" s_head,
579 testProperty "sf_head" sf_head,
580 testProperty "t_head" t_head,
581 testProperty "tl_head" tl_head,
582 testProperty "s_last" s_last,
583 testProperty "sf_last" sf_last,
584 testProperty "t_last" t_last,
585 testProperty "tl_last" tl_last,
586 testProperty "s_tail" s_tail,
587 testProperty "sf_tail" sf_tail,
588 testProperty "t_tail" t_tail,
589 testProperty "tl_tail" tl_tail,
590 testProperty "s_init" s_init,
591 testProperty "sf_init" sf_init,
592 testProperty "t_init" t_init,
593 testProperty "tl_init" tl_init,
594 testProperty "s_null" s_null,
595 testProperty "sf_null" sf_null,
596 testProperty "t_null" t_null,
597 testProperty "tl_null" tl_null,
598 testProperty "s_length" s_length,
599 testProperty "sf_length" sf_length,
600 testProperty "t_length" t_length,
601 testProperty "tl_length" tl_length
604 testGroup "transformations" [
605 testProperty "s_map" s_map,
606 testProperty "sf_map" sf_map,
607 testProperty "t_map" t_map,
608 testProperty "tl_map" tl_map,
609 testProperty "t_intercalate" t_intercalate,
610 testProperty "tl_intercalate" tl_intercalate,
611 testProperty "s_intersperse" s_intersperse,
612 testProperty "sf_intersperse" sf_intersperse,
613 testProperty "t_intersperse" t_intersperse,
614 testProperty "tl_intersperse" tl_intersperse,
615 testProperty "t_transpose" t_transpose,
616 testProperty "tl_transpose" tl_transpose,
617 testProperty "t_reverse" t_reverse,
618 testProperty "tl_reverse" tl_reverse,
619 testProperty "t_reverse_short" t_reverse_short,
620 testProperty "t_replace" t_replace,
621 testProperty "tl_replace" tl_replace,
623 testGroup "case conversion" [
624 testProperty "s_toCaseFold_length" s_toCaseFold_length,
625 testProperty "sf_toCaseFold_length" sf_toCaseFold_length,
626 testProperty "t_toCaseFold_length" t_toCaseFold_length,
627 testProperty "tl_toCaseFold_length" tl_toCaseFold_length,
628 testProperty "t_toLower_length" t_toLower_length,
629 testProperty "t_toLower_lower" t_toLower_lower,
630 testProperty "tl_toLower_lower" tl_toLower_lower,
631 testProperty "t_toUpper_length" t_toUpper_length,
632 testProperty "t_toUpper_upper" t_toUpper_upper,
633 testProperty "tl_toUpper_upper" tl_toUpper_upper
636 testGroup "justification" [
637 testProperty "s_justifyLeft" s_justifyLeft,
638 testProperty "sf_justifyLeft" sf_justifyLeft,
639 testProperty "t_justifyLeft" t_justifyLeft,
640 testProperty "tl_justifyLeft" tl_justifyLeft,
641 testProperty "t_justifyRight" t_justifyRight,
642 testProperty "tl_justifyRight" tl_justifyRight
647 testProperty "sf_foldl" sf_foldl,
648 testProperty "t_foldl" t_foldl,
649 testProperty "tl_foldl" tl_foldl,
650 testProperty "sf_foldl'" sf_foldl',
651 testProperty "t_foldl'" t_foldl',
652 testProperty "tl_foldl'" tl_foldl',
653 testProperty "sf_foldl1" sf_foldl1,
654 testProperty "t_foldl1" t_foldl1,
655 testProperty "tl_foldl1" tl_foldl1,
656 testProperty "t_foldl1'" t_foldl1',
657 testProperty "sf_foldl1'" sf_foldl1',
658 testProperty "tl_foldl1'" tl_foldl1',
659 testProperty "sf_foldr" sf_foldr,
660 testProperty "t_foldr" t_foldr,
661 testProperty "tl_foldr" tl_foldr,
662 testProperty "sf_foldr1" sf_foldr1,
663 testProperty "t_foldr1" t_foldr1,
664 testProperty "tl_foldr1" tl_foldr1,
666 testGroup "special" [
667 testProperty "sf_concat" sf_concat,
668 testProperty "t_concat" t_concat,
669 testProperty "tl_concat" tl_concat,
670 testProperty "sf_concatMap" sf_concatMap,
671 testProperty "t_concatMap" t_concatMap,
672 testProperty "tl_concatMap" tl_concatMap,
673 testProperty "sf_any" sf_any,
674 testProperty "t_any" t_any,
675 testProperty "tl_any" tl_any,
676 testProperty "sf_all" sf_all,
677 testProperty "t_all" t_all,
678 testProperty "tl_all" tl_all,
679 testProperty "sf_maximum" sf_maximum,
680 testProperty "t_maximum" t_maximum,
681 testProperty "tl_maximum" tl_maximum,
682 testProperty "sf_minimum" sf_minimum,
683 testProperty "t_minimum" t_minimum,
684 testProperty "tl_minimum" tl_minimum
688 testGroup "construction" [
690 testProperty "sf_scanl" sf_scanl,
691 testProperty "t_scanl" t_scanl,
692 testProperty "tl_scanl" tl_scanl,
693 testProperty "t_scanl1" t_scanl1,
694 testProperty "tl_scanl1" tl_scanl1,
695 testProperty "t_scanr" t_scanr,
696 testProperty "tl_scanr" tl_scanr,
697 testProperty "t_scanr1" t_scanr1,
698 testProperty "tl_scanr1" tl_scanr1
701 testGroup "mapAccum" [
702 testProperty "t_mapAccumL" t_mapAccumL,
703 testProperty "tl_mapAccumL" tl_mapAccumL,
704 testProperty "t_mapAccumR" t_mapAccumR,
705 testProperty "tl_mapAccumR" tl_mapAccumR
708 testGroup "unfolds" [
709 testProperty "t_replicate" t_replicate,
710 testProperty "tl_replicate" tl_replicate,
711 testProperty "t_replicateChar" t_replicateChar,
712 testProperty "tl_replicateChar" tl_replicateChar,
713 testProperty "t_unfoldr" t_unfoldr,
714 testProperty "tl_unfoldr" tl_unfoldr,
715 testProperty "t_unfoldrN" t_unfoldrN,
716 testProperty "tl_unfoldrN" tl_unfoldrN
720 testGroup "substrings" [
721 testGroup "breaking" [
722 testProperty "s_take" s_take,
723 testProperty "sf_take" sf_take,
724 testProperty "t_take" t_take,
725 testProperty "tl_take" tl_take,
726 testProperty "s_drop" s_drop,
727 testProperty "sf_drop" sf_drop,
728 testProperty "t_drop" t_drop,
729 testProperty "tl_drop" tl_drop,
730 testProperty "s_takeWhile" s_takeWhile,
731 testProperty "sf_takeWhile" sf_takeWhile,
732 testProperty "t_takeWhile" t_takeWhile,
733 testProperty "tl_takeWhile" tl_takeWhile,
734 testProperty "sf_dropWhile" sf_dropWhile,
735 testProperty "s_dropWhile" s_dropWhile,
736 testProperty "t_dropWhile" t_dropWhile,
737 testProperty "tl_dropWhile" tl_dropWhile,
738 testProperty "t_dropWhileEnd" t_dropWhileEnd,
739 testProperty "tl_dropWhileEnd" tl_dropWhileEnd,
740 testProperty "t_dropAround" t_dropAround,
741 testProperty "tl_dropAround" tl_dropAround,
742 testProperty "t_stripStart" t_stripStart,
743 testProperty "tl_stripStart" tl_stripStart,
744 testProperty "t_stripEnd" t_stripEnd,
745 testProperty "tl_stripEnd" tl_stripEnd,
746 testProperty "t_strip" t_strip,
747 testProperty "tl_strip" tl_strip,
748 testProperty "t_splitAt" t_splitAt,
749 testProperty "tl_splitAt" tl_splitAt,
750 testProperty "t_span" t_span,
751 testProperty "tl_span" tl_span,
752 testProperty "t_break" t_break,
753 testProperty "tl_break" tl_break,
754 testProperty "t_group" t_group,
755 testProperty "tl_group" tl_group,
756 testProperty "t_groupBy" t_groupBy,
757 testProperty "tl_groupBy" tl_groupBy,
758 testProperty "t_inits" t_inits,
759 testProperty "tl_inits" tl_inits,
760 testProperty "t_tails" t_tails,
761 testProperty "tl_tails" tl_tails
764 testGroup "breaking many" [
765 testProperty "t_split_i" t_split_i,
766 testProperty "t_splitTimes_i" t_splitTimes_i,
767 testProperty "tl_splitTimes_i" tl_splitTimes_i,
768 testProperty "t_splitTimes_split" t_splitTimes_split,
769 testProperty "tl_splitTimes_split" tl_splitTimes_split,
770 testProperty "t_splitTimesEnd_i" t_splitTimesEnd_i,
771 testProperty "tl_splitTimesEnd_i" tl_splitTimesEnd_i,
772 testProperty "t_splitTimesEnd_split" t_splitTimesEnd_split,
773 testProperty "tl_splitTimesEnd_split" tl_splitTimesEnd_split,
774 testProperty "tl_split_i" tl_split_i,
775 testProperty "t_splitWith" t_splitWith,
776 testProperty "t_splitWith_count" t_splitWith_count,
777 testProperty "t_splitWith_split" t_splitWith_split,
778 testProperty "tl_splitWith" tl_splitWith,
779 testProperty "t_chunksOf_same_lengths" t_chunksOf_same_lengths,
780 testProperty "t_chunksOf_length" t_chunksOf_length,
781 testProperty "tl_chunksOf" tl_chunksOf
784 testGroup "lines and words" [
785 testProperty "t_lines" t_lines,
786 testProperty "tl_lines" tl_lines,
787 --testProperty "t_lines'" t_lines',
788 testProperty "t_words" t_words,
789 testProperty "tl_words" tl_words,
790 testProperty "t_unlines" t_unlines,
791 testProperty "tl_unlines" tl_unlines,
792 testProperty "t_unwords" t_unwords,
793 testProperty "tl_unwords" tl_unwords
797 testGroup "predicates" [
798 testProperty "s_isPrefixOf" s_isPrefixOf,
799 testProperty "sf_isPrefixOf" sf_isPrefixOf,
800 testProperty "t_isPrefixOf" t_isPrefixOf,
801 testProperty "tl_isPrefixOf" tl_isPrefixOf,
802 testProperty "t_isSuffixOf" t_isSuffixOf,
803 testProperty "tl_isSuffixOf" tl_isSuffixOf,
804 testProperty "t_isInfixOf" t_isInfixOf,
805 testProperty "tl_isInfixOf" tl_isInfixOf
808 testGroup "searching" [
809 testProperty "sf_elem" sf_elem,
810 testProperty "t_elem" t_elem,
811 testProperty "tl_elem" tl_elem,
812 testProperty "sf_filter" sf_filter,
813 testProperty "t_filter" t_filter,
814 testProperty "tl_filter" tl_filter,
815 testProperty "sf_find" sf_find,
816 testProperty "t_find" t_find,
817 testProperty "tl_find" tl_find,
818 testProperty "t_partition" t_partition,
819 testProperty "tl_partition" tl_partition
822 testGroup "indexing" [
823 testProperty "sf_index" sf_index,
824 testProperty "t_index" t_index,
825 testProperty "tl_index" tl_index,
826 testProperty "sf_findIndex" sf_findIndex,
827 testProperty "t_findIndex" t_findIndex,
828 testProperty "tl_findIndex" tl_findIndex,
829 testProperty "sf_findIndices" sf_findIndices,
830 testProperty "t_findIndices" t_findIndices,
831 testProperty "tl_findIndices" tl_findIndices,
832 testProperty "sf_elemIndex" sf_elemIndex,
833 testProperty "t_elemIndex" t_elemIndex,
834 testProperty "tl_elemIndex" tl_elemIndex,
835 testProperty "sf_elemIndices" sf_elemIndices,
836 testProperty "t_elemIndices" t_elemIndices,
837 testProperty "tl_elemIndices" tl_elemIndices,
838 testProperty "t_count" t_count,
839 testProperty "tl_count" tl_count
843 testProperty "t_zip" t_zip,
844 testProperty "tl_zip" tl_zip,
845 testProperty "sf_zipWith" sf_zipWith,
846 testProperty "t_zipWith" t_zipWith,
847 testProperty "tl_zipWith" tl_zipWith
850 testGroup "regressions" [
851 testProperty "s_filter_eq" s_filter_eq
855 testProperty "shiftL_Int" shiftL_Int,
856 testProperty "shiftL_Word16" shiftL_Word16,
857 testProperty "shiftL_Word32" shiftL_Word32,
858 testProperty "shiftR_Int" shiftR_Int,
859 testProperty "shiftR_Word16" shiftR_Word16,
860 testProperty "shiftR_Word32" shiftR_Word32
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list