1 {-#LANGUAGE ScopedTypeVariables#-}
3 import Control.Exception (SomeException, bracket, bracket_, evaluate, try)
4 import System.IO.Unsafe (unsafePerformIO)
5 import Debug.Trace (trace)
6 import Data.Bits ((.&.))
8 import Data.String (IsString, fromString)
9 import System.Random (Random (..), RandomGen)
10 import Test.QuickCheck hiding ((.&.))
11 import Test.QuickCheck.Monadic (assert, monadicIO, run)
12 import qualified Data.ByteString as B
13 import Pipes.Text.Internal
19 -- Ensure that two potentially bottom values (in the sense of crashing
20 -- for some inputs, not looping infinitely) either both crash, or both
21 -- give comparable results for some input.
22 (=^=) :: (Eq a, Show a) => a -> a -> Bool
23 i =^= j = unsafePerformIO $ do
27 (Left (_ :: SomeException), Left (_ :: SomeException))
29 (Right a, Right b) -> return (a == b)
30 e -> trace ("*** Divergence: " ++ show e) return False
32 {-# NOINLINE (=^=) #-}
34 -- Do two functions give the same answer?
35 eq :: (Eq a, Show a) => (t -> a) -> (t -> a) -> t -> Bool
36 eq a b s = a s =^= b s
38 -- What about with the RHS packed?
39 -- eqP :: (Eq a, Show a, Stringy s) =>
40 -- (String -> a) -> (s -> a) -> String -> Word8 -> Bool
41 -- eqP f g s w = eql "orig" (f s) (g t) &&
42 -- eql "mini" (f s) (g mini) &&
43 -- eql "head" (f sa) (g ta) &&
44 -- eql "tail" (f sb) (g tb)
46 -- mini = packSChunkSize 10 s
47 -- (sa,sb) = splitAt m s
48 -- (ta,tb) = splitAtS m t
51 -- | otherwise = n `mod` l
55 -- | otherwise = trace (d ++ ": " ++ show a ++ " /= " ++ show b) False
58 instance Arbitrary B.ByteString where
59 arbitrary = B.pack `fmap` arbitrary
61 genUnicode :: IsString a => Gen a
62 genUnicode = fmap fromString string where
63 string = sized $ \n ->
65 sequence [ char | _ <- [1..k] ]
67 excluding :: [a -> Bool] -> Gen a -> Gen a
68 excluding bad gen = loop
76 reserved = [lowSurrogate, highSurrogate, noncharacter]
77 lowSurrogate c = c >= 0xDC00 && c <= 0xDFFF
78 highSurrogate c = c >= 0xD800 && c <= 0xDBFF
79 noncharacter c = masked == 0xFFFE || masked == 0xFFFF
83 ascii = choose (0,0x7F)
84 plane0 = choose (0xF0, 0xFFFF)
85 plane1 = oneof [ choose (0x10000, 0x10FFF)
86 , choose (0x11000, 0x11FFF)
87 , choose (0x12000, 0x12FFF)
88 , choose (0x13000, 0x13FFF)
89 , choose (0x1D000, 0x1DFFF)
90 , choose (0x1F000, 0x1FFFF)
92 plane2 = oneof [ choose (0x20000, 0x20FFF)
93 , choose (0x21000, 0x21FFF)
94 , choose (0x22000, 0x22FFF)
95 , choose (0x23000, 0x23FFF)
96 , choose (0x24000, 0x24FFF)
97 , choose (0x25000, 0x25FFF)
98 , choose (0x26000, 0x26FFF)
99 , choose (0x27000, 0x27FFF)
100 , choose (0x28000, 0x28FFF)
101 , choose (0x29000, 0x29FFF)
102 , choose (0x2A000, 0x2AFFF)
103 , choose (0x2B000, 0x2BFFF)
104 , choose (0x2F000, 0x2FFFF)
106 plane14 = choose (0xE0000, 0xE0FFF)
107 planes = [ascii, plane0, plane1, plane2, plane14]
109 char = chr `fmap` excluding reserved (oneof planes)