@@ -3,12 +3,15 @@
3module QuickCheckUtils where
3module QuickCheckUtils where
5import Control.Arrow (first)
5import Control.Arrow (first)
7+import Data.Bits ((.&.))
6import Data.Int (Int64)
8import Data.Int (Int64)
7import Data.Word (Word8, Word16, Word32)
9import Data.Word (Word8, Word16, Word32)
10+import Data.String (IsString, fromString)
8import qualified Data.Text as T
11import qualified Data.Text as T
9import qualified Data.Text.Lazy as TL
12import qualified Data.Text.Lazy as TL
10import System.Random (Random(..), RandomGen)
13import System.Random (Random(..), RandomGen)
11−import Test.QuickCheck (Arbitrary(..), choose, sized, vector)
14+import Test.QuickCheck (Gen, Arbitrary(..), choose, sized, vector, oneof)
12import qualified Data.ByteString as B
15import qualified Data.ByteString as B
14instance Random Int64 where
17instance Random Int64 where
@@ -42,6 +45,56 @@ instance Random Word32 where
42instance Arbitrary Word32 where
45instance Arbitrary Word32 where
43 arbitrary = choose (minBound,maxBound)
46 arbitrary = choose (minBound,maxBound)
48+genUnicode :: IsString a => Gen a
49+genUnicode = fmap fromString string where
50+ string = sized $ \n ->
52+ sequence [ char | _ <- [1..k] ]
54+ excluding :: [a -> Bool] -> Gen a -> Gen a
55+ excluding bad gen = loop
59+ if or (map ($ x) bad)
63+ reserved = [lowSurrogate, highSurrogate, noncharacter]
64+ lowSurrogate c = c >= 0xDC00 && c <= 0xDFFF
65+ highSurrogate c = c >= 0xD800 && c <= 0xDBFF
66+ noncharacter c = masked == 0xFFFE || masked == 0xFFFF
68+ masked = c .&. 0xFFFF
70+ ascii = choose (0,0x7F)
71+ plane0 = choose (0xF0, 0xFFFF)
72+ plane1 = oneof [ choose (0x10000, 0x10FFF)
73+ , choose (0x11000, 0x11FFF)
74+ , choose (0x12000, 0x12FFF)
75+ , choose (0x13000, 0x13FFF)
76+ , choose (0x1D000, 0x1DFFF)
77+ , choose (0x1F000, 0x1FFFF)
79+ plane2 = oneof [ choose (0x20000, 0x20FFF)
80+ , choose (0x21000, 0x21FFF)
81+ , choose (0x22000, 0x22FFF)
82+ , choose (0x23000, 0x23FFF)
83+ , choose (0x24000, 0x24FFF)
84+ , choose (0x25000, 0x25FFF)
85+ , choose (0x26000, 0x26FFF)
86+ , choose (0x27000, 0x27FFF)
87+ , choose (0x28000, 0x28FFF)
88+ , choose (0x29000, 0x29FFF)
89+ , choose (0x2A000, 0x2AFFF)
90+ , choose (0x2B000, 0x2BFFF)
91+ , choose (0x2F000, 0x2FFFF)
93+ plane14 = choose (0xE0000, 0xE0FFF)
94+ planes = [ascii, plane0, plane1, plane2, plane14]
96+ char = chr `fmap` excluding reserved (oneof planes)
45instance Arbitrary T.Text where
98instance Arbitrary T.Text where
46 arbitrary = T.pack `fmap` arbitrary
99 arbitrary = T.pack `fmap` arbitrary