{-# LANGUAGE TypeApplications #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module Z.Data.CBytesSpec where import qualified Data.List as List import qualified GHC.Exts as List import Data.Word import Data.Hashable (hashWithSalt, hash) import qualified Z.Data.CBytes as CB import Z.Foreign import qualified Z.Data.Vector.Base as V import System.IO.Unsafe import Test.QuickCheck import Test.QuickCheck.Function import Test.QuickCheck.Property import Test.Hspec import Test.Hspec.QuickCheck spec :: Spec spec = describe "CBytes-base" $ do describe "CBytes Eq Ord property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do prop "CBytes eq === List.eq" $ \ xs ys -> (CB.pack xs == CB.pack ys) === (xs == ys) prop "CBytes compare === List.compare" $ \ xs ys -> let xs' = List.filter (/= '\NUL') xs ys' = List.filter (/= '\NUL') ys in (CB.pack xs' `compare` CB.pack ys') === (xs' `compare` ys') describe "CBytes Hashable instance property" . modifyMaxSuccess (*10) . modifyMaxSize (*10) $ do prop "CBytes a's hash should be equal to Bytes's hash" $ \ (ASCIIString xs) -> let ys = List.filter (/= '\NUL') xs in hash (CB.pack ys) === hash (V.packASCII ys) prop "CBytes a's hash should be equal to literal's hash" $ hash ("hello world!" :: CB.CBytes) === hash (CB.fromBytes "hello world!") describe "CBytes IsString instance property" $ do prop "ASCII string" $ "hello world" === CB.fromText "hello world" prop "ASCII string" $ "hello world" === CB.fromBytes "hello world" prop "ASCII string" $ CB.toBytes "\NUL" === (V.pack [0xC0, 0x80]) prop "UTF8 string" $ "你好世界" === CB.fromText "你好世界" prop "UTF8 string" $ "\NUL" === CB.pack ['\NUL'] describe "CBytes length == List.length" $ do prop "CBytes length === List.length" $ \ (ASCIIString xs) -> let ys = List.filter (/= '\NUL') xs in (CB.length $ CB.pack ys) === List.length ys describe "CBytes append == List.(++)" $ do prop "CBytes eq === List.eq" $ \ xs ys -> (CB.pack xs `CB.append` CB.pack ys) === CB.pack (xs ++ ys) describe "CBytes concat == List.concat" $ do prop "CBytes eq === List.eq" $ \ xss -> (CB.concat (map CB.pack xss)) === CB.pack (List.concat xss) describe "withCBytes fromCString == id" $ do prop "withCBytes fromCString == id" $ \ xs -> (unsafeDupablePerformIO $ CB.withCBytes (CB.pack xs) (CB.fromCString . castPtr)) === CB.pack xs describe "withCBytes fromNullTerminated == toBytes" $ do prop "CBytes eq === List.eq" $ \ xs -> CB.toBytes (CB.pack xs) === (unsafeDupablePerformIO $ CB.withCBytes (CB.pack xs) fromNullTerminated)