happstack-state-6.1.4: tests/Happstack/State/Tests/SaverProperties.hs
module Happstack.State.Tests.SaverProperties
( saverProperties
) where
import Control.Monad
import Control.Exception
import Control.Concurrent
import Data.Char (isAlphaNum)
import Data.List
import Happstack.State.Saver
import Happstack.State.Saver.Impl.Memory
import Happstack.State.Tests.Helpers
import Happstack.Util.Testing (qctest, qccheck)
import System.Directory
import System.Random
import System.FilePath
import System.IO.Unsafe
import Test.QuickCheck (Args(maxSize), Property, (==>), stdArgs)
import Test.HUnit (Test(TestCase),(~:))
--------------------------------------------------------------
-- Tests
--------------------------------------------------------------
-- read (write values) == values
prop_getSetId :: ((Saver -> IO Bool) -> IO Bool) -> {- String -> -} Int -> [Int] -> Property
prop_getSetId withSaver {- (NonEmpty key) -} cutoff values
= (abs cutoff) > 0 ==>
ioProperty $ withSaver $ \saver ->
do writer <- createWriter saver key (abs cutoff)
forM_ values $ \value -> writerAdd writer (value::Int) $ return ()
writerClose writer
reader <- createReader saver key (abs cutoff)
out <- readerGetUncut reader
return $ values == out
where
key = "key" -- not sure if randomly generating the key is useful. But it was causing trouble because it contain ~ / and other meaningful characters
prop_seqReadWrite withSaver {-(NonEmpty key) -} (Abs cutoff) valss
= ioProperty $ withSaver $ \saver ->
do writer <- createWriter saver key cutoff
forM_ valss $ \vals -> do forM_ vals $ \val -> writerAdd writer (val::Int) $ return ()
writerCut writer
writerClose writer
reader <- createReader saver key cutoff
(out,newCut) <- readerGet reader
return $ out == concat valss && newCut == length valss + 1
where
key = "key"
prop_cutDrop withSaver {- (NonEmpty key) -} (Abs cutoff) a b
= ioProperty $ withSaver $ \saver ->
do writer <- createWriter saver key cutoff
forM_ a $ \val -> writerAdd writer (val::Int) $ return ()
newCut <- writerCut writer
forM_ b $ \val -> writerAdd writer (val::Int) $ return ()
writerClose writer
reader <- createReader saver key newCut
(out,_) <- readerGet reader
return $ b `isSuffixOf` out
where
key = "key"
prop_atomic withSaver {- (NonEmpty key) -} (Abs cutoff) value
= ioProperty $ withSaver $ \saver ->
do writer <- createWriter saver key cutoff
writerAtomicReplace writer (value::Int)
writerClose writer
reader <- createReader saver key cutoff
out <- readerGetUncut reader
readerClose reader
return $ out == [value]
where
key = "key"
{-
checkSaverProperties :: IO ()
checkSaverProperties
= forEachSaver_ $ \name withSaver ->
tryTests (name ++ " saver") args [run (prop_getSetId withSaver)
,run (prop_seqReadWrite withSaver)
,run (prop_cutDrop withSaver)
,run (prop_atomic withSaver)]
where args = stdArgs{maxSize=5}
-}
saverProperties :: Test
saverProperties
= "saverProperties" ~:
((forEachSaver $ \name withSaver ->
name ~:
[ "prop_getSetId" ~: qccheck args (prop_getSetId withSaver)
, "prop_seqReadWrite" ~: qccheck args (prop_seqReadWrite withSaver)
, "prop_cutDrop" ~: qccheck args (prop_cutDrop withSaver)
, "prop_atomic" ~: qccheck args (prop_atomic withSaver)
]))
where args = stdArgs{maxSize=5}