couchdb-enumerator-0.3.5: test/Database/CouchDB/Enumerator/Test/Basic.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Basic tests
module Database.CouchDB.Enumerator.Test.Basic where
import Control.Monad
import Control.Monad.Trans.Class (lift)
import qualified Control.Exception.Lifted as E
import Data.Aeson ((.=))
import qualified Data.Aeson as A
import qualified Data.HashMap.Lazy as M
import Data.List (nubBy)
import Database.CouchDB.Enumerator
import Database.CouchDB.Enumerator.Test.Util
import Test.Framework (testGroup, Test)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit (Assertion)
import Test.QuickCheck (sample', arbitrary)
tests :: Test
tests = testGroup "Basic" [
testGroup "DB" [
testCouchCase "basic connection" connectTest
, testCouchCase "basic error" missingObjectTest
, testCouchCase "conflict" conflictError
--, testCouchProperty "single insert" (1,7) insertTest
, testCouchCase "insert" insertTestCase
, testCouchCase "basic delete" deleteTest
, testCase "Delete noexistent" case_deleteNoexistentDb
-- TODO: right now, the following test screws up other tests by deleting the db.
-- Perhaps the code should be updated to put the database at the beginning of each test?
--, testCouchCase "Double put and delete" case_doublePutAndDel
]
]
connectTest :: CouchT IO ()
connectTest = do
v <- couchGet "" []
lift $ assertObjMember "db_name" (assertStr "testcouchenum") v
missingObjectTest :: CouchT IO ()
missingObjectTest = assertRecvError (Just 404) $ couchGet "jaosihaweoghaweiouhawef" []
conflictError :: CouchT IO ()
conflictError = do
E.handle catch404 $ do rev <- couchRev "conflicttest"
couchDelete "conflicttest" rev
--E.handle catch404 $ couchRev "somebadobject" >> return ()
couchPut_ "conflicttest" [] $ A.object [ "foo" .= True ]
return ()
where catch404 e@(CouchError c _) = unless (c == Just 404) $ E.throwIO e
insertTestCase :: CouchT IO ()
insertTestCase = replicateM_ 20 $ do
objs <- lift $ sample' arbitrary
insertTest objs
insertTest :: [(Int,ArbitraryObject,ArbitraryObject,ArbitraryObject)] -> CouchT IO ()
insertTest objs = do
let objs' = nubBy (\(a,_,_,_) (b,_,_,_) -> a == b) objs
let keys = map (("otest"++) . show . (\(a,_,_,_) -> a)) objs'
let vals1 = map (\(_,ArbitraryObject a,_,_) -> a) objs'
let vals2 = map (\(_,_,ArbitraryObject a,_) -> a) objs'
let vals3 = map (\(_,_,_,ArbitraryObject a) -> a) objs'
mapM_ clearObject keys
rev <- forM (zip keys vals1) $ \(k,o) ->
couchPut k [] o
forM_ (zip3 rev keys vals1) $ \(r,k,o) -> do
checkLoad k $ M.insert "_rev" (A.toJSON r) o
checkRevision k r
rev2 <- forM (zip3 rev keys vals2) $ \(r,k,o) ->
couchPut k [] $ M.insert "_rev" (A.toJSON r) o
forM_ (zip3 rev2 keys vals2) $ \(r,k,o) -> do
checkLoad k $ M.insert "_rev" (A.toJSON r) o
checkRevision k r
rev3 <- forM (zip3 rev2 keys vals3) $ \(r,k,o) ->
couchPutRev k r [] o
forM_ (zip3 rev3 keys vals3) $ \(r,k,o) -> do
checkLoad k $ M.insert "_rev" (A.toJSON r) o
checkRevision k r
deleteTest :: CouchT IO ()
deleteTest = do
(ArbitraryObject obj) <- liftM (head . drop 5) $ lift $ sample' arbitrary
clearObject "deltest"
rev <- couchPut "deltest" [] obj
checkLoad "deltest" obj
couchDelete "deltest" rev
assertRecvError (Just 404) $ couchGet "deltest" []
case_doublePutAndDel :: CouchT IO ()
case_doublePutAndDel = do
couchPutDb ""
couchPutDb ""
couchDeleteDb ""
-- | A test with an empty db
case_deleteNoexistentDb :: Assertion
case_deleteNoexistentDb = runCouch "localhost" 5984 "" $
checkError (Just 404) $ couchDeleteDb "cdbe_noexistent"