@@ -0,0 +1,1242 @@
1+{-# LANGUAGE BangPatterns, FlexibleInstances, OverloadedStrings,
2+ ScopedTypeVariables, TypeSynonymInstances, CPP #-}
3+{-# OPTIONS_GHC -fno-enable-rewrite-rules #-}
4+
5+import Test.QuickCheck
6+import Test.QuickCheck.Monadic
7+import Text.Show.Functions ()
8+
9+import qualified Data.Bits as Bits (shiftL, shiftR)
10+import Numeric (showHex)
11+import Data.Char (chr, isDigit, isHexDigit, isLower, isSpace, isUpper, ord)
12+import Data.Monoid (Monoid(..))
13+import Data.String (fromString)
14+import Debug.Trace (trace)
15+import Control.Arrow ((***), second)
16+import Control.DeepSeq
17+import Data.Word (Word8, Word16, Word32)
18+import qualified Data.Text as T
19+import qualified Data.Text.IO as T
20+import qualified Data.Text.Lazy as TL
21+import qualified Data.Text.Lazy.IO as TL
22+import qualified Data.Text.Lazy.Internal as TL
23+import qualified Data.Text.Lazy.Builder as TB
24+import qualified Data.Text.Encoding as E
25+import Data.Text.Read as T
26+import Data.Text.Lazy.Read as TL
27+import Data.Text.Encoding.Error
28+import Control.Exception (SomeException, bracket, catch, evaluate, try)
29+import Data.Text.Foreign
30+import qualified Data.Text.Fusion as S
31+import qualified Data.Text.Fusion.Common as S
32+import Data.Text.Fusion.Size
33+import qualified Data.Text.Lazy.Encoding as EL
34+import qualified Data.Text.Lazy.Fusion as SL
35+import qualified Data.Text.UnsafeShift as U
36+import qualified Data.List as L
37+import Prelude hiding (catch, replicate)
38+import System.IO
39+import System.IO.Unsafe (unsafePerformIO)
40+import Test.Framework (Test, defaultMain, testGroup)
41+import Test.Framework.Providers.QuickCheck2 (testProperty)
42+import Data.Text.Search (indices)
43+import qualified Data.Text.Lazy.Search as S (indices)
44+
45+import Data.Text.Tests.QuickCheckUtils
46+import Data.Text.Tests.TestUtils
47+import qualified Data.Text.Tests.SlowFunctions as Slow
48+
49+-- Ensure that two potentially bottom values (in the sense of crashing
50+-- for some inputs, not looping infinitely) either both crash, or both
51+-- give comparable results for some input.
52+(=^=) :: (Eq a, Show a) => a -> a -> Bool
53+{-# NOINLINE (=^=) #-}
54+i =^= j = unsafePerformIO $ do
55+ x <- try (evaluate i)
56+ y <- try (evaluate j)
57+ case (x,y) of
58+ (Left (_ :: SomeException), Left (_ :: SomeException))
59+ -> return True
60+ (Right a, Right b) -> return (a == b)
61+ e -> trace ("*** Divergence: " ++ show e) return False
62+infix 4 =^=
63+
64+t_pack_unpack = (T.unpack . T.pack) `eq` id
65+tl_pack_unpack = (TL.unpack . TL.pack) `eq` id
66+t_stream_unstream = (S.unstream . S.stream) `eq` id
67+tl_stream_unstream = (SL.unstream . SL.stream) `eq` id
68+t_reverse_stream t = (S.reverse . S.reverseStream) t == t
69+t_singleton c = [c] == (T.unpack . T.singleton) c
70+tl_singleton c = [c] == (TL.unpack . TL.singleton) c
71+tl_unstreamChunks x = f 11 x == f 1000 x
72+ where f n = SL.unstreamChunks n . S.streamList
73+tl_chunk_unchunk = (TL.fromChunks . TL.toChunks) `eq` id
74+tl_from_to_strict = (TL.fromStrict . TL.toStrict) `eq` id
75+
76+t_ascii t = E.decodeASCII (E.encodeUtf8 a) == a
77+ where a = T.map (\c -> chr (ord c `mod` 128)) t
78+tl_ascii t = EL.decodeASCII (EL.encodeUtf8 a) == a
79+ where a = TL.map (\c -> chr (ord c `mod` 128)) t
80+t_utf8 = forAll genUnicode $ (E.decodeUtf8 . E.encodeUtf8) `eq` id
81+t_utf8' = forAll genUnicode $ (E.decodeUtf8' . E.encodeUtf8) `eq` (id . Right)
82+tl_utf8 = forAll genUnicode $ (EL.decodeUtf8 . EL.encodeUtf8) `eq` id
83+tl_utf8' = forAll genUnicode $ (EL.decodeUtf8' . EL.encodeUtf8) `eq` (id . Right)
84+t_utf16LE = forAll genUnicode $ (E.decodeUtf16LE . E.encodeUtf16LE) `eq` id
85+tl_utf16LE = forAll genUnicode $ (EL.decodeUtf16LE . EL.encodeUtf16LE) `eq` id
86+t_utf16BE = forAll genUnicode $ (E.decodeUtf16BE . E.encodeUtf16BE) `eq` id
87+tl_utf16BE = forAll genUnicode $ (EL.decodeUtf16BE . EL.encodeUtf16BE) `eq` id
88+t_utf32LE = forAll genUnicode $ (E.decodeUtf32LE . E.encodeUtf32LE) `eq` id
89+tl_utf32LE = forAll genUnicode $ (EL.decodeUtf32LE . EL.encodeUtf32LE) `eq` id
90+t_utf32BE = forAll genUnicode $ (E.decodeUtf32BE . E.encodeUtf32BE) `eq` id
91+tl_utf32BE = forAll genUnicode $ (EL.decodeUtf32BE . EL.encodeUtf32BE) `eq` id
92+
93+data DecodeErr = DE String OnDecodeError
94+
95+instance Show DecodeErr where
96+ show (DE d _) = "DE " ++ d
97+
98+instance Arbitrary DecodeErr where
99+ arbitrary = oneof [ return $ DE "lenient" lenientDecode
100+ , return $ DE "ignore" ignore
101+ , return $ DE "strict" strictDecode
102+ , DE "replace" `fmap` arbitrary ]
103+
104+-- This is a poor attempt to ensure that the error handling paths on
105+-- decode are exercised in some way. Proper testing would be rather
106+-- more involved.
107+t_utf8_err (DE _ de) bs = monadicIO $ do
108+ l <- run $ let len = T.length (E.decodeUtf8With de bs)
109+ in (len `seq` return (Right len)) `catch`
110+ (\(e::UnicodeException) -> return (Left e))
111+ case l of
112+ Left err -> assert $ length (show err) >= 0
113+ Right n -> assert $ n >= 0
114+
115+t_utf8_err' bs = monadicIO . assert $ case E.decodeUtf8' bs of
116+ Left err -> length (show err) >= 0
117+ Right t -> T.length t >= 0
118+
119+class Stringy s where
120+ packS :: String -> s
121+ unpackS :: s -> String
122+ splitAtS :: Int -> s -> (s,s)
123+ packSChunkSize :: Int -> String -> s
124+ packSChunkSize _ = packS
125+
126+instance Stringy String where
127+ packS = id
128+ unpackS = id
129+ splitAtS = splitAt
130+
131+instance Stringy (S.Stream Char) where
132+ packS = S.streamList
133+ unpackS = S.unstreamList
134+ splitAtS n s = (S.take n s, S.drop n s)
135+
136+instance Stringy T.Text where
137+ packS = T.pack
138+ unpackS = T.unpack
139+ splitAtS = T.splitAt
140+
141+instance Stringy TL.Text where
142+ packSChunkSize k = SL.unstreamChunks k . S.streamList
143+ packS = TL.pack
144+ unpackS = TL.unpack
145+ splitAtS = ((TL.lazyInvariant *** TL.lazyInvariant) .) .
146+ TL.splitAt . fromIntegral
147+
148+-- Do two functions give the same answer?
149+eq :: (Eq a, Show a) => (t -> a) -> (t -> a) -> t -> Bool
150+eq a b s = a s =^= b s
151+
152+-- What about with the RHS packed?
153+eqP :: (Eq a, Show a, Stringy s) =>
154+ (String -> a) -> (s -> a) -> String -> Word8 -> Bool
155+eqP f g s w = eql "orig" (f s) (g t) &&
156+ eql "mini" (f s) (g mini) &&
157+ eql "head" (f sa) (g ta) &&
158+ eql "tail" (f sb) (g tb)
159+ where t = packS s
160+ mini = packSChunkSize 10 s
161+ (sa,sb) = splitAt m s
162+ (ta,tb) = splitAtS m t
163+ l = length s
164+ m | l == 0 = n
165+ | otherwise = n `mod` l
166+ n = fromIntegral w
167+ eql d a b
168+ | a =^= b = True
169+ | otherwise = trace (d ++ ": " ++ show a ++ " /= " ++ show b) False
170+
171+s_Eq s = (s==) `eq` ((S.streamList s==) . S.streamList)
172+ where _types = s :: String
173+sf_Eq p s =
174+ ((L.filter p s==) . L.filter p) `eq`
175+ (((S.filter p $ S.streamList s)==) . S.filter p . S.streamList)
176+t_Eq s = (s==) `eq` ((T.pack s==) . T.pack)
177+tl_Eq s = (s==) `eq` ((TL.pack s==) . TL.pack)
178+s_Ord s = (compare s) `eq` (compare (S.streamList s) . S.streamList)
179+ where _types = s :: String
180+sf_Ord p s =
181+ ((compare $ L.filter p s) . L.filter p) `eq`
182+ (compare (S.filter p $ S.streamList s) . S.filter p . S.streamList)
183+t_Ord s = (compare s) `eq` (compare (T.pack s) . T.pack)
184+tl_Ord s = (compare s) `eq` (compare (TL.pack s) . TL.pack)
185+t_Read = id `eq` (T.unpack . read . show)
186+tl_Read = id `eq` (TL.unpack . read . show)
187+t_Show = show `eq` (show . T.pack)
188+tl_Show = show `eq` (show . TL.pack)
189+t_mappend s = mappend s`eqP` (unpackS . mappend (T.pack s))
190+tl_mappend s = mappend s`eqP` (unpackS . mappend (TL.pack s))
191+t_mconcat = mconcat `eq` (unpackS . mconcat . L.map T.pack)
192+tl_mconcat = mconcat `eq` (unpackS . mconcat . L.map TL.pack)
193+t_mempty = mempty == (unpackS (mempty :: T.Text))
194+tl_mempty = mempty == (unpackS (mempty :: TL.Text))
195+t_IsString = fromString `eqP` (T.unpack . fromString)
196+tl_IsString = fromString `eqP` (TL.unpack . fromString)
197+
198+s_cons x = (x:) `eqP` (unpackS . S.cons x)
199+s_cons_s x = (x:) `eqP` (unpackS . S.unstream . S.cons x)
200+sf_cons p x = ((x:) . L.filter p) `eqP` (unpackS . S.cons x . S.filter p)
201+t_cons x = (x:) `eqP` (unpackS . T.cons x)
202+tl_cons x = (x:) `eqP` (unpackS . TL.cons x)
203+s_snoc x = (++ [x]) `eqP` (unpackS . (flip S.snoc) x)
204+t_snoc x = (++ [x]) `eqP` (unpackS . (flip T.snoc) x)
205+tl_snoc x = (++ [x]) `eqP` (unpackS . (flip TL.snoc) x)
206+s_append s = (s++) `eqP` (unpackS . S.append (S.streamList s))
207+s_append_s s = (s++) `eqP`
208+ (unpackS . S.unstream . S.append (S.streamList s))
209+sf_append p s = (L.filter p s++) `eqP`
210+ (unpackS . S.append (S.filter p $ S.streamList s))
211+t_append s = (s++) `eqP` (unpackS . T.append (packS s))
212+
213+uncons (x:xs) = Just (x,xs)
214+uncons _ = Nothing
215+
216+s_uncons = uncons `eqP` (fmap (second unpackS) . S.uncons)
217+sf_uncons p = (uncons . L.filter p) `eqP`
218+ (fmap (second unpackS) . S.uncons . S.filter p)
219+t_uncons = uncons `eqP` (fmap (second unpackS) . T.uncons)
220+tl_uncons = uncons `eqP` (fmap (second unpackS) . TL.uncons)
221+s_head = head `eqP` S.head
222+sf_head p = (head . L.filter p) `eqP` (S.head . S.filter p)
223+t_head = head `eqP` T.head
224+tl_head = head `eqP` TL.head
225+s_last = last `eqP` S.last
226+sf_last p = (last . L.filter p) `eqP` (S.last . S.filter p)
227+t_last = last `eqP` T.last
228+tl_last = last `eqP` TL.last
229+s_tail = tail `eqP` (unpackS . S.tail)
230+s_tail_s = tail `eqP` (unpackS . S.unstream . S.tail)
231+sf_tail p = (tail . L.filter p) `eqP` (unpackS . S.tail . S.filter p)
232+t_tail = tail `eqP` (unpackS . T.tail)
233+tl_tail = tail `eqP` (unpackS . TL.tail)
234+s_init = init `eqP` (unpackS . S.init)
235+s_init_s = init `eqP` (unpackS . S.unstream . S.init)
236+sf_init p = (init . L.filter p) `eqP` (unpackS . S.init . S.filter p)
237+t_init = init `eqP` (unpackS . T.init)
238+tl_init = init `eqP` (unpackS . TL.init)
239+s_null = null `eqP` S.null
240+sf_null p = (null . L.filter p) `eqP` (S.null . S.filter p)
241+t_null = null `eqP` T.null
242+tl_null = null `eqP` TL.null
243+s_length = length `eqP` S.length
244+sf_length p = (length . L.filter p) `eqP` (S.length . S.filter p)
245+sl_length = (fromIntegral . length) `eqP` SL.length
246+t_length = length `eqP` T.length
247+tl_length = L.genericLength `eqP` TL.length
248+t_compareLength t = (compare (T.length t)) `eq` T.compareLength t
249+tl_compareLength t= (compare (TL.length t)) `eq` TL.compareLength t
250+
251+s_map f = map f `eqP` (unpackS . S.map f)
252+s_map_s f = map f `eqP` (unpackS . S.unstream . S.map f)
253+sf_map p f = (map f . L.filter p) `eqP` (unpackS . S.map f . S.filter p)
254+t_map f = map f `eqP` (unpackS . T.map f)
255+tl_map f = map f `eqP` (unpackS . TL.map f)
256+t_intercalate c = L.intercalate c `eq`
257+ (unpackS . T.intercalate (packS c) . map packS)
258+tl_intercalate c = L.intercalate c `eq`
259+ (unpackS . TL.intercalate (TL.pack c) . map TL.pack)
260+s_intersperse c = L.intersperse c `eqP`
261+ (unpackS . S.intersperse c)
262+s_intersperse_s c = L.intersperse c `eqP`
263+ (unpackS . S.unstream . S.intersperse c)
264+sf_intersperse p c= (L.intersperse c . L.filter p) `eqP`
265+ (unpackS . S.intersperse c . S.filter p)
266+t_intersperse c = L.intersperse c `eqP` (unpackS . T.intersperse c)
267+tl_intersperse c = L.intersperse c `eqP` (unpackS . TL.intersperse c)
268+t_transpose = L.transpose `eq` (map unpackS . T.transpose . map packS)
269+tl_transpose = L.transpose `eq` (map unpackS . TL.transpose . map TL.pack)
270+t_reverse = L.reverse `eqP` (unpackS . T.reverse)
271+tl_reverse = L.reverse `eqP` (unpackS . TL.reverse)
272+t_reverse_short n = L.reverse `eqP` (unpackS . S.reverse . shorten n . S.stream)
273+
274+t_replace s d = (L.intercalate d . splitOn s) `eqP`
275+ (unpackS . T.replace (T.pack s) (T.pack d))
276+tl_replace s d = (L.intercalate d . splitOn s) `eqP`
277+ (unpackS . TL.replace (TL.pack s) (TL.pack d))
278+
279+splitOn :: (Eq a) => [a] -> [a] -> [[a]]
280+splitOn pat src0
281+ | l == 0 = error "empty"
282+ | otherwise = go src0
283+ where
284+ l = length pat
285+ go src = search 0 src
286+ where
287+ search _ [] = [src]
288+ search !n s@(_:s')
289+ | pat `L.isPrefixOf` s = take n src : go (drop l s)
290+ | otherwise = search (n+1) s'
291+
292+s_toCaseFold_length xs = S.length (S.toCaseFold s) >= length xs
293+ where s = S.streamList xs
294+sf_toCaseFold_length p xs =
295+ (S.length . S.toCaseFold . S.filter p $ s) >= (length . L.filter p $ xs)
296+ where s = S.streamList xs
297+t_toCaseFold_length t = T.length (T.toCaseFold t) >= T.length t
298+tl_toCaseFold_length t = TL.length (TL.toCaseFold t) >= TL.length t
299+t_toLower_length t = T.length (T.toLower t) >= T.length t
300+t_toLower_lower t = p (T.toLower t) >= p t
301+ where p = T.length . T.filter isLower
302+tl_toLower_lower t = p (TL.toLower t) >= p t
303+ where p = TL.length . TL.filter isLower
304+t_toUpper_length t = T.length (T.toUpper t) >= T.length t
305+t_toUpper_upper t = p (T.toUpper t) >= p t
306+ where p = T.length . T.filter isUpper
307+tl_toUpper_upper t = p (TL.toUpper t) >= p t
308+ where p = TL.length . TL.filter isUpper
309+
310+justifyLeft k c xs = xs ++ L.replicate (k - length xs) c
311+justifyRight m n xs = L.replicate (m - length xs) n ++ xs
312+center k c xs
313+ | len >= k = xs
314+ | otherwise = L.replicate l c ++ xs ++ L.replicate r c
315+ where len = length xs
316+ d = k - len
317+ r = d `div` 2
318+ l = d - r
319+
320+s_justifyLeft k c = justifyLeft j c `eqP` (unpackS . S.justifyLeftI j c)
321+ where j = fromIntegral (k :: Word8)
322+s_justifyLeft_s k c = justifyLeft j c `eqP`
323+ (unpackS . S.unstream . S.justifyLeftI j c)
324+ where j = fromIntegral (k :: Word8)
325+sf_justifyLeft p k c = (justifyLeft j c . L.filter p) `eqP`
326+ (unpackS . S.justifyLeftI j c . S.filter p)
327+ where j = fromIntegral (k :: Word8)
328+t_justifyLeft k c = justifyLeft j c `eqP` (unpackS . T.justifyLeft j c)
329+ where j = fromIntegral (k :: Word8)
330+tl_justifyLeft k c = justifyLeft j c `eqP`
331+ (unpackS . TL.justifyLeft (fromIntegral j) c)
332+ where j = fromIntegral (k :: Word8)
333+t_justifyRight k c = justifyRight j c `eqP` (unpackS . T.justifyRight j c)
334+ where j = fromIntegral (k :: Word8)
335+tl_justifyRight k c = justifyRight j c `eqP`
336+ (unpackS . TL.justifyRight (fromIntegral j) c)
337+ where j = fromIntegral (k :: Word8)
338+t_center k c = center j c `eqP` (unpackS . T.center j c)
339+ where j = fromIntegral (k :: Word8)
340+tl_center k c = center j c `eqP` (unpackS . TL.center (fromIntegral j) c)
341+ where j = fromIntegral (k :: Word8)
342+
343+sf_foldl p f z = (L.foldl f z . L.filter p) `eqP` (S.foldl f z . S.filter p)
344+ where _types = f :: Char -> Char -> Char
345+t_foldl f z = L.foldl f z `eqP` (T.foldl f z)
346+ where _types = f :: Char -> Char -> Char
347+tl_foldl f z = L.foldl f z `eqP` (TL.foldl f z)
348+ where _types = f :: Char -> Char -> Char
349+sf_foldl' p f z = (L.foldl' f z . L.filter p) `eqP`
350+ (S.foldl' f z . S.filter p)
351+ where _types = f :: Char -> Char -> Char
352+t_foldl' f z = L.foldl' f z `eqP` T.foldl' f z
353+ where _types = f :: Char -> Char -> Char
354+tl_foldl' f z = L.foldl' f z `eqP` TL.foldl' f z
355+ where _types = f :: Char -> Char -> Char
356+sf_foldl1 p f = (L.foldl1 f . L.filter p) `eqP` (S.foldl1 f . S.filter p)
357+t_foldl1 f = L.foldl1 f `eqP` T.foldl1 f
358+tl_foldl1 f = L.foldl1 f `eqP` TL.foldl1 f
359+sf_foldl1' p f = (L.foldl1' f . L.filter p) `eqP` (S.foldl1' f . S.filter p)
360+t_foldl1' f = L.foldl1' f `eqP` T.foldl1' f
361+tl_foldl1' f = L.foldl1' f `eqP` TL.foldl1' f
362+sf_foldr p f z = (L.foldr f z . L.filter p) `eqP` (S.foldr f z . S.filter p)
363+ where _types = f :: Char -> Char -> Char
364+t_foldr f z = L.foldr f z `eqP` T.foldr f z
365+ where _types = f :: Char -> Char -> Char
366+tl_foldr f z = L.foldr f z `eqP` TL.foldr f z
367+ where _types = f :: Char -> Char -> Char
368+sf_foldr1 p f = (L.foldr1 f . L.filter p) `eqP` (S.foldr1 f . S.filter p)
369+t_foldr1 f = L.foldr1 f `eqP` T.foldr1 f
370+tl_foldr1 f = L.foldr1 f `eqP` TL.foldr1 f
371+
372+s_concat_s = L.concat `eq` (unpackS . S.unstream . S.concat . map packS)
373+sf_concat p = (L.concat . map (L.filter p)) `eq`
374+ (unpackS . S.concat . map (S.filter p . packS))
375+t_concat = L.concat `eq` (unpackS . T.concat . map packS)
376+tl_concat = L.concat `eq` (unpackS . TL.concat . map TL.pack)
377+sf_concatMap p f = unsquare $ (L.concatMap f . L.filter p) `eqP`
378+ (unpackS . S.concatMap (packS . f) . S.filter p)
379+t_concatMap f = unsquare $
380+ L.concatMap f `eqP` (unpackS . T.concatMap (packS . f))
381+tl_concatMap f = unsquare $
382+ L.concatMap f `eqP` (unpackS . TL.concatMap (TL.pack . f))
383+sf_any q p = (L.any p . L.filter q) `eqP` (S.any p . S.filter q)
384+t_any p = L.any p `eqP` T.any p
385+tl_any p = L.any p `eqP` TL.any p
386+sf_all q p = (L.all p . L.filter q) `eqP` (S.all p . S.filter q)
387+t_all p = L.all p `eqP` T.all p
388+tl_all p = L.all p `eqP` TL.all p
389+sf_maximum p = (L.maximum . L.filter p) `eqP` (S.maximum . S.filter p)
390+t_maximum = L.maximum `eqP` T.maximum
391+tl_maximum = L.maximum `eqP` TL.maximum
392+sf_minimum p = (L.minimum . L.filter p) `eqP` (S.minimum . S.filter p)
393+t_minimum = L.minimum `eqP` T.minimum
394+tl_minimum = L.minimum `eqP` TL.minimum
395+
396+sf_scanl p f z = (L.scanl f z . L.filter p) `eqP`
397+ (unpackS . S.scanl f z . S.filter p)
398+t_scanl f z = L.scanl f z `eqP` (unpackS . T.scanl f z)
399+tl_scanl f z = L.scanl f z `eqP` (unpackS . TL.scanl f z)
400+t_scanl1 f = L.scanl1 f `eqP` (unpackS . T.scanl1 f)
401+tl_scanl1 f = L.scanl1 f `eqP` (unpackS . TL.scanl1 f)
402+t_scanr f z = L.scanr f z `eqP` (unpackS . T.scanr f z)
403+tl_scanr f z = L.scanr f z `eqP` (unpackS . TL.scanr f z)
404+t_scanr1 f = L.scanr1 f `eqP` (unpackS . T.scanr1 f)
405+tl_scanr1 f = L.scanr1 f `eqP` (unpackS . TL.scanr1 f)
406+
407+t_mapAccumL f z = L.mapAccumL f z `eqP` (second unpackS . T.mapAccumL f z)
408+ where _types = f :: Int -> Char -> (Int,Char)
409+tl_mapAccumL f z = L.mapAccumL f z `eqP` (second unpackS . TL.mapAccumL f z)
410+ where _types = f :: Int -> Char -> (Int,Char)
411+t_mapAccumR f z = L.mapAccumR f z `eqP` (second unpackS . T.mapAccumR f z)
412+ where _types = f :: Int -> Char -> (Int,Char)
413+tl_mapAccumR f z = L.mapAccumR f z `eqP` (second unpackS . TL.mapAccumR f z)
414+ where _types = f :: Int -> Char -> (Int,Char)
415+
416+replicate n l = concat (L.replicate n l)
417+
418+t_replicate n = replicate m `eq` (unpackS . T.replicate m . packS)
419+ where m = fromIntegral (n :: Word8)
420+tl_replicate n = replicate m `eq`
421+ (unpackS . TL.replicate (fromIntegral m) . packS)
422+ where m = fromIntegral (n :: Word8)
423+
424+unf :: Int -> Char -> Maybe (Char, Char)
425+unf n c | fromEnum c * 100 > n = Nothing
426+ | otherwise = Just (c, succ c)
427+
428+t_unfoldr n = L.unfoldr (unf m) `eq` (unpackS . T.unfoldr (unf m))
429+ where m = fromIntegral (n :: Word16)
430+tl_unfoldr n = L.unfoldr (unf m) `eq` (unpackS . TL.unfoldr (unf m))
431+ where m = fromIntegral (n :: Word16)
432+t_unfoldrN n m = (L.take i . L.unfoldr (unf j)) `eq`
433+ (unpackS . T.unfoldrN i (unf j))
434+ where i = fromIntegral (n :: Word16)
435+ j = fromIntegral (m :: Word16)
436+tl_unfoldrN n m = (L.take i . L.unfoldr (unf j)) `eq`
437+ (unpackS . TL.unfoldrN (fromIntegral i) (unf j))
438+ where i = fromIntegral (n :: Word16)
439+ j = fromIntegral (m :: Word16)
440+
441+unpack2 :: (Stringy s) => (s,s) -> (String,String)
442+unpack2 = unpackS *** unpackS
443+
444+s_take n = L.take n `eqP` (unpackS . S.take n)
445+s_take_s m = L.take n `eqP` (unpackS . S.unstream . S.take n)
446+ where n = small m
447+sf_take p n = (L.take n . L.filter p) `eqP`
448+ (unpackS . S.take n . S.filter p)
449+t_take n = L.take n `eqP` (unpackS . T.take n)
450+tl_take n = L.take n `eqP` (unpackS . TL.take (fromIntegral n))
451+s_drop n = L.drop n `eqP` (unpackS . S.drop n)
452+s_drop_s m = L.drop n `eqP` (unpackS . S.unstream . S.drop n)
453+ where n = small m
454+sf_drop p n = (L.drop n . L.filter p) `eqP`
455+ (unpackS . S.drop n . S.filter p)
456+t_drop n = L.drop n `eqP` (unpackS . T.drop n)
457+tl_drop n = L.drop n `eqP` (unpackS . TL.drop (fromIntegral n))
458+s_take_drop m = (L.take n . L.drop n) `eqP` (unpackS . S.take n . S.drop n)
459+ where n = small m
460+s_take_drop_s m = (L.take n . L.drop n) `eqP`
461+ (unpackS . S.unstream . S.take n . S.drop n)
462+ where n = small m
463+s_takeWhile p = L.takeWhile p `eqP` (unpackS . S.takeWhile p)
464+s_takeWhile_s p = L.takeWhile p `eqP` (unpackS . S.unstream . S.takeWhile p)
465+sf_takeWhile q p = (L.takeWhile p . L.filter q) `eqP`
466+ (unpackS . S.takeWhile p . S.filter q)
467+t_takeWhile p = L.takeWhile p `eqP` (unpackS . T.takeWhile p)
468+tl_takeWhile p = L.takeWhile p `eqP` (unpackS . TL.takeWhile p)
469+s_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
470+s_dropWhile_s p = L.dropWhile p `eqP` (unpackS . S.unstream . S.dropWhile p)
471+sf_dropWhile q p = (L.dropWhile p . L.filter q) `eqP`
472+ (unpackS . S.dropWhile p . S.filter q)
473+t_dropWhile p = L.dropWhile p `eqP` (unpackS . T.dropWhile p)
474+tl_dropWhile p = L.dropWhile p `eqP` (unpackS . S.dropWhile p)
475+t_dropWhileEnd p = (L.reverse . L.dropWhile p . L.reverse) `eqP`
476+ (unpackS . T.dropWhileEnd p)
477+tl_dropWhileEnd p = (L.reverse . L.dropWhile p . L.reverse) `eqP`
478+ (unpackS . TL.dropWhileEnd p)
479+t_dropAround p = (L.dropWhile p . L.reverse . L.dropWhile p . L.reverse)
480+ `eqP` (unpackS . T.dropAround p)
481+tl_dropAround p = (L.dropWhile p . L.reverse . L.dropWhile p . L.reverse)
482+ `eqP` (unpackS . TL.dropAround p)
483+t_stripStart = T.dropWhile isSpace `eq` T.stripStart
484+tl_stripStart = TL.dropWhile isSpace `eq` TL.stripStart
485+t_stripEnd = T.dropWhileEnd isSpace `eq` T.stripEnd
486+tl_stripEnd = TL.dropWhileEnd isSpace `eq` TL.stripEnd
487+t_strip = T.dropAround isSpace `eq` T.strip
488+tl_strip = TL.dropAround isSpace `eq` TL.strip
489+t_splitAt n = L.splitAt n `eqP` (unpack2 . T.splitAt n)
490+tl_splitAt n = L.splitAt n `eqP` (unpack2 . TL.splitAt (fromIntegral n))
491+t_span p = L.span p `eqP` (unpack2 . T.span p)
492+tl_span p = L.span p `eqP` (unpack2 . TL.span p)
493+
494+t_breakOn_id s = squid `eq` (uncurry T.append . T.breakOn s)
495+ where squid t | T.null s = error "empty"
496+ | otherwise = t
497+tl_breakOn_id s = squid `eq` (uncurry TL.append . TL.breakOn s)
498+ where squid t | TL.null s = error "empty"
499+ | otherwise = t
500+t_breakOn_start (NotEmpty s) t = let (_,m) = T.breakOn s t
501+ in T.null m || s `T.isPrefixOf` m
502+tl_breakOn_start (NotEmpty s) t = let (_,m) = TL.breakOn s t
503+ in TL.null m || s `TL.isPrefixOf` m
504+t_breakOnEnd_end (NotEmpty s) t = let (m,_) = T.breakOnEnd s t
505+ in T.null m || s `T.isSuffixOf` m
506+tl_breakOnEnd_end (NotEmpty s) t = let (m,_) = TL.breakOnEnd s t
507+ in TL.null m || s `TL.isSuffixOf` m
508+t_break p = L.break p `eqP` (unpack2 . T.break p)
509+tl_break p = L.break p `eqP` (unpack2 . TL.break p)
510+t_group = L.group `eqP` (map unpackS . T.group)
511+tl_group = L.group `eqP` (map unpackS . TL.group)
512+t_groupBy p = L.groupBy p `eqP` (map unpackS . T.groupBy p)
513+tl_groupBy p = L.groupBy p `eqP` (map unpackS . TL.groupBy p)
514+t_inits = L.inits `eqP` (map unpackS . T.inits)
515+tl_inits = L.inits `eqP` (map unpackS . TL.inits)
516+t_tails = L.tails `eqP` (map unpackS . T.tails)
517+tl_tails = L.tails `eqP` (map unpackS . TL.tails)
518+t_findAppendId (NotEmpty s) = unsquare $ \ts ->
519+ let t = T.intercalate s ts
520+ in all (==t) $ map (uncurry T.append) (T.breakOnAll s t)
521+tl_findAppendId (NotEmpty s) = unsquare $ \ts ->
522+ let t = TL.intercalate s ts
523+ in all (==t) $ map (uncurry TL.append) (TL.breakOnAll s t)
524+t_findContains (NotEmpty s) = all (T.isPrefixOf s . snd) . T.breakOnAll s .
525+ T.intercalate s
526+tl_findContains (NotEmpty s) = all (TL.isPrefixOf s . snd) .
527+ TL.breakOnAll s . TL.intercalate s
528+sl_filterCount c = (L.genericLength . L.filter (==c)) `eqP` SL.countChar c
529+t_findCount s = (L.length . T.breakOnAll s) `eq` T.count s
530+tl_findCount s = (L.genericLength . TL.breakOnAll s) `eq` TL.count s
531+
532+t_splitOn_split s = (T.splitOn s `eq` Slow.splitOn s) . T.intercalate s
533+tl_splitOn_split s = ((TL.splitOn (TL.fromStrict s) . TL.fromStrict) `eq`
534+ (map TL.fromStrict . T.splitOn s)) . T.intercalate s
535+t_splitOn_i (NotEmpty t) = id `eq` (T.intercalate t . T.splitOn t)
536+tl_splitOn_i (NotEmpty t) = id `eq` (TL.intercalate t . TL.splitOn t)
537+
538+t_split p = split p `eqP` (map unpackS . T.split p)
539+t_split_count c = (L.length . T.split (==c)) `eq`
540+ ((1+) . T.count (T.singleton c))
541+t_split_splitOn c = T.split (==c) `eq` T.splitOn (T.singleton c)
542+tl_split p = split p `eqP` (map unpackS . TL.split p)
543+
544+split :: (a -> Bool) -> [a] -> [[a]]
545+split _ [] = [[]]
546+split p xs = loop xs
547+ where loop s | null s' = [l]
548+ | otherwise = l : loop (tail s')
549+ where (l, s') = break p s
550+
551+t_chunksOf_same_lengths k = all ((==k) . T.length) . ini . T.chunksOf k
552+ where ini [] = []
553+ ini xs = init xs
554+
555+t_chunksOf_length k t = len == T.length t || (k <= 0 && len == 0)
556+ where len = L.sum . L.map T.length $ T.chunksOf k t
557+
558+tl_chunksOf k = T.chunksOf k `eq` (map (T.concat . TL.toChunks) .
559+ TL.chunksOf (fromIntegral k) . TL.fromStrict)
560+
561+t_lines = L.lines `eqP` (map unpackS . T.lines)
562+tl_lines = L.lines `eqP` (map unpackS . TL.lines)
563+{-
564+t_lines' = lines' `eqP` (map unpackS . T.lines')
565+ where lines' "" = []
566+ lines' s = let (l, s') = break eol s
567+ in l : case s' of
568+ [] -> []
569+ ('\r':'\n':s'') -> lines' s''
570+ (_:s'') -> lines' s''
571+ eol c = c == '\r' || c == '\n'
572+-}
573+t_words = L.words `eqP` (map unpackS . T.words)
574+
575+tl_words = L.words `eqP` (map unpackS . TL.words)
576+t_unlines = L.unlines `eq` (unpackS . T.unlines . map packS)
577+tl_unlines = L.unlines `eq` (unpackS . TL.unlines . map packS)
578+t_unwords = L.unwords `eq` (unpackS . T.unwords . map packS)
579+tl_unwords = L.unwords `eq` (unpackS . TL.unwords . map packS)
580+
581+s_isPrefixOf s = L.isPrefixOf s `eqP`
582+ (S.isPrefixOf (S.stream $ packS s) . S.stream)
583+sf_isPrefixOf p s = (L.isPrefixOf s . L.filter p) `eqP`
584+ (S.isPrefixOf (S.stream $ packS s) . S.filter p . S.stream)
585+t_isPrefixOf s = L.isPrefixOf s`eqP` T.isPrefixOf (packS s)
586+tl_isPrefixOf s = L.isPrefixOf s`eqP` TL.isPrefixOf (packS s)
587+t_isSuffixOf s = L.isSuffixOf s`eqP` T.isSuffixOf (packS s)
588+tl_isSuffixOf s = L.isSuffixOf s`eqP` TL.isSuffixOf (packS s)
589+t_isInfixOf s = L.isInfixOf s `eqP` T.isInfixOf (packS s)
590+tl_isInfixOf s = L.isInfixOf s `eqP` TL.isInfixOf (packS s)
591+
592+t_stripPrefix s = (fmap packS . L.stripPrefix s) `eqP` T.stripPrefix (packS s)
593+tl_stripPrefix s = (fmap packS . L.stripPrefix s) `eqP` TL.stripPrefix (packS s)
594+
595+stripSuffix p t = reverse `fmap` L.stripPrefix (reverse p) (reverse t)
596+
597+t_stripSuffix s = (fmap packS . stripSuffix s) `eqP` T.stripSuffix (packS s)
598+tl_stripSuffix s = (fmap packS . stripSuffix s) `eqP` TL.stripSuffix (packS s)
599+
600+commonPrefixes a0@(_:_) b0@(_:_) = Just (go a0 b0 [])
601+ where go (a:as) (b:bs) ps
602+ | a == b = go as bs (a:ps)
603+ go as bs ps = (reverse ps,as,bs)
604+commonPrefixes _ _ = Nothing
605+
606+t_commonPrefixes a b (NonEmpty p)
607+ = commonPrefixes pa pb ==
608+ repack `fmap` T.commonPrefixes (packS pa) (packS pb)
609+ where repack (x,y,z) = (unpackS x,unpackS y,unpackS z)
610+ pa = p ++ a
611+ pb = p ++ b
612+
613+tl_commonPrefixes a b (NonEmpty p)
614+ = commonPrefixes pa pb ==
615+ repack `fmap` TL.commonPrefixes (packS pa) (packS pb)
616+ where repack (x,y,z) = (unpackS x,unpackS y,unpackS z)
617+ pa = p ++ a
618+ pb = p ++ b
619+
620+sf_elem p c = (L.elem c . L.filter p) `eqP` (S.elem c . S.filter p)
621+sf_filter q p = (L.filter p . L.filter q) `eqP`
622+ (unpackS . S.filter p . S.filter q)
623+t_filter p = L.filter p `eqP` (unpackS . T.filter p)
624+tl_filter p = L.filter p `eqP` (unpackS . TL.filter p)
625+sf_findBy q p = (L.find p . L.filter q) `eqP` (S.findBy p . S.filter q)
626+t_find p = L.find p `eqP` T.find p
627+tl_find p = L.find p `eqP` TL.find p
628+t_partition p = L.partition p `eqP` (unpack2 . T.partition p)
629+tl_partition p = L.partition p `eqP` (unpack2 . TL.partition p)
630+
631+sf_index p s = forAll (choose (-l,l*2))
632+ ((L.filter p s L.!!) `eq` S.index (S.filter p $ packS s))
633+ where l = L.length s
634+t_index s = forAll (choose (-l,l*2)) ((s L.!!) `eq` T.index (packS s))
635+ where l = L.length s
636+
637+tl_index s = forAll (choose (-l,l*2))
638+ ((s L.!!) `eq` (TL.index (packS s) . fromIntegral))
639+ where l = L.length s
640+
641+t_findIndex p = L.findIndex p `eqP` T.findIndex p
642+t_count (NotEmpty t) = (subtract 1 . L.length . T.splitOn t) `eq` T.count t
643+tl_count (NotEmpty t) = (subtract 1 . L.genericLength . TL.splitOn t) `eq`
644+ TL.count t
645+t_zip s = L.zip s `eqP` T.zip (packS s)
646+tl_zip s = L.zip s `eqP` TL.zip (packS s)
647+sf_zipWith p c s = (L.zipWith c (L.filter p s) . L.filter p) `eqP`
648+ (unpackS . S.zipWith c (S.filter p $ packS s) . S.filter p)
649+t_zipWith c s = L.zipWith c s `eqP` (unpackS . T.zipWith c (packS s))
650+tl_zipWith c s = L.zipWith c s `eqP` (unpackS . TL.zipWith c (packS s))
651+
652+t_indices (NotEmpty s) = Slow.indices s `eq` indices s
653+tl_indices (NotEmpty s) = lazyIndices s `eq` S.indices s
654+ where lazyIndices ss t = map fromIntegral $ Slow.indices (conc ss) (conc t)
655+ conc = T.concat . TL.toChunks
656+t_indices_occurs (NotEmpty t) ts = let s = T.intercalate t ts
657+ in Slow.indices t s == indices t s
658+
659+-- Bit shifts.
660+shiftL w = forAll (choose (0,width-1)) $ \k -> Bits.shiftL w k == U.shiftL w k
661+ where width = round (log (fromIntegral m) / log 2 :: Double)
662+ (m,_) = (maxBound, m == w)
663+shiftR w = forAll (choose (0,width-1)) $ \k -> Bits.shiftR w k == U.shiftR w k
664+ where width = round (log (fromIntegral m) / log 2 :: Double)
665+ (m,_) = (maxBound, m == w)
666+
667+shiftL_Int = shiftL :: Int -> Property
668+shiftL_Word16 = shiftL :: Word16 -> Property
669+shiftL_Word32 = shiftL :: Word32 -> Property
670+shiftR_Int = shiftR :: Int -> Property
671+shiftR_Word16 = shiftR :: Word16 -> Property
672+shiftR_Word32 = shiftR :: Word32 -> Property
673+
674+-- Builder.
675+
676+t_builderSingleton = id `eqP`
677+ (unpackS . TB.toLazyText . mconcat . map TB.singleton)
678+t_builderFromText = L.concat `eq` (unpackS . TB.toLazyText . mconcat .
679+ map (TB.fromText . packS))
680+t_builderAssociative s1 s2 s3 =
681+ TB.toLazyText (b1 `mappend` (b2 `mappend` b3)) ==
682+ TB.toLazyText ((b1 `mappend` b2) `mappend` b3)
683+ where b1 = TB.fromText (packS s1)
684+ b2 = TB.fromText (packS s2)
685+ b3 = TB.fromText (packS s3)
686+
687+-- Reading.
688+
689+t_decimal (n::Int) s =
690+ T.signed T.decimal (T.pack (show n) `T.append` t) == Right (n,t)
691+ where t = T.dropWhile isDigit s
692+tl_decimal (n::Int) s =
693+ TL.signed TL.decimal (TL.pack (show n) `TL.append` t) == Right (n,t)
694+ where t = TL.dropWhile isDigit s
695+t_hexadecimal (n::Positive Int) s ox =
696+ T.hexadecimal (T.concat [p, T.pack (showHex n ""), t]) == Right (n,t)
697+ where t = T.dropWhile isHexDigit s
698+ p = if ox then "0x" else ""
699+tl_hexadecimal (n::Positive Int) s ox =
700+ TL.hexadecimal (TL.concat [p, TL.pack (showHex n ""), t]) == Right (n,t)
701+ where t = TL.dropWhile isHexDigit s
702+ p = if ox then "0x" else ""
703+
704+isFloaty c = c `elem` "+-.0123456789eE"
705+
706+t_read_rational p tol (n::Double) s =
707+ case p (T.pack (show n) `T.append` t) of
708+ Left _err -> False
709+ Right (n',t') -> t == t' && abs (n-n') <= tol
710+ where t = T.dropWhile isFloaty s
711+
712+tl_read_rational p tol (n::Double) s =
713+ case p (TL.pack (show n) `TL.append` t) of
714+ Left _err -> False
715+ Right (n',t') -> t == t' && abs (n-n') <= tol
716+ where t = TL.dropWhile isFloaty s
717+
718+t_double = t_read_rational T.double 1e-13
719+tl_double = tl_read_rational TL.double 1e-13
720+t_rational = t_read_rational T.rational 1e-16
721+tl_rational = tl_read_rational TL.rational 1e-16
722+
723+-- Input and output.
724+
725+-- Work around lack of Show instance for TextEncoding.
726+data Encoding = E String TextEncoding
727+
728+instance Show Encoding where show (E n _) = "utf" ++ n
729+
730+instance Arbitrary Encoding where
731+ arbitrary = oneof . map return $
732+ [ E "8" utf8, E "8_bom" utf8_bom, E "16" utf16, E "16le" utf16le,
733+ E "16be" utf16be, E "32" utf32, E "32le" utf32le, E "32be" utf32be ]
734+
735+windowsNewlineMode = NewlineMode { inputNL = CRLF, outputNL = CRLF }
736+
737+-- Newline and NewlineMode have standard Show instance from GHC 7 onwards
738+#if __GLASGOW_HASKELL__ < 700
739+instance Show Newline where
740+ show CRLF = "CRLF"
741+ show LF = "LF"
742+
743+instance Show NewlineMode where
744+ show (NewlineMode i o) = "NewlineMode { inputNL = " ++ show i ++
745+ ", outputNL = " ++ show o ++ " }"
746+# endif
747+
748+instance Arbitrary NewlineMode where
749+ arbitrary = oneof . map return $
750+ [ noNewlineTranslation, universalNewlineMode, nativeNewlineMode,
751+ windowsNewlineMode ]
752+
753+instance Arbitrary BufferMode where
754+ arbitrary = oneof [ return NoBuffering,
755+ return LineBuffering,
756+ return (BlockBuffering Nothing),
757+ (BlockBuffering . Just . (+1) . fromIntegral) `fmap`
758+ (arbitrary :: Gen Word16) ]
759+
760+-- This test harness is complex! What property are we checking?
761+--
762+-- Reading after writing a multi-line file should give the same
763+-- results as were written.
764+--
765+-- What do we vary while checking this property?
766+-- * The lines themselves, scrubbed to contain neither CR nor LF. (By
767+-- working with a list of lines, we ensure that the data will
768+-- sometimes contain line endings.)
769+-- * Encoding.
770+-- * Newline translation mode.
771+-- * Buffering.
772+write_read unline filt writer reader (E _ enc) nl buf ts =
773+ monadicIO $ assert . (==t) =<< run act
774+ where t = unline . map (filt (not . (`elem` "\r\n"))) $ ts
775+ act = withTempFile $ \path h -> do
776+ -- hSetEncoding h enc
777+ hSetNewlineMode h nl
778+ hSetBuffering h buf
779+ () <- writer h t
780+ hClose h
781+ bracket (openFile path ReadMode) hClose $ \h' -> do
782+ -- hSetEncoding h' enc
783+ hSetNewlineMode h' nl
784+ hSetBuffering h' buf
785+ r <- reader h'
786+ r `deepseq` return r
787+
788+t_put_get = write_read T.unlines T.filter put get
789+ where put h = withRedirect h stdout . T.putStr
790+ get h = withRedirect h stdin T.getContents
791+tl_put_get = write_read TL.unlines TL.filter put get
792+ where put h = withRedirect h stdout . TL.putStr
793+ get h = withRedirect h stdin TL.getContents
794+t_write_read = write_read T.unlines T.filter T.hPutStr T.hGetContents
795+tl_write_read = write_read TL.unlines TL.filter TL.hPutStr TL.hGetContents
796+
797+t_write_read_line e m b t = write_read head T.filter T.hPutStrLn
798+ T.hGetLine e m b [t]
799+tl_write_read_line e m b t = write_read head TL.filter TL.hPutStrLn
800+ TL.hGetLine e m b [t]
801+
802+-- Low-level.
803+
804+t_dropWord16 m t = dropWord16 m t `T.isSuffixOf` t
805+t_takeWord16 m t = takeWord16 m t `T.isPrefixOf` t
806+t_take_drop_16 m t = T.append (takeWord16 n t) (dropWord16 n t) == t
807+ where n = small m
808+t_use_from t = monadicIO $ assert . (==t) =<< run (useAsPtr t fromPtr)
809+
810+-- Regression tests.
811+s_filter_eq s = S.filter p t == S.streamList (filter p s)
812+ where p = (/= S.last t)
813+ t = S.streamList s
814+
815+-- Make a stream appear shorter than it really is, to ensure that
816+-- functions that consume inaccurately sized streams behave
817+-- themselves.
818+shorten :: Int -> S.Stream a -> S.Stream a
819+shorten n t@(S.Stream arr off len)
820+ | n > 0 = S.Stream arr off (smaller (exactSize n) len)
821+ | otherwise = t
822+
823+main :: IO ()
824+main = defaultMain tests
825+
826+tests :: [Test]
827+tests = [
828+ testGroup "creation/elimination" [
829+ testProperty "t_pack_unpack" t_pack_unpack,
830+ testProperty "tl_pack_unpack" tl_pack_unpack,
831+ testProperty "t_stream_unstream" t_stream_unstream,
832+ testProperty "tl_stream_unstream" tl_stream_unstream,
833+ testProperty "t_reverse_stream" t_reverse_stream,
834+ testProperty "t_singleton" t_singleton,
835+ testProperty "tl_singleton" tl_singleton,
836+ testProperty "tl_unstreamChunks" tl_unstreamChunks,
837+ testProperty "tl_chunk_unchunk" tl_chunk_unchunk,
838+ testProperty "tl_from_to_strict" tl_from_to_strict
839+ ],
840+
841+ testGroup "transcoding" [
842+ testProperty "t_ascii" t_ascii,
843+ testProperty "tl_ascii" tl_ascii,
844+ testProperty "t_utf8" t_utf8,
845+ testProperty "t_utf8'" t_utf8',
846+ testProperty "tl_utf8" tl_utf8,
847+ testProperty "tl_utf8'" tl_utf8',
848+ testProperty "t_utf16LE" t_utf16LE,
849+ testProperty "tl_utf16LE" tl_utf16LE,
850+ testProperty "t_utf16BE" t_utf16BE,
851+ testProperty "tl_utf16BE" tl_utf16BE,
852+ testProperty "t_utf32LE" t_utf32LE,
853+ testProperty "tl_utf32LE" tl_utf32LE,
854+ testProperty "t_utf32BE" t_utf32BE,
855+ testProperty "tl_utf32BE" tl_utf32BE,
856+ testGroup "errors" [
857+ testProperty "t_utf8_err" t_utf8_err,
858+ testProperty "t_utf8_err'" t_utf8_err'
859+ ]
860+ ],
861+
862+ testGroup "instances" [
863+ testProperty "s_Eq" s_Eq,
864+ testProperty "sf_Eq" sf_Eq,
865+ testProperty "t_Eq" t_Eq,
866+ testProperty "tl_Eq" tl_Eq,
867+ testProperty "s_Ord" s_Ord,
868+ testProperty "sf_Ord" sf_Ord,
869+ testProperty "t_Ord" t_Ord,
870+ testProperty "tl_Ord" tl_Ord,
871+ testProperty "t_Read" t_Read,
872+ testProperty "tl_Read" tl_Read,
873+ testProperty "t_Show" t_Show,
874+ testProperty "tl_Show" tl_Show,
875+ testProperty "t_mappend" t_mappend,
876+ testProperty "tl_mappend" tl_mappend,
877+ testProperty "t_mconcat" t_mconcat,
878+ testProperty "tl_mconcat" tl_mconcat,
879+ testProperty "t_mempty" t_mempty,
880+ testProperty "tl_mempty" tl_mempty,
881+ testProperty "t_IsString" t_IsString,
882+ testProperty "tl_IsString" tl_IsString
883+ ],
884+
885+ testGroup "basics" [
886+ testProperty "s_cons" s_cons,
887+ testProperty "s_cons_s" s_cons_s,
888+ testProperty "sf_cons" sf_cons,
889+ testProperty "t_cons" t_cons,
890+ testProperty "tl_cons" tl_cons,
891+ testProperty "s_snoc" s_snoc,
892+ testProperty "t_snoc" t_snoc,
893+ testProperty "tl_snoc" tl_snoc,
894+ testProperty "s_append" s_append,
895+ testProperty "s_append_s" s_append_s,
896+ testProperty "sf_append" sf_append,
897+ testProperty "t_append" t_append,
898+ testProperty "s_uncons" s_uncons,
899+ testProperty "sf_uncons" sf_uncons,
900+ testProperty "t_uncons" t_uncons,
901+ testProperty "tl_uncons" tl_uncons,
902+ testProperty "s_head" s_head,
903+ testProperty "sf_head" sf_head,
904+ testProperty "t_head" t_head,
905+ testProperty "tl_head" tl_head,
906+ testProperty "s_last" s_last,
907+ testProperty "sf_last" sf_last,
908+ testProperty "t_last" t_last,
909+ testProperty "tl_last" tl_last,
910+ testProperty "s_tail" s_tail,
911+ testProperty "s_tail_s" s_tail_s,
912+ testProperty "sf_tail" sf_tail,
913+ testProperty "t_tail" t_tail,
914+ testProperty "tl_tail" tl_tail,
915+ testProperty "s_init" s_init,
916+ testProperty "s_init_s" s_init_s,
917+ testProperty "sf_init" sf_init,
918+ testProperty "t_init" t_init,
919+ testProperty "tl_init" tl_init,
920+ testProperty "s_null" s_null,
921+ testProperty "sf_null" sf_null,
922+ testProperty "t_null" t_null,
923+ testProperty "tl_null" tl_null,
924+ testProperty "s_length" s_length,
925+ testProperty "sf_length" sf_length,
926+ testProperty "sl_length" sl_length,
927+ testProperty "t_length" t_length,
928+ testProperty "tl_length" tl_length,
929+ testProperty "t_compareLength" t_compareLength,
930+ testProperty "tl_compareLength" tl_compareLength
931+ ],
932+
933+ testGroup "transformations" [
934+ testProperty "s_map" s_map,
935+ testProperty "s_map_s" s_map_s,
936+ testProperty "sf_map" sf_map,
937+ testProperty "t_map" t_map,
938+ testProperty "tl_map" tl_map,
939+ testProperty "t_intercalate" t_intercalate,
940+ testProperty "tl_intercalate" tl_intercalate,
941+ testProperty "s_intersperse" s_intersperse,
942+ testProperty "s_intersperse_s" s_intersperse_s,
943+ testProperty "sf_intersperse" sf_intersperse,
944+ testProperty "t_intersperse" t_intersperse,
945+ testProperty "tl_intersperse" tl_intersperse,
946+ testProperty "t_transpose" t_transpose,
947+ testProperty "tl_transpose" tl_transpose,
948+ testProperty "t_reverse" t_reverse,
949+ testProperty "tl_reverse" tl_reverse,
950+ testProperty "t_reverse_short" t_reverse_short,
951+ testProperty "t_replace" t_replace,
952+ testProperty "tl_replace" tl_replace,
953+
954+ testGroup "case conversion" [
955+ testProperty "s_toCaseFold_length" s_toCaseFold_length,
956+ testProperty "sf_toCaseFold_length" sf_toCaseFold_length,
957+ testProperty "t_toCaseFold_length" t_toCaseFold_length,
958+ testProperty "tl_toCaseFold_length" tl_toCaseFold_length,
959+ testProperty "t_toLower_length" t_toLower_length,
960+ testProperty "t_toLower_lower" t_toLower_lower,
961+ testProperty "tl_toLower_lower" tl_toLower_lower,
962+ testProperty "t_toUpper_length" t_toUpper_length,
963+ testProperty "t_toUpper_upper" t_toUpper_upper,
964+ testProperty "tl_toUpper_upper" tl_toUpper_upper
965+ ],
966+
967+ testGroup "justification" [
968+ testProperty "s_justifyLeft" s_justifyLeft,
969+ testProperty "s_justifyLeft_s" s_justifyLeft_s,
970+ testProperty "sf_justifyLeft" sf_justifyLeft,
971+ testProperty "t_justifyLeft" t_justifyLeft,
972+ testProperty "tl_justifyLeft" tl_justifyLeft,
973+ testProperty "t_justifyRight" t_justifyRight,
974+ testProperty "tl_justifyRight" tl_justifyRight,
975+ testProperty "t_center" t_center,
976+ testProperty "tl_center" tl_center
977+ ]
978+ ],
979+
980+ testGroup "folds" [
981+ testProperty "sf_foldl" sf_foldl,
982+ testProperty "t_foldl" t_foldl,
983+ testProperty "tl_foldl" tl_foldl,
984+ testProperty "sf_foldl'" sf_foldl',
985+ testProperty "t_foldl'" t_foldl',
986+ testProperty "tl_foldl'" tl_foldl',
987+ testProperty "sf_foldl1" sf_foldl1,
988+ testProperty "t_foldl1" t_foldl1,
989+ testProperty "tl_foldl1" tl_foldl1,
990+ testProperty "t_foldl1'" t_foldl1',
991+ testProperty "sf_foldl1'" sf_foldl1',
992+ testProperty "tl_foldl1'" tl_foldl1',
993+ testProperty "sf_foldr" sf_foldr,
994+ testProperty "t_foldr" t_foldr,
995+ testProperty "tl_foldr" tl_foldr,
996+ testProperty "sf_foldr1" sf_foldr1,
997+ testProperty "t_foldr1" t_foldr1,
998+ testProperty "tl_foldr1" tl_foldr1,
999+
1000+ testGroup "special" [
1001+ testProperty "s_concat_s" s_concat_s,
1002+ testProperty "sf_concat" sf_concat,
1003+ testProperty "t_concat" t_concat,
1004+ testProperty "tl_concat" tl_concat,
1005+ testProperty "sf_concatMap" sf_concatMap,
1006+ testProperty "t_concatMap" t_concatMap,
1007+ testProperty "tl_concatMap" tl_concatMap,
1008+ testProperty "sf_any" sf_any,
1009+ testProperty "t_any" t_any,
1010+ testProperty "tl_any" tl_any,
1011+ testProperty "sf_all" sf_all,
1012+ testProperty "t_all" t_all,
1013+ testProperty "tl_all" tl_all,
1014+ testProperty "sf_maximum" sf_maximum,
1015+ testProperty "t_maximum" t_maximum,
1016+ testProperty "tl_maximum" tl_maximum,
1017+ testProperty "sf_minimum" sf_minimum,
1018+ testProperty "t_minimum" t_minimum,
1019+ testProperty "tl_minimum" tl_minimum
1020+ ]
1021+ ],
1022+
1023+ testGroup "construction" [
1024+ testGroup "scans" [
1025+ testProperty "sf_scanl" sf_scanl,
1026+ testProperty "t_scanl" t_scanl,
1027+ testProperty "tl_scanl" tl_scanl,
1028+ testProperty "t_scanl1" t_scanl1,
1029+ testProperty "tl_scanl1" tl_scanl1,
1030+ testProperty "t_scanr" t_scanr,
1031+ testProperty "tl_scanr" tl_scanr,
1032+ testProperty "t_scanr1" t_scanr1,
1033+ testProperty "tl_scanr1" tl_scanr1
1034+ ],
1035+
1036+ testGroup "mapAccum" [
1037+ testProperty "t_mapAccumL" t_mapAccumL,
1038+ testProperty "tl_mapAccumL" tl_mapAccumL,
1039+ testProperty "t_mapAccumR" t_mapAccumR,
1040+ testProperty "tl_mapAccumR" tl_mapAccumR
1041+ ],
1042+
1043+ testGroup "unfolds" [
1044+ testProperty "t_replicate" t_replicate,
1045+ testProperty "tl_replicate" tl_replicate,
1046+ testProperty "t_unfoldr" t_unfoldr,
1047+ testProperty "tl_unfoldr" tl_unfoldr,
1048+ testProperty "t_unfoldrN" t_unfoldrN,
1049+ testProperty "tl_unfoldrN" tl_unfoldrN
1050+ ]
1051+ ],
1052+
1053+ testGroup "substrings" [
1054+ testGroup "breaking" [
1055+ testProperty "s_take" s_take,
1056+ testProperty "s_take_s" s_take_s,
1057+ testProperty "sf_take" sf_take,
1058+ testProperty "t_take" t_take,
1059+ testProperty "tl_take" tl_take,
1060+ testProperty "s_drop" s_drop,
1061+ testProperty "s_drop_s" s_drop_s,
1062+ testProperty "sf_drop" sf_drop,
1063+ testProperty "t_drop" t_drop,
1064+ testProperty "tl_drop" tl_drop,
1065+ testProperty "s_take_drop" s_take_drop,
1066+ testProperty "s_take_drop_s" s_take_drop_s,
1067+ testProperty "s_takeWhile" s_takeWhile,
1068+ testProperty "s_takeWhile_s" s_takeWhile_s,
1069+ testProperty "sf_takeWhile" sf_takeWhile,
1070+ testProperty "t_takeWhile" t_takeWhile,
1071+ testProperty "tl_takeWhile" tl_takeWhile,
1072+ testProperty "sf_dropWhile" sf_dropWhile,
1073+ testProperty "s_dropWhile" s_dropWhile,
1074+ testProperty "s_dropWhile_s" s_dropWhile_s,
1075+ testProperty "t_dropWhile" t_dropWhile,
1076+ testProperty "tl_dropWhile" tl_dropWhile,
1077+ testProperty "t_dropWhileEnd" t_dropWhileEnd,
1078+ testProperty "tl_dropWhileEnd" tl_dropWhileEnd,
1079+ testProperty "t_dropAround" t_dropAround,
1080+ testProperty "tl_dropAround" tl_dropAround,
1081+ testProperty "t_stripStart" t_stripStart,
1082+ testProperty "tl_stripStart" tl_stripStart,
1083+ testProperty "t_stripEnd" t_stripEnd,
1084+ testProperty "tl_stripEnd" tl_stripEnd,
1085+ testProperty "t_strip" t_strip,
1086+ testProperty "tl_strip" tl_strip,
1087+ testProperty "t_splitAt" t_splitAt,
1088+ testProperty "tl_splitAt" tl_splitAt,
1089+ testProperty "t_span" t_span,
1090+ testProperty "tl_span" tl_span,
1091+ testProperty "t_breakOn_id" t_breakOn_id,
1092+ testProperty "tl_breakOn_id" tl_breakOn_id,
1093+ testProperty "t_breakOn_start" t_breakOn_start,
1094+ testProperty "tl_breakOn_start" tl_breakOn_start,
1095+ testProperty "t_breakOnEnd_end" t_breakOnEnd_end,
1096+ testProperty "tl_breakOnEnd_end" tl_breakOnEnd_end,
1097+ testProperty "t_break" t_break,
1098+ testProperty "tl_break" tl_break,
1099+ testProperty "t_group" t_group,
1100+ testProperty "tl_group" tl_group,
1101+ testProperty "t_groupBy" t_groupBy,
1102+ testProperty "tl_groupBy" tl_groupBy,
1103+ testProperty "t_inits" t_inits,
1104+ testProperty "tl_inits" tl_inits,
1105+ testProperty "t_tails" t_tails,
1106+ testProperty "tl_tails" tl_tails
1107+ ],
1108+
1109+ testGroup "breaking many" [
1110+ testProperty "t_findAppendId" t_findAppendId,
1111+ testProperty "tl_findAppendId" tl_findAppendId,
1112+ testProperty "t_findContains" t_findContains,
1113+ testProperty "tl_findContains" tl_findContains,
1114+ testProperty "sl_filterCount" sl_filterCount,
1115+ testProperty "t_findCount" t_findCount,
1116+ testProperty "tl_findCount" tl_findCount,
1117+ testProperty "t_splitOn_split" t_splitOn_split,
1118+ testProperty "tl_splitOn_split" tl_splitOn_split,
1119+ testProperty "t_splitOn_i" t_splitOn_i,
1120+ testProperty "tl_splitOn_i" tl_splitOn_i,
1121+ testProperty "t_split" t_split,
1122+ testProperty "t_split_count" t_split_count,
1123+ testProperty "t_split_splitOn" t_split_splitOn,
1124+ testProperty "tl_split" tl_split,
1125+ testProperty "t_chunksOf_same_lengths" t_chunksOf_same_lengths,
1126+ testProperty "t_chunksOf_length" t_chunksOf_length,
1127+ testProperty "tl_chunksOf" tl_chunksOf
1128+ ],
1129+
1130+ testGroup "lines and words" [
1131+ testProperty "t_lines" t_lines,
1132+ testProperty "tl_lines" tl_lines,
1133+ --testProperty "t_lines'" t_lines',
1134+ testProperty "t_words" t_words,
1135+ testProperty "tl_words" tl_words,
1136+ testProperty "t_unlines" t_unlines,
1137+ testProperty "tl_unlines" tl_unlines,
1138+ testProperty "t_unwords" t_unwords,
1139+ testProperty "tl_unwords" tl_unwords
1140+ ]
1141+ ],
1142+
1143+ testGroup "predicates" [
1144+ testProperty "s_isPrefixOf" s_isPrefixOf,
1145+ testProperty "sf_isPrefixOf" sf_isPrefixOf,
1146+ testProperty "t_isPrefixOf" t_isPrefixOf,
1147+ testProperty "tl_isPrefixOf" tl_isPrefixOf,
1148+ testProperty "t_isSuffixOf" t_isSuffixOf,
1149+ testProperty "tl_isSuffixOf" tl_isSuffixOf,
1150+ testProperty "t_isInfixOf" t_isInfixOf,
1151+ testProperty "tl_isInfixOf" tl_isInfixOf,
1152+
1153+ testGroup "view" [
1154+ testProperty "t_stripPrefix" t_stripPrefix,
1155+ testProperty "tl_stripPrefix" tl_stripPrefix,
1156+ testProperty "t_stripSuffix" t_stripSuffix,
1157+ testProperty "tl_stripSuffix" tl_stripSuffix,
1158+ testProperty "t_commonPrefixes" t_commonPrefixes,
1159+ testProperty "tl_commonPrefixes" tl_commonPrefixes
1160+ ]
1161+ ],
1162+
1163+ testGroup "searching" [
1164+ testProperty "sf_elem" sf_elem,
1165+ testProperty "sf_filter" sf_filter,
1166+ testProperty "t_filter" t_filter,
1167+ testProperty "tl_filter" tl_filter,
1168+ testProperty "sf_findBy" sf_findBy,
1169+ testProperty "t_find" t_find,
1170+ testProperty "tl_find" tl_find,
1171+ testProperty "t_partition" t_partition,
1172+ testProperty "tl_partition" tl_partition
1173+ ],
1174+
1175+ testGroup "indexing" [
1176+ testProperty "sf_index" sf_index,
1177+ testProperty "t_index" t_index,
1178+ testProperty "tl_index" tl_index,
1179+ testProperty "t_findIndex" t_findIndex,
1180+ testProperty "t_count" t_count,
1181+ testProperty "tl_count" tl_count,
1182+ testProperty "t_indices" t_indices,
1183+ testProperty "tl_indices" tl_indices,
1184+ testProperty "t_indices_occurs" t_indices_occurs
1185+ ],
1186+
1187+ testGroup "zips" [
1188+ testProperty "t_zip" t_zip,
1189+ testProperty "tl_zip" tl_zip,
1190+ testProperty "sf_zipWith" sf_zipWith,
1191+ testProperty "t_zipWith" t_zipWith,
1192+ testProperty "tl_zipWith" tl_zipWith
1193+ ],
1194+
1195+ testGroup "regressions" [
1196+ testProperty "s_filter_eq" s_filter_eq
1197+ ],
1198+
1199+ testGroup "shifts" [
1200+ testProperty "shiftL_Int" shiftL_Int,
1201+ testProperty "shiftL_Word16" shiftL_Word16,
1202+ testProperty "shiftL_Word32" shiftL_Word32,
1203+ testProperty "shiftR_Int" shiftR_Int,
1204+ testProperty "shiftR_Word16" shiftR_Word16,
1205+ testProperty "shiftR_Word32" shiftR_Word32
1206+ ],
1207+
1208+ testGroup "builder" [
1209+ testProperty "t_builderSingleton" t_builderSingleton,
1210+ testProperty "t_builderFromText" t_builderFromText,
1211+ testProperty "t_builderAssociative" t_builderAssociative
1212+ ],
1213+
1214+ testGroup "read" [
1215+ testProperty "t_decimal" t_decimal,
1216+ testProperty "tl_decimal" tl_decimal,
1217+ testProperty "t_hexadecimal" t_hexadecimal,
1218+ testProperty "tl_hexadecimal" tl_hexadecimal,
1219+ testProperty "t_double" t_double,
1220+ testProperty "tl_double" tl_double,
1221+ testProperty "t_rational" t_rational,
1222+ testProperty "tl_rational" tl_rational
1223+ ],
1224+
1225+ testGroup "input-output" [
1226+ testProperty "t_write_read" t_write_read,
1227+ testProperty "tl_write_read" tl_write_read,
1228+ testProperty "t_write_read_line" t_write_read_line,
1229+ testProperty "tl_write_read_line" tl_write_read_line
1230+ -- These tests are subject to I/O race conditions when run under
1231+ -- test-framework-quickcheck2.
1232+ -- testProperty "t_put_get" t_put_get
1233+ -- testProperty "tl_put_get" tl_put_get
1234+ ],
1235+
1236+ testGroup "lowlevel" [
1237+ testProperty "t_dropWord16" t_dropWord16,
1238+ testProperty "t_takeWord16" t_takeWord16,
1239+ testProperty "t_take_drop_16" t_take_drop_16,
1240+ testProperty "t_use_from" t_use_from
1241+ ]
1242+ ]