memcached-binary 0.1.1.1 → 0.1.2
raw patch · 2 files changed
+257/−261 lines, 2 filesdep +hspecdep −test-frameworkdep −test-framework-hunitdep ~networkPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec
Dependencies removed: test-framework, test-framework-hunit
Dependency ranges changed: network
API changes (from Hackage documentation)
Files
- memcached-binary.cabal +4/−5
- test/test.hs +253/−256
memcached-binary.cabal view
@@ -1,5 +1,5 @@ name: memcached-binary-version: 0.1.1.1+version: 0.1.2 synopsis: memcached client using binary protocol. description: memcached client using binary protocol. license: MIT@@ -27,7 +27,7 @@ Database.Memcached.Binary.Internal.Definition build-depends: base >=4.6 && <4.8 , bytestring >=0.10 && <0.11- , network >=2.6 && <2.7+ , network >=2.5 && <2.7 , storable-endian >=0.2 && <0.3 , data-default-class >=0.0 && <0.1 , resource-pool >=0.2 && <0.3@@ -43,11 +43,10 @@ main-is: test.hs ghc-options: -Wall -O2 build-depends: base >=4.6 && <4.8+ , hspec >=1.11 && <1.12 , memcached-binary- , test-framework >=0.8 && <0.9- , test-framework-hunit >=0.3 && <0.4 , process >=1.2 && <1.3- , network >=2.6 && <2.7+ , network >=2.5 && <2.7 , HUnit >=1.2 && <1.3 , data-default-class >=0.0 && <0.1 , bytestring >=0.10 && <0.11
test/test.hs view
@@ -25,9 +25,8 @@ import qualified Database.Memcached.Binary.IO as McIO import qualified Database.Memcached.Binary.Maybe as McMaybe +import Test.Hspec import Test.HUnit hiding (Test)-import Test.Framework-import Test.Framework.Providers.HUnit startMemcached :: IO ProcessHandle startMemcached = do@@ -45,9 +44,6 @@ void $ McIO.set 0 0 "foo" "foovalue" c void $ McIO.set 1 0 "bar" "1234567890" c -testMc :: TestName -> (Connection -> IO ()) -> Test-testMc title m = testCase title $ withConnection def (\c -> precond c >> m c)- newtype ByPassException = ByPassException String deriving (Typeable) instance Show ByPassException where show (ByPassException s) = s@@ -67,204 +63,219 @@ , "occured: " ++ show e ] -testGet :: Test-testGet = testGroup "get"- [ testGroup "IO module"- [ testGroup "get"- [ doTest "foo" (0, "foovalue") McIO.get- , doTest "bar" (1, "1234567890") McIO.get- , doTestException "notexist" McIO.get- ]- , testGroup "get_"- [ doTest "foo" "foovalue" McIO.get_- , doTest "bar" "1234567890" McIO.get_- , doTestException "notexist" McIO.get_- ]- ]- , testGroup "Maybe module"- [ testGroup "get"- [ doTest "foo" (Just (0, "foovalue")) McMaybe.get- , doTest "bar" (Just (1, "1234567890")) McMaybe.get- , doTest "notexist" Nothing McMaybe.get- ]- , testGroup "get_"- [ doTest "foo" (Just "foovalue") McMaybe.get_- , doTest "bar" (Just "1234567890") McMaybe.get_- , doTest "notexist" Nothing McMaybe.get_- ]- ]- ]+withConn :: (Connection -> IO a) -> IO a+withConn m = withConnection def $ \c -> precond c >> m c++main :: IO ()+main = bracket startMemcached terminateProcess $ \_ -> hspec $ do+ v <- runIO $ withConn McIO.version+ testGet+ testSetAddReplace+ testDelete+ testIncrDecr v+ testFlush+ testVersion+ testNoOp+ testAppendPrepend+ testTouchGAT v+ testModify++testGet :: Spec+testGet = context "get" $ do+ context "IO module" $ do+ describe "get" $ do+ doTest "foo" (0, "foovalue") "get" McIO.get+ doTest "bar" (1, "1234567890") "get" McIO.get+ doTestException "get" McIO.get+ describe "get_" $ do+ doTest "foo" "foovalue" "get_" McIO.get_+ doTest "bar" "1234567890" "get_" McIO.get_+ doTestException "get_" McIO.get_+ context "Maybe module" $ do+ describe "get" $ do+ doTest "foo" (Just (0, "foovalue")) "get" McMaybe.get+ doTest "bar" (Just (1, "1234567890")) "get" McMaybe.get+ doTest "notexist" Nothing "get" McMaybe.get+ describe "get_" $ do+ doTest "foo" (Just "foovalue") "get_" McMaybe.get_+ doTest "bar" (Just "1234567890") "get_" McMaybe.get_+ doTest "notexist" Nothing "get_" McMaybe.get_ where- doTest key ex fn = testMc (S.unpack key) $ \c -> do+ doTest key ex meth fn = it ("return " ++ show ex ++ " when " ++ meth ++ ' ': show key) $ withConn $ \c -> do v <- fn key c v @?= ex- doTestException key fn = testMc (S.unpack key) $ \c ->- assertException 1 "Not found" $ fn key c+ doTestException meth fn = it ("throw exception(1) when " ++ meth ++ " notexist") $ withConn $ \c ->+ assertException 1 "Not found" $ fn "notexist" c -testSetAddReplace :: Test-testSetAddReplace = testGroup "set/add/replace"- [ testGroup "set"- [ testMc "set foo to foomod" $ \c -> do+testSetAddReplace :: Spec+testSetAddReplace = context "set/add/replace" $ do+ describe "set" $ do+ it "set foo = (100, foomod)" $ withConn $ \c -> do McIO.set 100 0 "foo" "foomod" c v <- McIO.get "foo" c v @?= (100, "foomod")- , testMc "set notexist to exist" $ \c -> do+ it "set notexist = exist" $ withConn $ \c -> do McIO.set 100 0 "notexist" "exist" c v <- McIO.get "notexist" c v @?= (100, "exist")- ]- , testGroup "add"- [ testMc "add foo to foomod" $ \c ->++ describe "add" $ do+ it "throw exception(2) when add exist key" $ withConn $ \c -> do assertException 2 "Data exists for key." $ McIO.add 100 0 "foo" "foomod" c- , testMc "add notexist to exist" $ \c -> do+ it "add notexist = exist" $ withConn $ \c -> do McIO.add 100 0 "notexist" "exist" c v <- McIO.get "notexist" c v @?= (100, "exist")- ]- , testGroup "replace"- [ testMc "set foo to foomod" $ \c -> do++ describe "replace" $ do+ it "replace foo = foomod" $ withConn $ \c -> do McIO.replace 100 0 "foo" "foomod" c v <- McIO.get "foo" c v @?= (100, "foomod")- , testMc "set notexist to exist" $ \c ->+ it "throw exception(1) when replace not exist key" $ withConn $ \c -> do assertException 1 "Not found" $ McIO.replace 100 0 "notexist" "exist" c- ]- ] -testDelete :: Test-testDelete = testGroup "delete"- [ testGroup "IO module"- [ testMc "foo" $ \c -> do++testDelete :: Spec+testDelete = context "delete" $ do+ context "IO module" $ do+ it "delete foo" $ withConn $ \c -> do McIO.delete "foo" c r <- McMaybe.get "foo" c r @?= Nothing- , testMc "notexist" $ \c ->- assertException 1 "Not found" $ McIO.delete "notexist" c- ]- , testGroup "Maybe module"- [ testMc "foo" $ \c -> do+ it "throw exception(1) when delete notexist" $ withConn $+ assertException 1 "Not found" . McIO.delete "notexist"++ context "Maybe module" $ do+ it "delete foo" $ withConn $ \c -> do b <- McMaybe.delete "foo" c r <- McMaybe.get "foo" c b @?= True r @?= Nothing- , testMc "notexist" $ \c -> do+ it "delete notexist" $ withConn $ \c -> do b <- McMaybe.delete "notexist" c r <- McMaybe.get "notexist" c b @?= False r @?= Nothing- ]- ] -- https://code.google.com/p/memcached/wiki/ReleaseNotes1417-testIncrDecr :: Version -> Test-testIncrDecr v = testGroup "increment/decrement"- [ testGroup "IO module"- [ testGroup "increment"- [ testMc "foo" $ \c ->+testIncrDecr :: Version -> Spec+testIncrDecr v = context "increment/decrement" $ do+ context "IO module" $ do+ describe "increment" $ do+ it "throw exception(6) when increment non numeric value" $ withConn $ \c -> assertException 6 "Non-numeric server-side value for incr or decr" $ McIO.increment 0 "foo" 10 10 c- , testMc "bar" $ \c -> do++ it "increment bar" $ withConn $ \c -> do a <- McIO.increment 0 "bar" 10 10 c b <- McIO.get_ "bar" c a @?= 1234567900 b @?= "1234567900"- , testMc "notexist" $ \c -> do++ it "set initial value notexist" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McIO.increment 0 "notexist" 10 10 c b <- McIO.get_ "notexist" c a @?= 10- when (v >= ev) $ b @?= "10"- ]- , testGroup "decrement"- [ testMc "foo" $ \c ->+ b @?= "10"++ describe "decrement" $ do+ it "throw exception(6) when increment non numeric value" $ withConn $ \c -> assertException 6 "Non-numeric server-side value for incr or decr" $ McIO.decrement 0 "foo" 10 10 c- , testMc "bar" $ \c -> do++ it "decrement bar" $ withConn $ \c -> do a <- McIO.decrement 0 "bar" 10 10 c b <- McIO.get_ "bar" c a @?= 1234567880 b @?= "1234567880"- , testMc "notexist" $ \c -> do++ it "set initial value notexist" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McIO.decrement 0 "notexist" 10 10 c b <- McIO.get_ "notexist" c a @?= 10- when (v >= ev) $ b @?= "10"- ]- ]- , testGroup "Maybe module"- [ testGroup "increment"- [ testMc "foo" $ \c -> do+ b @?= "10"++ context "Maybe module" $ do+ describe "increment" $ do+ it "return Nothing when increment non numeric value" $ withConn $ \c -> do r <- McMaybe.increment 0 "foo" 10 10 c b <- McIO.get_ "foo" c r @?= Nothing b @?= "foovalue"- , testMc "bar" $ \c -> do+ it "increment bar" $ withConn $ \c -> do a <- McMaybe.increment 0 "bar" 10 10 c b <- McIO.get_ "bar" c a @?= Just 1234567900 b @?= "1234567900"- , testMc "notexist" $ \c -> do+ it "set initial value notexist" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.increment 0 "notexist" 10 10 c b <- McIO.get_ "notexist" c a @?= Just 10- when (v >= ev) $ b @?= "10"- ]- , testGroup "decrement'"- [ testMc "foo" $ \c -> do+ b @?= "10"++ describe "decrement" $ do+ it "return Nothing when decrement non numeric value" $ withConn $ \c -> do r <- McMaybe.decrement 0 "foo" 10 10 c b <- McIO.get_ "foo" c r @?= Nothing b @?= "foovalue"- , testMc "bar" $ \c -> do+ it "decrement bar" $ withConn $ \c -> do a <- McMaybe.decrement 0 "bar" 10 10 c b <- McIO.get_ "bar" c a @?= Just 1234567880 b @?= "1234567880"- , testMc "notexist" $ \c -> do+ it "set initial value notexist" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.decrement 0 "notexist" 10 10 c b <- McIO.get_ "notexist" c a @?= Just 10- when (v >= ev) $ b @?= "10"- ]- ]- ]+ b @?= "10"+ where- ev = Version [1,4,17] []+ ev = Version [1,4,17] []+ msg = "memcached(< 1.4.17) bug. see: https://code.google.com/p/memcached/wiki/ReleaseNotes1417" -testFlush :: Test-testFlush = testGroup "flush"- [ testGroup "IO module"- [ testMc "flushAll" $ \c -> do- McIO.flushAll c- a <- McMaybe.get "foo" c- a @?= Nothing- ]- , testGroup "Maybe module"- [ testMc "flushAll" $ \c -> do- r <- McMaybe.flushAll c- a <- McMaybe.get "foo" c- r @?= True- a @?= Nothing- ]- ]+testFlush :: Spec+testFlush = context "flush" $ do+ context "IO module" $ do+ describe "flushAll" $ do+ it "flush all data" $ withConn $ \c -> do+ McIO.flushAll c+ a <- McMaybe.get "foo" c+ a @?= Nothing -testVersion :: Test-testVersion = testGroup "version"- [ testGroup "versionString"- [ testMc "IO module" $ \c -> do- v <- McIO.versionString c- assertBool (show v ++ " is not version like.") $ isVersionLike v- , testMc "Maybe module" $ \c -> do- Just v <- McMaybe.versionString c- assertBool (show v ++ " is not version like.") $ isVersionLike v- ]- , testGroup "version"- [ testMc "IO module" $ \c -> do- v <- McIO.version c- assertEqual "version branch length" 3 (length $ versionBranch v)- ]- ]+ context "Maybe module" $ do+ describe "flushAll" $ do+ it "flush all data and return True" $ withConn $ \c -> do+ r <- McMaybe.flushAll c+ a <- McMaybe.get "foo" c+ r @?= True+ a @?= Nothing++testVersion :: Spec+testVersion = context "version" $ do+ context "IO module" $ do+ describe "versionString" $+ it "return version bytestring" $ withConn $ \c -> do+ v <- McIO.versionString c+ assertBool (show v ++ " is not version like.") $ isVersionLike v++ describe "version" $+ it "return Version" $ withConn $ \c -> do+ v <- McIO.version c+ assertEqual "version branch length" 3 (length $ versionBranch v)++ context "Maybe module" $ do+ describe "versionString" $+ it "returns version bytestring" $ withConn $ \c -> do+ Just v <- McMaybe.versionString c+ assertBool (show v ++ " is not version like.") $ isVersionLike v where isVersionLike s0 = isJust $ do (_, s1) <- S.readInt s0@@ -274,212 +285,198 @@ (_, s3) <- S.readInt (S.tail s2) unless (S.null s3) Nothing -testNoOp :: Test-testNoOp = testGroup "noOp"- [ testMc "IO module" McIO.noOp- , testMc "Maybe module" $ \c -> do- b <- McMaybe.noOp c- b @?= True- ]+testNoOp :: Spec+testNoOp = context "noOp" $ do+ context "IO module" $+ it "is noop" $ withConn McIO.noOp+ context "Maybe module" $+ it "is noop and returns True" $ withConn $ \c -> do+ b <- McMaybe.noOp c+ b @?= True -testAppendPrepend :: Test-testAppendPrepend = testGroup "append/prepend"- [ testGroup "IO module"- [ testGroup "append"- [ testMc "foo" $ \c -> do+testAppendPrepend :: Spec+testAppendPrepend = context "append/prepend" $ do+ context "IO module" $ do+ describe "append" $ do+ it "append !! to foo" $ withConn $ \c -> do McIO.append "foo" "!!" c a <- McIO.get_ "foo" c a @?= "foovalue!!"- , testMc "bar" $ \c -> do+ it "append !! to bar" $ withConn $ \c -> do McIO.append "bar" "!!" c a <- McIO.get_ "bar" c a @?= "1234567890!!"- , testMc "notexist" $ \c ->+ it "throws exception(5) when not exist." $ withConn $ \c -> assertException 5 "Not stored." $ McIO.append "notexist" "!!" c- ]- , testGroup "prepend"- [ testMc "foo" $ \c -> do+ + describe "prepend" $ do+ it "prepend !! to foo" $ withConn $ \c -> do McIO.prepend "foo" "!!" c a <- McIO.get_ "foo" c a @?= "!!foovalue"- , testMc "bar" $ \c -> do++ it "prepend !! to bar" $ withConn $ \c -> do McIO.prepend "bar" "!!" c a <- McIO.get_ "bar" c a @?= "!!1234567890"- , testMc "notexist" $ \c ->++ it "throws exception(5) when not exist" $ withConn $ \c -> assertException 5 "Not stored." $ McIO.prepend "notexist" "!!" c- ]- ]- , testGroup "maybe module"- [ testGroup "append'"- [ testMc "foo" $ \c -> do++ context "Maybe module" $ do+ describe "append" $ do+ it "append !! to foo and return True" $ withConn $ \c -> do b <- McMaybe.append "foo" "!!" c a <- McIO.get_ "foo" c b @?= True a @?= "foovalue!!"- , testMc "bar" $ \c -> do++ it "append !! to bar and return True" $ withConn $ \c -> do b <- McMaybe.append "bar" "!!" c a <- McIO.get_ "bar" c b @?= True a @?= "1234567890!!"- , testMc "notexist" $ \c -> do++ it "return False when not exist" $ withConn $ \c -> do b <- McMaybe.append "notexist" "!!" c b @?= False- ]- , testGroup "prepend'"- [ testMc "foo" $ \c -> do++ describe "prepend" $ do+ it "prepend !! to foo and return True" $ withConn $ \c -> do b <- McMaybe.prepend "foo" "!!" c a <- McIO.get_ "foo" c b @?= True a @?= "!!foovalue"- , testMc "bar" $ \c -> do++ it "prepend !! to baar and return True" $ withConn $ \c -> do b <- McMaybe.prepend "bar" "!!" c a <- McIO.get_ "bar" c b @?= True a @?= "!!1234567890"- , testMc "notexist" $ \c -> do++ it "return False when not exist" $ withConn $ \c -> do b <- McMaybe.prepend "notexist" "!!" c b @?= False- ]- ]- ] --- https://code.google.com/p/memcached/wiki/ReleaseNotes1414--- https://code.google.com/p/memcached/issues/detail?id=275-testTouchGAT :: Version -> Test-testTouchGAT v = testGroup "touch/GAT"- [ testGroup "IO module"- [ testGroup "touch"- [ testMc "foo" $ \c -> do+testTouchGAT :: Version -> Spec+testTouchGAT v = context "touch/GAT" $ do+ context "IO module" $ do+ describe "touch" $ do+ it "touch 1s and expire it." $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.get_ "foo" c McIO.touch 1 "foo" c a @?= (Just "foovalue")- when (v >= ev) $ do- threadDelay 1100000- b <- McMaybe.get_ "foo" c- b @?= Nothing- , testMc "notexist" $ \c ->+ threadDelay 1100000+ b <- McMaybe.get_ "foo" c+ b @?= Nothing++ it "throws exception(1) when not exist" $ withConn $ \c -> assertException 1 "Not found" $ McIO.touch 1 "notexist" c- ]- , testGroup "getAndTouch"- [ testMc "foo" $ \c -> do++ describe "getAndTouch" $ do+ it "touch 1s, return (flag, value), and expire it" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg x <- McMaybe.get "foo" c y <- McIO.getAndTouch 1 "foo" c x @?= Just (0, "foovalue") y @?= (0, "foovalue")- when (v >= ev) $ do- threadDelay 1100000- z <- McMaybe.get "foo" c- z @?= Nothing- , testMc "notexist" $ \c ->+ threadDelay 1100000+ z <- McMaybe.get "foo" c+ z @?= Nothing++ it "throws exception(1) when not exist" $ withConn $ \c -> assertException 1 "Not found" $ McIO.getAndTouch 1 "notexist" c- ]- , testGroup "getAndTouch_"- [ testMc "foo" $ \c -> do++ describe "getAndTouch_" $ do+ it "touch 1s, return value, and expire it" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg x <- McMaybe.get_ "foo" c y <- McIO.getAndTouch_ 1 "foo" c x @?= Just "foovalue" y @?= "foovalue"- when (v >= ev) $ do- threadDelay 1100000- z <- McMaybe.get_ "foo" c- z @?= Nothing- , testMc "notexist" $ \c ->+ threadDelay 1100000+ z <- McMaybe.get_ "foo" c+ z @?= Nothing++ it "throws exception(1) when not exist" $ withConn $ \c -> assertException 1 "Not found" $ McIO.getAndTouch_ 1 "notexist" c- ]- ]- , testGroup "Maybe module"- [ testGroup "touch"- [ testMc "foo" $ \c -> do++ context "Maybe module" $ do+ describe "touch" $ do+ it "touch 1s, return True, and expire it." $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.get_ "foo" c r <- McMaybe.touch 1 "foo" c a @?= (Just "foovalue") r @?= True- when (v >= ev) $ do- threadDelay 1100000- b <- McMaybe.get_ "foo" c- b @?= Nothing- , testMc "notexist" $ \c -> do+ threadDelay 1100000+ b <- McMaybe.get_ "foo" c+ b @?= Nothing++ it "return False when not exist" $ withConn $ \c -> do r <- McMaybe.touch 1 "notexist" c a <- McMaybe.get "notexist" c r @?= False a @?= Nothing- ]- , testGroup "getAndTouch'/getMaybeAndTouch"- [ testMc "foo" $ \c -> do++ describe "getAndTouch" $ do+ it "touch 1s, return (flag, value), and expire it" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.get "foo" c r <- McMaybe.getAndTouch 1 "foo" c a @?= Just (0, "foovalue") r @?= Just (0, "foovalue")- when (v >= ev) $ do- threadDelay 1100000- b <- McMaybe.get_ "foo" c- b @?= Nothing- , testMc "notexist" $ \c -> do+ threadDelay 1100000+ b <- McMaybe.get_ "foo" c+ b @?= Nothing++ it "return Nothing when not exist" $ withConn $ \c -> do r <- McMaybe.getAndTouch 1 "notexist" c a <- McMaybe.get "notexist" c r @?= Nothing a @?= Nothing- ]- , testGroup "getAndTouch'_/getMaybeAndTouch_"- [ testMc "foo" $ \c -> do++ describe "getAndTouch_" $ do+ it "touch 1s, return value, and expire it" $ withConn $ \c -> do+ when (v < ev) $ pendingWith msg a <- McMaybe.get_ "foo" c r <- McMaybe.getAndTouch_ 1 "foo" c a @?= Just "foovalue" r @?= Just "foovalue"- when (v >= ev) $ do- threadDelay 1100000- b <- McMaybe.get_ "foo" c- b @?= Nothing- , testMc "notexist" $ \c -> do+ threadDelay 1100000+ b <- McMaybe.get_ "foo" c+ b @?= Nothing++ it "return Nothing when not exist" $ withConn $ \c -> do r <- McMaybe.getAndTouch_ 1 "notexist" c a <- McMaybe.get "notexist" c r @?= Nothing a @?= Nothing- ]- ]- ] where- ev = Version [1,4,14] []--testModify :: Test-testModify = testGroup "modify"- [ testMc "reverse foo" $ \c -> do- r <- McIO.modify 0 "foo" (\f v -> (f + 100, L.reverse v, v)) c- a <- McMaybe.get "foo" c- r @?= "foovalue"- a @?= Just (100, "eulavoof")- , testMc "notexist" $ \c ->- assertException 1 "Not found" $- McIO.modify 0 "notexist" (\f v -> (f,v,())) c- ]+ ev = Version [1,4,14] []+ msg = "memcached(< 1.4.14) bug. see: https://code.google.com/p/memcached/wiki/ReleaseNotes1414 & https://code.google.com/p/memcached/issues/detail?id=275" -testModify_ :: Test-testModify_ = testGroup "modify_"- [ testMc "reverse foo" $ \c -> do- McIO.modify_ 0 "foo" (\f v -> (f + 100, L.reverse v)) c- a <- McMaybe.get "foo" c- a @?= Just (100, "eulavoof")- , testMc "notexist" $ \c ->- assertException 1 "Not found" $- McIO.modify_ 0 "notexist" (\f v -> (f,v)) c- ]+testModify :: Spec+testModify = context "modify" $ do+ context "IO monad" $ do+ describe "modify" $ do+ it "reverse foo value and return original" $ withConn $ \c -> do+ r <- McIO.modify 0 "foo" (\f v -> (f + 100, L.reverse v, v)) c+ a <- McMaybe.get "foo" c+ r @?= "foovalue"+ a @?= Just (100, "eulavoof") + it "throw exception(1) when not exist" $ withConn $ \c -> do+ assertException 1 "Not found" $+ McIO.modify 0 "notexist" (\f v -> (f,v,())) c + describe "modify_" $ do+ it "reverse foo value" $ withConn $ \c -> do+ McIO.modify_ 0 "foo" (\f v -> (f + 100, L.reverse v)) c+ a <- McMaybe.get "foo" c+ a @?= Just (100, "eulavoof") -main :: IO ()-main = bracket startMemcached terminateProcess $ \_ -> do- v <- McIO.withConnection def McIO.version- defaultMain- [ testGet- , testSetAddReplace- , testDelete- , testIncrDecr v- , testFlush- , testVersion- , testNoOp- , testAppendPrepend- , testTouchGAT v- , testModify- , testModify_- ]+ it "throw exception(1) when not exist" $ withConn $ \c -> do+ assertException 1 "Not found" $+ McIO.modify_ 0 "notexist" (\f v -> (f,v)) c