{-# OPTIONS_GHC -F -pgmF htfpp #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Concurrent.Async
import Control.Monad
import Data.ByteString.SuperBuffer
import Data.Int
import qualified Data.ByteString as BS
import qualified Data.ByteString.SuperBuffer.Pure as P
import Test.Framework
import Test.QuickCheck.Monadic
main :: IO ()
main = htfMain htf_thisModulesTests
test_size :: IO ()
test_size =
void $
withBuffer 8 $ \buf ->
do appendBuffer buf "hello"
sz <- size buf
assertEqual sz 5
test_basic :: IO ()
test_basic =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello world! Welcome to S U P E R B U F F E R"
fillBuf =
withBuffer 8 $ \buf ->
do appendBuffer buf "hello"
appendBuffer buf " world"
appendBuffer buf "!"
appendBuffer buf " Welcome"
appendBuffer buf " to"
appendBuffer buf " S U P E R B U F F E R"
test_nullContained :: IO ()
test_nullContained =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello\0world"
fillBuf =
withBuffer 8 $ \buf ->
do appendBuffer buf "hello"
appendBuffer buf "\0world"
test_threaded :: IO ()
test_threaded =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello world! Welcome to S U P E R B U F F E R"
fillBuf =
withBuffer 8 $ \buf ->
forConcurrently_ ["hello", " world", "!", " Welcome", " to", " S U P E R B U F F E R"] $
appendBufferT buf
newtype BufferChunks
= BufferChunks { unBufferChunks :: (Int64, [BS.ByteString]) }
deriving (Show, Eq)
instance Arbitrary BufferChunks where
arbitrary = -- 5000 * 200 000 = 1 GB max
do listSize <- choose (1, 5000)
chunks <-
replicateM listSize $
do bsSize <- choose (0, 200000)
pure $ BS.replicate bsSize 84
bufSize <- choose (1, 1024 * 1024 * 1024)
pure $ BufferChunks (bufSize, chunks)
prop_appendingWorks :: BufferChunks -> Property
prop_appendingWorks (BufferChunks (bufSize, chunks)) =
monadicIO $
do out <- run chunkAction
assert $ out == BS.concat chunks
where
chunkAction =
withBuffer bufSize $ \buf ->
forM_ chunks $ appendBuffer buf
test_sizePure :: IO ()
test_sizePure =
void $
P.withBuffer 8 $ \buf ->
do P.appendBuffer buf "hello"
sz <- P.size buf
assertEqual sz 5
test_basicPure :: IO ()
test_basicPure =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello world! Welcome to S U P E R B U F F E R"
fillBuf =
P.withBuffer 8 $ \buf ->
do P.appendBuffer buf "hello"
P.appendBuffer buf " world"
P.appendBuffer buf "!"
P.appendBuffer buf " Welcome"
P.appendBuffer buf " to"
P.appendBuffer buf " S U P E R B U F F E R"
test_nullContainedPure :: IO ()
test_nullContainedPure =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello\0world"
fillBuf =
P.withBuffer 8 $ \buf ->
do P.appendBuffer buf "hello"
P.appendBuffer buf "\0world"
test_threadedPure :: IO ()
test_threadedPure =
do bs <- fillBuf
assertEqual bs expected
where
expected =
"hello world! Welcome to S U P E R B U F F E R"
fillBuf =
P.withBuffer 8 $ \buf ->
forConcurrently_ ["hello", " world", "!", " Welcome", " to", " S U P E R B U F F E R"] $
P.appendBufferT buf
prop_appendingWorksPure :: BufferChunks -> Property
prop_appendingWorksPure (BufferChunks (bufSize, chunks)) =
monadicIO $
do out <- run chunkAction
assert $ out == BS.concat chunks
where
chunkAction =
P.withBuffer (fromIntegral bufSize) $ \buf ->
forM_ chunks $ P.appendBuffer buf