dbus 0.10.13 → 0.10.14
raw patch · 22 files changed
+978/−982 lines, 22 filesdep +extradep +resourcetdep +tastydep −chelldep −chell-quickcheckdep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: extra, resourcet, tasty, tasty-hunit, tasty-quickcheck
Dependencies removed: chell, chell-quickcheck
Dependency ranges changed: base
API changes (from Hackage documentation)
- DBus.Internal.Types: instance (GHC.Classes.Ord k, DBus.Internal.Types.IsAtom k, DBus.Internal.Types.IsValue v) => DBus.Internal.Types.IsValue (Data.Map.Base.Map k v)
- DBus.Internal.Types: instance (GHC.Classes.Ord k, DBus.Internal.Types.IsAtom k, DBus.Internal.Types.IsValue v) => DBus.Internal.Types.IsVariant (Data.Map.Base.Map k v)
+ DBus.Client: matchPathNamespace :: MatchRule -> Maybe ObjectPath
+ DBus.Internal.Types: instance (GHC.Classes.Ord k, DBus.Internal.Types.IsAtom k, DBus.Internal.Types.IsValue v) => DBus.Internal.Types.IsValue (Data.Map.Internal.Map k v)
+ DBus.Internal.Types: instance (GHC.Classes.Ord k, DBus.Internal.Types.IsAtom k, DBus.Internal.Types.IsValue v) => DBus.Internal.Types.IsVariant (Data.Map.Internal.Map k v)
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.BusName
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.ErrorName
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.InterfaceName
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.MemberName
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.ObjectPath
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.Signature
+ DBus.Internal.Types: instance Control.DeepSeq.NFData DBus.Internal.Types.Type
+ DBus.Internal.Types: instance GHC.Generics.Generic DBus.Internal.Types.Type
- DBus: class Message a where messageFlags _ = 0
+ DBus: class Message a
- DBus.Internal.Message: class Message a where messageFlags _ = 0
+ DBus.Internal.Message: class Message a
- DBus.Transport: class Transport t where data TransportOptions t :: * where {
+ DBus.Transport: class Transport t where {
- DBus.Transport: class Transport t => TransportListen t where data TransportListener t :: * where {
+ DBus.Transport: class Transport t => TransportListen t where {
Files
- benchmarks/DBusBenchmarks.hs +5/−25
- dbus.cabal +9/−5
- lib/DBus/Client.hs +12/−3
- lib/DBus/Internal/Types.hs +28/−23
- tests/DBusTests.hs +28/−28
- tests/DBusTests/Address.hs +46/−47
- tests/DBusTests/BusName.hs +26/−26
- tests/DBusTests/Client.hs +130/−137
- tests/DBusTests/ErrorName.hs +25/−24
- tests/DBusTests/Integration.hs +43/−45
- tests/DBusTests/InterfaceName.hs +25/−24
- tests/DBusTests/Introspection.hs +34/−38
- tests/DBusTests/MemberName.hs +23/−21
- tests/DBusTests/Message.hs +18/−23
- tests/DBusTests/ObjectPath.hs +17/−19
- tests/DBusTests/Serialization.hs +29/−30
- tests/DBusTests/Signature.hs +53/−50
- tests/DBusTests/Socket.hs +62/−75
- tests/DBusTests/Transport.hs +206/−200
- tests/DBusTests/Util.hs +86/−57
- tests/DBusTests/Variant.hs +58/−68
- tests/DBusTests/Wire.hs +15/−14
benchmarks/DBusBenchmarks.hs view
@@ -17,37 +17,17 @@ module Main (benchmarks, main) where -import Control.DeepSeq-import Criterion.Types-import Criterion.Config+import Criterion.Types+import Data.Word (Word32)+import Unsafe.Coerce (unsafeCoerce) import qualified Criterion.Main-import Data.Word (Word32)-import Unsafe.Coerce (unsafeCoerce) -import DBus--config :: Config-config = defaultConfig { cfgPerformGC = ljust True }+import DBus serial :: Word32 -> Serial serial = unsafeCoerce -- FIXME: should the Serial constructor be exposed to -- clients? -instance NFData Type--instance NFData Signature where- rnf = rnf . signatureTypes--instance NFData ObjectPath--instance NFData InterfaceName--instance NFData MemberName--instance NFData ErrorName--instance NFData BusName- empty_MethodCall :: MethodCall empty_MethodCall = methodCall "/" "org.i" "m" @@ -106,4 +86,4 @@ ] main :: IO ()-main = Criterion.Main.defaultMainWith config (return ()) benchmarks+main = Criterion.Main.defaultMain benchmarks
dbus.cabal view
@@ -1,9 +1,9 @@ name: dbus-version: 0.10.13+version: 0.10.14 license: GPL-3 license-file: license.txt author: John Millikin <john@john-millikin.com>-maintainer: Andrey Sverdlichenko <blaze@ruddy.ru>, John Millikin <john@john-millikin.com>+maintainer: Andrey Sverdlichenko <blaze@ruddy.ru> build-type: Simple cabal-version: >= 1.8 category: Network, Desktop@@ -83,6 +83,7 @@ , bytestring , cereal , containers+ , deepseq , libxml-sax , network , parsec@@ -108,16 +109,16 @@ type: exitcode-stdio-1.0 main-is: DBusTests.hs hs-source-dirs: tests+ ghc-options: -W -Wall build-depends: dbus , base , bytestring , cereal- , chell- , chell-quickcheck , containers , directory+ , extra , filepath , libxml-sax , network@@ -125,6 +126,10 @@ , process , QuickCheck , random+ , resourcet+ , tasty+ , tasty-hunit+ , tasty-quickcheck , text , transformers , unix@@ -160,4 +165,3 @@ dbus , base , criterion- , deepseq
lib/DBus/Client.hs view
@@ -99,6 +99,7 @@ , matchPath , matchInterface , matchMember+ , matchPathNamespace -- * Name reservation , requestName@@ -132,13 +133,14 @@ import Control.Monad (forever, forM_, when) import Data.Bits ((.|.)) import Data.IORef-import Data.List (foldl', intercalate)+import Data.List (foldl', intercalate, isPrefixOf) import qualified Data.Map import Data.Map (Map) import Data.Maybe (catMaybes, listToMaybe) import Data.Typeable (Typeable) import Data.Unique import Data.Word (Word32)+import Data.Function import DBus import qualified DBus.Introspection as I@@ -641,6 +643,10 @@ -- | If set, only receives signals sent with the given member name. , matchMember :: Maybe MemberName++ -- | If set, only receives signals sent with the given path or any of+ -- its children.+ , matchPathNamespace :: Maybe ObjectPath } instance Show MatchRule where@@ -655,6 +661,7 @@ , f "path" matchPath formatObjectPath , f "interface" matchInterface formatInterfaceName , f "member" matchMember formatMemberName+ , f "path_namespace" matchPathNamespace formatObjectPath ] f :: String -> (MatchRule -> Maybe a) -> (a -> String) -> Maybe String@@ -664,7 +671,7 @@ -- | Match any signal. matchAny :: MatchRule-matchAny = MatchRule Nothing Nothing Nothing Nothing Nothing+matchAny = MatchRule Nothing Nothing Nothing Nothing Nothing Nothing checkMatchRule :: MatchRule -> Signal -> Bool checkMatchRule rule msg = and@@ -673,7 +680,9 @@ , maybe True (== signalPath msg) (matchPath rule) , maybe True (== signalInterface msg) (matchInterface rule) , maybe True (== signalMember msg) (matchMember rule)- ]+ , maybe True (`pathPrefix` signalPath msg) (matchPathNamespace rule)+ ] where+ pathPrefix = isPrefixOf `on` formatObjectPath data MethodExc = MethodExc ErrorName [Variant] deriving (Show, Eq, Typeable)
lib/DBus/Internal/Types.hs view
@@ -1,8 +1,10 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE IncoherentInstances #-}+{-# LANGUAGE TypeSynonymInstances #-} -- Copyright (C) 2009-2012 John Millikin <john@john-millikin.com> --@@ -21,32 +23,33 @@ module DBus.Internal.Types where -import Control.Monad (liftM, when, (>=>))-import Control.Exception (Exception, handle, throwIO)-import Data.ByteString (ByteString)+import Control.DeepSeq+import Control.Exception (Exception, handle, throwIO)+import Control.Monad (liftM, when, (>=>))+import Data.ByteString (ByteString)+import Data.Char (ord)+import Data.Int+import Data.List (intercalate)+import Data.Map (Map)+import Data.Text (Text)+import Data.Typeable (Typeable)+import Data.Vector (Vector)+import Data.Word+import GHC.Generics+import System.IO.Unsafe (unsafePerformIO)+import System.Posix.Types (Fd)+import Text.ParserCombinators.Parsec ((<|>), oneOf) import qualified Data.ByteString import qualified Data.ByteString.Char8 as Char8 import qualified Data.ByteString.Lazy import qualified Data.ByteString.Unsafe-import Data.Char (ord)-import Data.Int-import Data.List (intercalate) import qualified Data.Map-import Data.Map (Map) import qualified Data.String import qualified Data.Text-import Data.Text (Text) import qualified Data.Text.Lazy-import Data.Typeable (Typeable) import qualified Data.Vector-import Data.Vector (Vector)-import Data.Word import qualified Foreign-import System.IO.Unsafe (unsafePerformIO)-import System.Posix.Types (Fd)- import qualified Text.ParserCombinators.Parsec as Parsec-import Text.ParserCombinators.Parsec ((<|>), oneOf) data Type = TypeBoolean@@ -66,8 +69,10 @@ | TypeArray Type | TypeDictionary Type Type | TypeStructure [Type]- deriving (Eq, Ord)+ deriving (Eq, Ord, Generic) +instance NFData Type+ instance Show Type where showsPrec d = showString . showType (d > 10) @@ -103,7 +108,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures> -- for details. newtype Signature = Signature [Type]- deriving (Eq, Ord)+ deriving (Eq, Ord, NFData) -- | Get the list of types in a signature. The inverse of 'signature'. signatureTypes :: Signature -> [Type]@@ -628,7 +633,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path> -- for details. newtype ObjectPath = ObjectPath String- deriving (Eq, Ord, Show)+ deriving (Eq, Ord, Show, NFData) formatObjectPath :: ObjectPath -> String formatObjectPath (ObjectPath s) = s@@ -671,7 +676,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-interface> -- for details. newtype InterfaceName = InterfaceName String- deriving (Eq, Ord, Show)+ deriving (Eq, Ord, Show, NFData) formatInterfaceName :: InterfaceName -> String formatInterfaceName (InterfaceName s) = s@@ -711,7 +716,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-member> -- for details. newtype MemberName = MemberName String- deriving (Eq, Ord, Show)+ deriving (Eq, Ord, Show, NFData) formatMemberName :: MemberName -> String formatMemberName (MemberName s) = s@@ -748,7 +753,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-error> -- for details. newtype ErrorName = ErrorName String- deriving (Eq, Ord, Show)+ deriving (Eq, Ord, Show, NFData) formatErrorName :: ErrorName -> String formatErrorName (ErrorName s) = s@@ -778,7 +783,7 @@ -- <http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names-bus> -- for details. newtype BusName = BusName String- deriving (Eq, Ord, Show)+ deriving (Eq, Ord, Show, NFData) formatBusName :: BusName -> String formatBusName (BusName s) = s
tests/DBusTests.hs view
@@ -18,38 +18,38 @@ , main ) where -import Test.Chell+import Test.Tasty -import DBusTests.Address-import DBusTests.BusName-import DBusTests.Client-import DBusTests.ErrorName-import DBusTests.Integration-import DBusTests.InterfaceName-import DBusTests.Introspection-import DBusTests.MemberName-import DBusTests.Message-import DBusTests.ObjectPath-import DBusTests.Serialization-import DBusTests.Socket-import DBusTests.Signature-import DBusTests.Transport-import DBusTests.Variant-import DBusTests.Wire+import DBusTests.Address+import DBusTests.BusName+import DBusTests.Client+import DBusTests.ErrorName+import DBusTests.Integration+import DBusTests.InterfaceName+import DBusTests.Introspection+import DBusTests.MemberName+import DBusTests.Message+import DBusTests.ObjectPath+import DBusTests.Serialization+import DBusTests.Socket+import DBusTests.Signature+import DBusTests.Transport+import DBusTests.Variant+import DBusTests.Wire -- import all dbus modules here to ensure they show up in the coverage report, -- even if not tested.-import DBus ()-import DBus.Client ()-import DBus.Internal.Address ()-import DBus.Internal.Message ()-import DBus.Internal.Types ()-import DBus.Internal.Wire ()-import DBus.Introspection ()-import DBus.Socket ()+import DBus ()+import DBus.Client ()+import DBus.Internal.Address ()+import DBus.Internal.Message ()+import DBus.Internal.Types ()+import DBus.Internal.Wire ()+import DBus.Introspection ()+import DBus.Socket () -tests :: [Suite]-tests =+tests :: TestTree+tests = testGroup "dbus" [ test_Address , test_BusName , test_Client@@ -69,4 +69,4 @@ ] main :: IO ()-main = Test.Chell.defaultMain tests+main = defaultMain tests
tests/DBusTests/Address.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,22 +15,23 @@ module DBusTests.Address (test_Address) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Data.Char (ord)-import Data.List (intercalate)-import Data.Map (Map)+import Data.Char (ord)+import Data.List (intercalate)+import Data.Map (Map)+import Data.Maybe+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck+import Text.Printf (printf) import qualified Data.Map-import Text.Printf (printf) import DBus import DBusTests.Util (smallListOf, smallListOf1, withEnv) -test_Address :: Suite-test_Address = suite "Address"+test_Address :: TestTree+test_Address = testGroup "Address" [ test_BuildAddress , test_ParseAddress , test_ParseAddresses@@ -44,8 +43,8 @@ , test_GetStarterAddress ] -test_BuildAddress :: Test-test_BuildAddress = property "address" prop where+test_BuildAddress :: TestTree+test_BuildAddress = testProperty "address" prop where prop = forAll gen_Address check check (method, params) = case address method params of Nothing -> False@@ -54,8 +53,8 @@ , addressParameters addr == params ] -test_ParseAddress :: Test-test_ParseAddress = property "parseAddress" prop where+test_ParseAddress :: TestTree+test_ParseAddress = testProperty "parseAddress" prop where prop = forAll gen_AddressBytes check check (bytes, method, params) = case parseAddress bytes of Nothing -> False@@ -64,8 +63,8 @@ , addressParameters addr == params ] -test_ParseAddresses :: Test-test_ParseAddresses = property "parseAddresses" prop where+test_ParseAddresses :: TestTree+test_ParseAddresses = testProperty "parseAddresses" prop where prop = forAll gen_AddressesBytes checkMany checkMany (bytes, expectedAddrs) = case parseAddresses bytes of Nothing -> False@@ -78,32 +77,32 @@ , addressParameters addr == params ] -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (address "" Data.Map.empty))- $expect (nothing (parseAddress ""))+ Nothing @=? address "" Data.Map.empty+ Nothing @=? parseAddress "" -- no colon- $expect (nothing (parseAddress "a"))+ Nothing @=? parseAddress "a" -- no equals sign- $expect (nothing (parseAddress "a:b"))+ Nothing @=? parseAddress "a:b" -- no parameter -- TODO: should this be OK? what about the trailing comma rule?- $expect (nothing (parseAddress "a:,"))+ Nothing @=? parseAddress "a:," -- no key- $expect (nothing (address "" (Data.Map.fromList [("", "c")])))- $expect (nothing (parseAddress "a:=c"))+ Nothing @=? address "" (Data.Map.fromList [("", "c")])+ Nothing @=? parseAddress "a:=c" -- no value- $expect (nothing (address "" (Data.Map.fromList [("b", "")])))- $expect (nothing (parseAddress "a:b="))+ Nothing @=? address "" (Data.Map.fromList [("b", "")])+ Nothing @=? parseAddress "a:b=" -test_FormatAddress :: Test-test_FormatAddress = property "formatAddress" prop where+test_FormatAddress :: TestTree+test_FormatAddress = testProperty "formatAddress" prop where prop = forAll gen_Address check where check (method, params) = let Just addr = address method params@@ -115,8 +114,8 @@ , shown == "Address " ++ show bytes ] -test_FormatAddresses :: Test-test_FormatAddresses = property "formatAddresses" prop where+test_FormatAddresses :: TestTree+test_FormatAddresses = testProperty "formatAddresses" prop where prop = forAll (smallListOf1 gen_Address) check where check pairs = let addrs = do@@ -127,28 +126,28 @@ parsed = parseAddresses bytes in parsed == Just addrs -test_GetSystemAddress :: Test-test_GetSystemAddress = assertions "getSystemAddress" $ do+test_GetSystemAddress :: TestTree+test_GetSystemAddress = testCase "getSystemAddress" $ do do addr <- withEnv "DBUS_SYSTEM_BUS_ADDRESS" Nothing getSystemAddress- $expect (just addr)- $assert (equal addr (address "unix" (Data.Map.fromList [("path", "/var/run/dbus/system_bus_socket")])))+ assertBool "can't get system address" $ isJust addr+ addr @?= address "unix" (Data.Map.fromList [("path", "/var/run/dbus/system_bus_socket")]) do addr <- withEnv "DBUS_SYSTEM_BUS_ADDRESS" (Just "a:b=c") getSystemAddress- $expect (just addr)- $assert (equal addr (address "a" (Data.Map.fromList [("b", "c")])))+ assertBool "can't get system address" $ isJust addr+ addr @?= address "a" (Data.Map.fromList [("b", "c")]) -test_GetSessionAddress :: Test-test_GetSessionAddress = assertions "getSessionAddress" $ do+test_GetSessionAddress :: TestTree+test_GetSessionAddress = testCase "getSessionAddress" $ do addr <- withEnv "DBUS_SESSION_BUS_ADDRESS" (Just "a:b=c") getSessionAddress- $expect (just addr)- $assert (equal addr (address "a" (Data.Map.fromList [("b", "c")])))+ assertBool "can't get session address" $ isJust addr+ addr @?= address "a" (Data.Map.fromList [("b", "c")]) -test_GetStarterAddress :: Test-test_GetStarterAddress = assertions "getStarterAddress" $ do+test_GetStarterAddress :: TestTree+test_GetStarterAddress = testCase "getStarterAddress" $ do addr <- withEnv "DBUS_STARTER_ADDRESS" (Just "a:b=c") getStarterAddress- $expect (just addr)- $assert (equal addr (address "a" (Data.Map.fromList [("b", "c")])))+ assertBool "can't get starter address" $ isJust addr+ addr @?= address "a" (Data.Map.fromList [("b", "c")]) gen_Address :: Gen (String, Map String String) gen_Address = gen where
tests/DBusTests/BusName.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,54 +15,56 @@ module DBusTests.BusName (test_BusName) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Data.List (intercalate)--import DBus+import Data.List (intercalate)+import Data.Maybe (isJust)+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBusTests.Util+import DBus+import DBusTests.Util -test_BusName :: Suite-test_BusName = suite "BusName"+test_BusName :: TestTree+test_BusName = testGroup "BusName" [ test_Parse , test_ParseInvalid , test_IsVariant ] -test_Parse :: Test-test_Parse = property "parse" prop where+test_Parse :: TestTree+test_Parse = testProperty "parse" prop where prop = forAll gen_BusName check check x = case parseBusName x of Nothing -> False Just parsed -> formatBusName parsed == x -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (parseBusName ""))+ Nothing @=? parseBusName "" -- well-known starting with a digit- $expect (nothing (parseBusName "foo.0bar"))+ Nothing @=? parseBusName "foo.0bar" -- well-known with one element- $expect (nothing (parseBusName "foo"))+ Nothing @=? parseBusName "foo" -- unique with one element- $expect (nothing (parseBusName ":foo"))+ Nothing @=? parseBusName ":foo" -- trailing characters- $expect (nothing (parseBusName "foo.bar!"))+ Nothing @=? parseBusName "foo.bar!" -- at most 255 characters- $expect (just (parseBusName (":0." ++ replicate 251 'y')))- $expect (just (parseBusName (":0." ++ replicate 252 'y')))- $expect (nothing (parseBusName (":0." ++ replicate 253 'y')))+ assertBool "valid parse failed"+ $ isJust (parseBusName (":0." ++ replicate 251 'y'))+ assertBool "valid parse failed"+ $ isJust (parseBusName (":0." ++ replicate 252 'y'))+ Nothing @=? parseBusName (":0." ++ replicate 253 'y') -test_IsVariant :: Test-test_IsVariant = assertions "IsVariant" $ do+test_IsVariant :: TestTree+test_IsVariant = testCase "IsVariant" $ assertVariant TypeString (busName_ "foo.bar") gen_BusName :: Gen String
tests/DBusTests/Client.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,22 +15,21 @@ module DBusTests.Client (test_Client) where -import Control.Concurrent-import Control.Exception (try)-import Control.Monad.IO.Class (liftIO)+import Control.Concurrent+import Control.Exception (try)+import Data.Word+import Test.Tasty+import Test.Tasty.HUnit import qualified Data.Map as Map-import Data.Word -import Test.Chell--import DBus+import DBus import qualified DBus.Client import qualified DBus.Socket -import DBusTests.Util (forkVar, withEnv)+import DBusTests.Util -test_Client :: Suite-test_Client = suite "Client" $+test_Client :: TestTree+test_Client = testGroup "Client" $ [ test_RequestName , test_ReleaseName , test_Call@@ -40,26 +37,27 @@ , test_AddMatch , test_AutoMethod , test_ExportIntrospection- ] ++ suiteTests suite_Connect+ , suite_Connect+ ] -test_Connect :: String -> (Address -> IO DBus.Client.Client) -> Test-test_Connect name connect = assertions name $ do+test_Connect :: String -> (Address -> IO DBus.Client.Client) -> TestTree+test_Connect name connect = testCase name $ do (addr, sockVar) <- startDummyBus clientVar <- forkVar (connect addr) -- TODO: verify that 'hello' contains expected data, and -- send a properly formatted reply.- sock <- liftIO (readMVar sockVar)- receivedHello <- liftIO (DBus.Socket.receive sock)+ sock <- readMVar sockVar+ receivedHello <- DBus.Socket.receive sock let (ReceivedMethodCall helloSerial _) = receivedHello - liftIO (DBus.Socket.send sock (methodReturn helloSerial) (\_ -> return ()))+ DBus.Socket.send sock (methodReturn helloSerial) (\_ -> return ()) - client <- liftIO (readMVar clientVar)- liftIO (DBus.Client.disconnect client)+ client <- readMVar clientVar+ DBus.Client.disconnect client -suite_Connect :: Suite-suite_Connect = suite "connect"+suite_Connect :: TestTree+suite_Connect = testGroup "connect" [ test_ConnectSystem , test_ConnectSystem_NoAddress , test_ConnectSession@@ -68,51 +66,51 @@ , test_ConnectStarter_NoAddress ] -test_ConnectSystem :: Test-test_ConnectSystem = test_Connect "connectSystem" $ \addr -> do+test_ConnectSystem :: TestTree+test_ConnectSystem = test_Connect "connectSystem" $ \addr -> withEnv "DBUS_SYSTEM_BUS_ADDRESS" (Just (formatAddress addr)) DBus.Client.connectSystem -test_ConnectSystem_NoAddress :: Test-test_ConnectSystem_NoAddress = assertions "connectSystem-no-address" $ do- $expect $ throwsEq+test_ConnectSystem_NoAddress :: TestTree+test_ConnectSystem_NoAddress = testCase "connectSystem-no-address" $+ assertException (DBus.Client.clientError "connectSystem: DBUS_SYSTEM_BUS_ADDRESS is invalid.") (withEnv "DBUS_SYSTEM_BUS_ADDRESS" (Just "invalid") DBus.Client.connectSystem) -test_ConnectSession :: Test-test_ConnectSession = test_Connect "connectSession" $ \addr -> do+test_ConnectSession :: TestTree+test_ConnectSession = test_Connect "connectSession" $ \addr -> withEnv "DBUS_SESSION_BUS_ADDRESS" (Just (formatAddress addr)) DBus.Client.connectSession -test_ConnectSession_NoAddress :: Test-test_ConnectSession_NoAddress = assertions "connectSession-no-address" $ do- $expect $ throwsEq+test_ConnectSession_NoAddress :: TestTree+test_ConnectSession_NoAddress = testCase "connectSession-no-address" $+ assertException (DBus.Client.clientError "connectSession: DBUS_SESSION_BUS_ADDRESS is missing or invalid.") (withEnv "DBUS_SESSION_BUS_ADDRESS" (Just "invalid") DBus.Client.connectSession) -test_ConnectStarter :: Test-test_ConnectStarter = test_Connect "connectStarter" $ \addr -> do+test_ConnectStarter :: TestTree+test_ConnectStarter = test_Connect "connectStarter" $ \addr -> withEnv "DBUS_STARTER_ADDRESS" (Just (formatAddress addr)) DBus.Client.connectStarter -test_ConnectStarter_NoAddress :: Test-test_ConnectStarter_NoAddress = assertions "connectStarter-no-address" $ do- $expect $ throwsEq+test_ConnectStarter_NoAddress :: TestTree+test_ConnectStarter_NoAddress = testCase "connectStarter-no-address" $+ assertException (DBus.Client.clientError "connectStarter: DBUS_STARTER_ADDRESS is missing or invalid.") (withEnv "DBUS_STARTER_ADDRESS" (Just "invalid") DBus.Client.connectStarter) -test_RequestName :: Test-test_RequestName = assertions "requestName" $ do- (sock, client) <- startConnectedClient+test_RequestName :: TestTree+test_RequestName = withConnectedClient $ \res -> testCase "requestName" $ do+ (sock, client) <- res let allFlags = [ DBus.Client.nameAllowReplacement , DBus.Client.nameReplaceExisting@@ -134,7 +132,7 @@ (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags) requestCall (requestReply [toVariant (1 :: Word32)])- $expect (equal reply DBus.Client.NamePrimaryOwner)+ reply @?= DBus.Client.NamePrimaryOwner -- NameInQueue do@@ -142,7 +140,7 @@ (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags) requestCall (requestReply [toVariant (2 :: Word32)])- $expect (equal reply DBus.Client.NameInQueue)+ reply @?= DBus.Client.NameInQueue -- NameExists do@@ -150,7 +148,7 @@ (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags) requestCall (requestReply [toVariant (3 :: Word32)])- $expect (equal reply DBus.Client.NameExists)+ reply @?= DBus.Client.NameExists -- NameAlreadyOwner do@@ -158,7 +156,7 @@ (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags) requestCall (requestReply [toVariant (4 :: Word32)])- $expect (equal reply DBus.Client.NameAlreadyOwner)+ reply @?= DBus.Client.NameAlreadyOwner -- response with empty body do@@ -166,10 +164,10 @@ (try (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags)) requestCall (requestReply [])- err <- $requireLeft tried- $expect (equal err (DBus.Client.clientError "requestName: received empty response")+ err <- requireLeft tried+ err @?= (DBus.Client.clientError "requestName: received empty response") { DBus.Client.clientErrorFatal = False- })+ } -- response with invalid body do@@ -177,10 +175,10 @@ (try (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags)) requestCall (requestReply [toVariant ""])- err <- $requireLeft tried- $expect (equal err (DBus.Client.clientError "requestName: received invalid response code (Variant \"\")")+ err <- requireLeft tried+ err @?= (DBus.Client.clientError "requestName: received invalid response code (Variant \"\")") { DBus.Client.clientErrorFatal = False- })+ } -- response with unknown result code do@@ -188,12 +186,11 @@ (DBus.Client.requestName client (busName_ "com.example.Foo") allFlags) requestCall (requestReply [toVariant (5 :: Word32)])- $expect (equal (show reply) ("UnknownRequestNameReply 5"))--test_ReleaseName :: Test-test_ReleaseName = assertions "releaseName" $ do- (sock, client) <- startConnectedClient+ show reply @?= "UnknownRequestNameReply 5" +test_ReleaseName :: TestTree+test_ReleaseName = withConnectedClient $ \res -> testCase "releaseName" $ do+ (sock, client) <- res let requestCall = (dbusCall "ReleaseName") { methodCallDestination = Just (busName_ "org.freedesktop.DBus") , methodCallBody = [toVariant "com.example.Foo"]@@ -209,7 +206,7 @@ (DBus.Client.releaseName client (busName_ "com.example.Foo")) requestCall (requestReply [toVariant (1 :: Word32)])- $expect (equal reply DBus.Client.NameReleased)+ reply @?= DBus.Client.NameReleased -- NameNonExistent do@@ -217,7 +214,7 @@ (DBus.Client.releaseName client (busName_ "com.example.Foo")) requestCall (requestReply [toVariant (2 :: Word32)])- $expect (equal reply DBus.Client.NameNonExistent)+ reply @?= DBus.Client.NameNonExistent -- NameNotOwner do@@ -225,7 +222,7 @@ (DBus.Client.releaseName client (busName_ "com.example.Foo")) requestCall (requestReply [toVariant (3 :: Word32)])- $expect (equal reply DBus.Client.NameNotOwner)+ reply @?= DBus.Client.NameNotOwner -- response with empty body do@@ -233,10 +230,10 @@ (try (DBus.Client.releaseName client (busName_ "com.example.Foo"))) requestCall (requestReply [])- err <- $requireLeft tried- $expect (equal err (DBus.Client.clientError "releaseName: received empty response")+ err <- requireLeft tried+ err @?= (DBus.Client.clientError "releaseName: received empty response") { DBus.Client.clientErrorFatal = False- })+ } -- response with invalid body do@@ -244,10 +241,10 @@ (try (DBus.Client.releaseName client (busName_ "com.example.Foo"))) requestCall (requestReply [toVariant ""])- err <- $requireLeft tried- $expect (equal err (DBus.Client.clientError "releaseName: received invalid response code (Variant \"\")")+ err <- requireLeft tried+ err @?= (DBus.Client.clientError "releaseName: received invalid response code (Variant \"\")") { DBus.Client.clientErrorFatal = False- })+ } -- response with unknown result code do@@ -255,12 +252,11 @@ (DBus.Client.releaseName client (busName_ "com.example.Foo")) requestCall (requestReply [toVariant (5 :: Word32)])- $expect (equal (show reply) ("UnknownReleaseNameReply 5"))--test_Call :: Test-test_Call = assertions "call" $ do- (sock, client) <- startConnectedClient+ show reply @?= "UnknownReleaseNameReply 5" +test_Call :: TestTree+test_Call = withConnectedClient $ \res -> testCase "call" $ do+ (sock, client) <- res let requestCall = (dbusCall "Hello") { methodCallSender = Just (busName_ "com.example.Foo") , methodCallDestination = Just (busName_ "org.freedesktop.DBus")@@ -277,14 +273,13 @@ { methodCallReplyExpected = True }) methodReturn- reply <- $requireRight response-- $expect (equal reply (methodReturn (methodReturnSerial reply)))+ reply <- requireRight response -test_CallNoReply :: Test-test_CallNoReply = assertions "callNoReply" $ do- (sock, client) <- startConnectedClient+ reply @?= methodReturn (methodReturnSerial reply) +test_CallNoReply :: TestTree+test_CallNoReply = withConnectedClient $ \res -> testCase "callNoReply" $ do+ (sock, client) <- res let requestCall = (dbusCall "Hello") { methodCallSender = Just (busName_ "com.example.Foo") , methodCallDestination = Just (busName_ "org.freedesktop.DBus")@@ -302,10 +297,9 @@ }) methodReturn -test_AddMatch :: Test-test_AddMatch = assertions "addMatch" $ do- (sock, client) <- startConnectedClient-+test_AddMatch :: TestTree+test_AddMatch = withConnectedClient $ \res -> testCase "addMatch" $ do+ (sock, client) <- res let matchRule = DBus.Client.matchAny { DBus.Client.matchSender = Just (busName_ "com.example.Foo") , DBus.Client.matchDestination = Just (busName_ "com.example.Bar")@@ -315,92 +309,90 @@ } -- might as well test this while we're at it- $expect (equal (show matchRule) "MatchRule \"sender='com.example.Foo',destination='com.example.Bar',path='/',interface='com.example.Baz',member='Qux'\"")+ show matchRule @?= "MatchRule \"sender='com.example.Foo',destination='com.example.Bar',path='/',interface='com.example.Baz',member='Qux'\"" let requestCall = (dbusCall "AddMatch") { methodCallDestination = Just (busName_ "org.freedesktop.DBus") , methodCallBody = [toVariant "type='signal',sender='com.example.Foo',destination='com.example.Bar',path='/',interface='com.example.Baz',member='Qux'"] } - signalVar <- liftIO newEmptyMVar+ signalVar <- newEmptyMVar -- add a listener for the given signal- stubMethodCall sock+ _ <- stubMethodCall sock (DBus.Client.addMatch client matchRule (putMVar signalVar)) requestCall methodReturn -- ignored signal- liftIO (DBus.Socket.send sock+ DBus.Socket.send sock (signal (objectPath_ "/") (interfaceName_ "com.example.Baz") (memberName_ "Qux"))- (\_ -> return ()))- $assert (isEmptyMVar signalVar)+ (\_ -> return ())+ isEmptyMVar signalVar >>= assertBool "signal not ignored" -- matched signal let matchedSignal = (signal (objectPath_ "/") (interfaceName_ "com.example.Baz") (memberName_ "Qux")) { signalSender = Just (busName_ "com.example.Foo") , signalDestination = Just (busName_ "com.example.Bar") }- liftIO (DBus.Socket.send sock matchedSignal (\_ -> return ()))- received <- liftIO (takeMVar signalVar)- $expect (equal received matchedSignal)--test_AutoMethod :: Test-test_AutoMethod = assertions "autoMethod" $ do- (sock, client) <- startConnectedClient+ DBus.Socket.send sock matchedSignal (\_ -> return ())+ received <- takeMVar signalVar+ received @?= matchedSignal +test_AutoMethod :: TestTree+test_AutoMethod = withConnectedClient $ \res -> testCase "autoMethod" $ do+ (sock, client) <- res let methodMax = (\x y -> return (max x y)) :: Word32 -> Word32 -> IO Word32 let methodPair = (\x y -> return (x, y)) :: String -> String -> IO (String, String) - liftIO (DBus.Client.export client (objectPath_ "/")+ DBus.Client.export client (objectPath_ "/") [ DBus.Client.autoMethod (interfaceName_ "com.example.Foo") (memberName_ "Max") methodMax , DBus.Client.autoMethod (interfaceName_ "com.example.Foo") (memberName_ "Pair") methodPair- ])+ ] -- valid call to com.example.Foo.Max do (serial, response) <- callClientMethod sock "/" "com.example.Foo" "Max" [toVariant (2 :: Word32), toVariant (1 :: Word32)]- $expect (equal response (Right (methodReturn serial)+ response @?= Right (methodReturn serial) { methodReturnBody = [toVariant (2 :: Word32)]- }))+ } -- valid call to com.example.Foo.Pair do (serial, response) <- callClientMethod sock "/" "com.example.Foo" "Pair" [toVariant "x", toVariant "y"]- $expect (equal response (Right (methodReturn serial)+ response @?= Right (methodReturn serial) { methodReturnBody = [toVariant "x", toVariant "y"]- }))+ } -- invalid call to com.example.Foo.Max do (serial, response) <- callClientMethod sock "/" "com.example.Foo" "Max" [toVariant "x", toVariant "y"]- $expect (equal response (Left (methodError serial (errorName_ "org.freedesktop.DBus.Error.InvalidParameters"))))--test_ExportIntrospection :: Test-test_ExportIntrospection = assertions "exportIntrospection" $ do- (sock, client) <- startConnectedClient+ response @?= Left (methodError serial (errorName_ "org.freedesktop.DBus.Error.InvalidParameters")) - liftIO (DBus.Client.export client (objectPath_ "/foo")+test_ExportIntrospection :: TestTree+test_ExportIntrospection = withConnectedClient $ \res -> testCase "exportIntrospection" $ do+ (sock, client) <- res+ DBus.Client.export client (objectPath_ "/foo") [ DBus.Client.autoMethod (interfaceName_ "com.example.Foo") (memberName_ "Method1") (undefined :: String -> IO ()) , DBus.Client.autoMethod (interfaceName_ "com.example.Foo") (memberName_ "Method2") (undefined :: String -> IO String) , DBus.Client.autoMethod (interfaceName_ "com.example.Foo") (memberName_ "Method3") (undefined :: String -> IO (String, String))- ])+ ] let introspect path = do (_, response) <- callClientMethod sock path "org.freedesktop.DBus.Introspectable" "Introspect" []- ret <- $requireRight response+ ret <- requireRight response let body = methodReturnBody ret - $assert (equal (length body) 1)+ length body @?= 1 let Just xml = fromVariant (head body) return xml root <- introspect "/"- $expect (equalLines root+ root @?= "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n\ \<node name='/'>\ \<interface name='org.freedesktop.DBus.Introspectable'>\@@ -409,10 +401,10 @@ \</method>\ \</interface>\ \<node name='foo'></node>\- \</node>")+ \</node>" foo <- introspect "/foo"- $expect (equalLines foo+ foo @?= "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN' 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n\ \<node name='/foo'>\ \<interface name='com.example.Foo'>\@@ -434,57 +426,58 @@ \<arg name='' type='s' direction='out'/>\ \</method>\ \</interface>\- \</node>")+ \</node>" -startDummyBus :: Assertions (Address, MVar DBus.Socket.Socket)+startDummyBus :: IO (Address, MVar DBus.Socket.Socket) startDummyBus = do- uuid <- liftIO randomUUID+ uuid <- randomUUID let Just addr = address "unix" (Map.fromList [("abstract", formatUUID uuid)])- listener <- liftIO (DBus.Socket.listen addr)+ listener <- DBus.Socket.listen addr sockVar <- forkVar (DBus.Socket.accept listener) return (DBus.Socket.socketListenerAddress listener, sockVar) -startConnectedClient :: Assertions (DBus.Socket.Socket, DBus.Client.Client)-startConnectedClient = do- (addr, sockVar) <- startDummyBus- clientVar <- forkVar (DBus.Client.connect addr)-- -- TODO: verify that 'hello' contains expected data, and- -- send a properly formatted reply.- sock <- liftIO (readMVar sockVar)- receivedHello <- liftIO (DBus.Socket.receive sock)- let (ReceivedMethodCall helloSerial _) = receivedHello+withConnectedClient :: (IO (DBus.Socket.Socket, DBus.Client.Client) -> TestTree) -> TestTree+withConnectedClient = withResource create remove+ where+ create = do+ (addr, sockVar) <- startDummyBus+ clientVar <- forkVar (DBus.Client.connect addr) - liftIO (DBus.Socket.send sock (methodReturn helloSerial) (\_ -> return ()))+ -- TODO: verify that 'hello' contains expected data, and+ -- send a properly formatted reply.+ sock <- readMVar sockVar+ receivedHello <- DBus.Socket.receive sock+ let (ReceivedMethodCall helloSerial _) = receivedHello - client <- liftIO (readMVar clientVar)- afterTest (DBus.Client.disconnect client)+ DBus.Socket.send sock (methodReturn helloSerial) (\_ -> return ()) - return (sock, client)+ client <- readMVar clientVar+ return (sock, client)+ remove (_, client) = DBus.Client.disconnect client -stubMethodCall :: DBus.Socket.Socket -> IO a -> MethodCall -> (Serial -> MethodReturn) -> Assertions a+stubMethodCall :: DBus.Socket.Socket -> IO a -> MethodCall -> (Serial -> MethodReturn) -> IO a stubMethodCall sock io expectedCall respond = do var <- forkVar io - receivedCall <- liftIO (DBus.Socket.receive sock)+ receivedCall <- DBus.Socket.receive sock let ReceivedMethodCall callSerial call = receivedCall- $expect (equal expectedCall call)+ expectedCall @?= call - liftIO (DBus.Socket.send sock (respond callSerial) (\_ -> return ()))+ DBus.Socket.send sock (respond callSerial) (\_ -> return ()) - liftIO (takeMVar var)+ takeMVar var -callClientMethod :: DBus.Socket.Socket -> String -> String -> String -> [Variant] -> Assertions (Serial, Either MethodError MethodReturn)+callClientMethod :: DBus.Socket.Socket -> String -> String -> String -> [Variant] -> IO (Serial, Either MethodError MethodReturn) callClientMethod sock path iface name body = do let call = (methodCall (objectPath_ path) (interfaceName_ iface) (memberName_ name)) { methodCallBody = body }- serial <- liftIO (DBus.Socket.send sock call return)- resp <- liftIO (DBus.Socket.receive sock)+ serial <- DBus.Socket.send sock call return+ resp <- DBus.Socket.receive sock case resp of ReceivedMethodReturn _ ret -> return (serial, Right ret) ReceivedMethodError _ err -> return (serial, Left err)- _ -> $die "callClientMethod: unexpected response to method call"+ _ -> assertFailure "callClientMethod: unexpected response to method call" >> undefined dbusCall :: String -> MethodCall dbusCall member = methodCall (objectPath_ "/org/freedesktop/DBus") (interfaceName_ "org.freedesktop.DBus") (memberName_ member)
tests/DBusTests/ErrorName.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,51 +15,54 @@ module DBusTests.ErrorName (test_ErrorName) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Data.List (intercalate)+import Data.List (intercalate)+import Data.Maybe+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus -import DBusTests.Util+import DBusTests.Util -test_ErrorName :: Suite-test_ErrorName = suite "ErrorName"+test_ErrorName :: TestTree+test_ErrorName = testGroup "ErrorName" [ test_Parse , test_ParseInvalid , test_IsVariant ] -test_Parse :: Test-test_Parse = property "parse" prop where+test_Parse :: TestTree+test_Parse = testProperty "parse" prop where prop = forAll gen_ErrorName check check x = case parseErrorName x of Nothing -> False Just parsed -> formatErrorName parsed == x -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (parseErrorName ""))+ Nothing @=? parseErrorName "" -- one element- $expect (nothing (parseErrorName "foo"))+ Nothing @=? parseErrorName "foo" -- element starting with a digit- $expect (nothing (parseErrorName "foo.0bar"))+ Nothing @=? parseErrorName "foo.0bar" -- trailing characters- $expect (nothing (parseErrorName "foo.bar!"))+ Nothing @=? parseErrorName "foo.bar!" -- at most 255 characters- $expect (just (parseErrorName ("f." ++ replicate 252 'y')))- $expect (just (parseErrorName ("f." ++ replicate 253 'y')))- $expect (nothing (parseErrorName ("f." ++ replicate 254 'y')))+ assertBool "valid parse failed"+ $ isJust (parseErrorName ("f." ++ replicate 252 'y'))+ assertBool "valid parse failed"+ $ isJust (parseErrorName ("f." ++ replicate 253 'y'))+ Nothing @=? parseErrorName ("f." ++ replicate 254 'y') -test_IsVariant :: Test-test_IsVariant = assertions "IsVariant" $ do+test_IsVariant :: TestTree+test_IsVariant = testCase "IsVariant" $ assertVariant TypeString (errorName_ "foo.bar") gen_ErrorName :: Gen String
tests/DBusTests/Integration.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-} -- Copyright (C) 2012 John Millikin <john@john-millikin.com> --@@ -18,79 +17,78 @@ module DBusTests.Integration (test_Integration) where -import Test.Chell--import Control.Exception (finally)-import Control.Monad.IO.Class (liftIO)-import System.Directory (removeFile)-import System.Exit-import System.IO (hGetLine, writeFile)-import System.Process+import Control.Exception (finally)+import System.Directory (removeFile)+import System.Exit+import System.IO (hGetLine)+import System.Process+import Test.Tasty+import Test.Tasty.HUnit -import DBus-import DBus.Socket-import DBus.Client-import DBusTests.Util (getTempPath)+import DBus+import DBus.Socket+import DBus.Client+import DBusTests.Util -test_Integration :: Suite-test_Integration = suite "integration"+test_Integration :: TestTree+test_Integration = testGroup "Integration" [ test_Socket , test_Client ] -test_Socket :: Test+test_Socket :: TestTree test_Socket = withDaemon "socket" $ \addr -> do let hello = (methodCall "/org/freedesktop/DBus" "org.freedesktop.DBus" "Hello") { methodCallDestination = Just "org.freedesktop.DBus" } - sock <- liftIO (open addr)- serial <- liftIO (send sock hello return)- $expect (greaterEqual (serialValue serial) 1)+ sock <- open addr+ serial <- send sock hello return+ assertBool "invalid serial" $ serialValue serial >= 1 - received <- liftIO (receive sock)+ received <- receive sock let ReceivedMethodReturn _ ret = received- $expect (equal (methodReturnSerial ret) serial)- $expect (equal (methodReturnSender ret) (Just "org.freedesktop.DBus"))+ methodReturnSerial ret @?= serial+ methodReturnSender ret @?= Just "org.freedesktop.DBus" - liftIO (close sock)+ close sock -test_Client :: Test+test_Client :: TestTree test_Client = withDaemon "client" $ \addr -> do- clientA <- liftIO (connect addr)- clientB <- liftIO (connect addr)+ clientA <- connect addr+ clientB <- connect addr - liftIO (export clientA "/"+ export clientA "/" [ method "com.example.Echo" "Echo" (signature_ [TypeString]) (signature_ []) ( \msg -> if map variantType (methodCallBody msg) == [TypeString] then return (replyReturn (methodCallBody msg)) else return (replyError "com.example.Error" [toVariant ("bad body: " ++ show (methodCallBody msg))]))- ])+ ] -- TODO: get bus address of clientA with a function let busAddrA = ":1.0" -- Successful call let bodyGood = [toVariant ("test" :: String)]- retGood <- liftIO (call clientB (methodCall "/" "com.example.Echo" "Echo")+ retGood <- call clientB (methodCall "/" "com.example.Echo" "Echo") { methodCallDestination = Just busAddrA , methodCallBody = bodyGood- })- ret <- $requireRight retGood- $expect (equal (methodReturnBody ret) bodyGood)+ }+ ret <- requireRight retGood+ methodReturnBody ret @?= bodyGood -- Failed call let bodyBad = [toVariant True]- retBad <- liftIO (call clientB (methodCall "/" "com.example.Echo" "Echo")+ retBad <- call clientB (methodCall "/" "com.example.Echo" "Echo") { methodCallDestination = Just busAddrA , methodCallBody = bodyBad- })- err <- $requireLeft retBad- $expect (equal (methodErrorName err) "com.example.Error")- $expect (equal (methodErrorBody err) [toVariant ("bad body: [Variant True]" :: String)])+ }+ err <- requireLeft retBad+ methodErrorName err @?= "com.example.Error"+ methodErrorBody err @?= [toVariant ("bad body: [Variant True]" :: String)] - liftIO (disconnect clientA)- liftIO (disconnect clientB)+ disconnect clientA+ disconnect clientB configFileContent :: String configFileContent = "\@@ -110,13 +108,13 @@ \ </policy>\ \</busconfig>" -withDaemon :: String -> (Address -> Assertions ()) -> Test-withDaemon name io = test name $ \opts -> do+withDaemon :: String -> (Address -> Assertion) -> TestTree+withDaemon name io = testCase name $ do (versionExit, _, _) <- readProcessWithExitCode "dbus-daemon" ["--version"] "" case versionExit of- ExitFailure _ -> return TestSkipped+ ExitFailure _ -> assertFailure $ "dbus-daemon failed: " ++ show versionExit ExitSuccess -> do- configFilePath <- liftIO getTempPath+ configFilePath <- getTempPath writeFile configFilePath configFileContent daemon <- createProcess (proc "dbus-daemon" ["--config-file=" ++ configFilePath, "--print-address"]) { std_out = CreatePipe@@ -127,8 +125,8 @@ (do addrString <- hGetLine daemonStdout case parseAddress addrString of- Nothing -> return (TestAborted [] ("dbus-daemon returned invalid address: " ++ show addrString))- Just addr -> runTest (assertions name (io addr)) opts)+ Nothing -> assertFailure $ "dbus-daemon returned invalid address: " ++ show addrString+ Just addr -> io addr) (do terminateProcess daemonProc _ <- waitForProcess daemonProc
tests/DBusTests/InterfaceName.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,51 +15,54 @@ module DBusTests.InterfaceName (test_InterfaceName) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Data.List (intercalate)+import Data.List (intercalate)+import Data.Maybe+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus -import DBusTests.Util+import DBusTests.Util -test_InterfaceName :: Suite-test_InterfaceName = suite "InterfaceName"+test_InterfaceName :: TestTree+test_InterfaceName = testGroup "InterfaceName" [ test_Parse , test_ParseInvalid , test_IsVariant ] -test_Parse :: Test-test_Parse = property "parse" prop where+test_Parse :: TestTree+test_Parse = testProperty "parse" prop where prop = forAll gen_InterfaceName check check x = case parseInterfaceName x of Nothing -> False Just parsed -> formatInterfaceName parsed == x -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (parseInterfaceName ""))+ Nothing @=? parseInterfaceName "" -- one element- $expect (nothing (parseInterfaceName "foo"))+ Nothing @=? parseInterfaceName "foo" -- element starting with a digit- $expect (nothing (parseInterfaceName "foo.0bar"))+ Nothing @=? parseInterfaceName "foo.0bar" -- trailing characters- $expect (nothing (parseInterfaceName "foo.bar!"))+ Nothing @=? parseInterfaceName "foo.bar!" -- at most 255 characters- $expect (just (parseInterfaceName ("f." ++ replicate 252 'y')))- $expect (just (parseInterfaceName ("f." ++ replicate 253 'y')))- $expect (nothing (parseInterfaceName ("f." ++ replicate 254 'y')))+ assertBool "valid parse failed"+ $ isJust (parseInterfaceName ("f." ++ replicate 252 'y'))+ assertBool "valid parse failed"+ $ isJust (parseInterfaceName ("f." ++ replicate 253 'y'))+ Nothing @=? parseInterfaceName ("f." ++ replicate 254 'y') -test_IsVariant :: Test-test_IsVariant = assertions "IsVariant" $ do+test_IsVariant :: TestTree+test_IsVariant = testCase "IsVariant" $ assertVariant TypeString (interfaceName_ "foo.bar") gen_InterfaceName :: Gen String
tests/DBusTests/Introspection.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,83 +15,81 @@ module DBusTests.Introspection (test_Introspection) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Control.Applicative ((<$>), (<*>))-import Control.Monad (liftM, liftM2)+import Control.Applicative ((<$>), (<*>))+import Control.Monad (liftM, liftM2)+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus import qualified DBus.Introspection as Introspection -import DBusTests.InterfaceName ()-import DBusTests.MemberName ()-import DBusTests.ObjectPath ()-import DBusTests.Signature ()-import DBusTests.Util (halfSized)+import DBusTests.InterfaceName ()+import DBusTests.MemberName ()+import DBusTests.ObjectPath ()+import DBusTests.Signature ()+import DBusTests.Util (halfSized) -test_Introspection :: Suite-test_Introspection = suite "Introspection"+test_Introspection :: TestTree+test_Introspection = testGroup "Introspection" [ test_XmlPassthrough , test_XmlParse , test_XmlParseFailed , test_XmlWriteFailed ] -test_XmlPassthrough :: Test-test_XmlPassthrough = property "xml-passthrough" $ \obj -> let+test_XmlPassthrough :: TestTree+test_XmlPassthrough = testProperty "xml-passthrough" $ \obj -> let path = Introspection.objectPath obj Just xml = Introspection.formatXML obj in Introspection.parseXML path xml == Just obj -test_XmlParse :: Test-test_XmlParse = assertions "xml-parse" $ do+test_XmlParse :: TestTree+test_XmlParse = testCase "xml-parse" $ do -- root object path can be inferred- $expect (equal- (Introspection.parseXML (objectPath_ "/") "<node><node name='foo'/></node>")- (Just (Introspection.object (objectPath_ "/"))+ Introspection.parseXML (objectPath_ "/") "<node><node name='foo'/></node>"+ @?= Just (Introspection.object (objectPath_ "/")) { Introspection.objectChildren = [ Introspection.object (objectPath_ "/foo") ] }- )) -test_XmlParseFailed :: Test-test_XmlParseFailed = assertions "xml-parse-failed" $ do- $expect (nothing (Introspection.parseXML (objectPath_ "/") "<invalid>"))- $expect (nothing (Introspection.parseXML (objectPath_ "/") "<invalid/>"))+test_XmlParseFailed :: TestTree+test_XmlParseFailed = testCase "xml-parse-failed" $ do+ Nothing @=? Introspection.parseXML (objectPath_ "/") "<invalid>"+ Nothing @=? Introspection.parseXML (objectPath_ "/") "<invalid/>" -- invalid property access- $expect (nothing (Introspection.parseXML (objectPath_ "/")+ Nothing @=? Introspection.parseXML (objectPath_ "/") "<node>\ \ <interface name='com.example.Foo'>\ \ <property type='s' access='invalid'>\ \ </property>\ \ </interface>\- \</node>"))+ \</node>" -- invalid parameter type- $expect (nothing (Introspection.parseXML (objectPath_ "/")+ Nothing @=? Introspection.parseXML (objectPath_ "/") "<node>\ \ <interface name='com.example.Foo'>\ \ <method name='Foo'>\ \ <arg type='yy'/>\ \ </method>\ \ </interface>\- \</node>"))+ \</node>" -test_XmlWriteFailed :: Test-test_XmlWriteFailed = assertions "xml-write-failed" $ do+test_XmlWriteFailed :: TestTree+test_XmlWriteFailed = testCase "xml-write-failed" $ do -- child's object path isn't under parent's- $expect (nothing (Introspection.formatXML (Introspection.object (objectPath_ "/foo"))+ Nothing @=? Introspection.formatXML (Introspection.object (objectPath_ "/foo")) { Introspection.objectChildren = [ Introspection.object (objectPath_ "/bar") ]- }))+ } -- invalid type- $expect (nothing (Introspection.formatXML (Introspection.object (objectPath_ "/foo"))+ Nothing @=? Introspection.formatXML (Introspection.object (objectPath_ "/foo")) { Introspection.objectInterfaces = [ (Introspection.interface (interfaceName_ "/bar")) { Introspection.interfaceProperties =@@ -101,7 +97,7 @@ ] } ]- }))+ } instance Arbitrary Type where arbitrary = oneof [atom, container] where
tests/DBusTests/MemberName.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,46 +15,50 @@ module DBusTests.MemberName (test_MemberName) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)+import Data.Maybe+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus -import DBusTests.Util+import DBusTests.Util -test_MemberName :: Suite-test_MemberName = suite "MemberName"+test_MemberName :: TestTree+test_MemberName = testGroup "MemberName" [ test_Parse , test_ParseInvalid , test_IsVariant ] -test_Parse :: Test-test_Parse = property "parse" prop where+test_Parse :: TestTree+test_Parse = testProperty "parse" prop where prop = forAll gen_MemberName check check x = case parseMemberName x of Nothing -> False Just parsed -> formatMemberName parsed == x -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (parseMemberName ""))+ Nothing @=? parseMemberName "" -- starts with a digit- $expect (nothing (parseMemberName "@foo"))+ Nothing @=? parseMemberName "@foo" -- trailing chars- $expect (nothing (parseMemberName "foo!"))+ Nothing @=? parseMemberName "foo!" -- at most 255 characters- $expect (just (parseMemberName (replicate 254 'y')))- $expect (just (parseMemberName (replicate 255 'y')))- $expect (nothing (parseMemberName (replicate 256 'y')))+ assertBool "valid parse failed"+ $ isJust (parseMemberName (replicate 254 'y'))+ assertBool "valid parse failed"+ $ isJust (parseMemberName (replicate 255 'y'))+ Nothing @=? parseMemberName (replicate 256 'y') -test_IsVariant :: Test-test_IsVariant = assertions "IsVariant" $ do+test_IsVariant :: TestTree+test_IsVariant = testCase "IsVariant" $ assertVariant TypeString (memberName_ "foo") gen_MemberName :: Gen String
tests/DBusTests/Message.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,36 +15,33 @@ module DBusTests.Message (test_Message) where -import Test.Chell+import Test.Tasty+import Test.Tasty.HUnit import DBus -test_Message :: Suite-test_Message = suite "Message"+test_Message :: TestTree+test_Message = testGroup "Message" [ test_MethodErrorMessage ] -test_MethodErrorMessage :: Test-test_MethodErrorMessage = assertions "methodErrorMessage" $ do+test_MethodErrorMessage :: TestTree+test_MethodErrorMessage = testCase "methodErrorMessage" $ do let emptyError = methodError firstSerial (errorName_ "com.example.Error") - $expect (equal- "(no error message)"- (methodErrorMessage emptyError+ "(no error message)" @=?+ methodErrorMessage emptyError { methodErrorBody = []- }))- $expect (equal- "(no error message)"- (methodErrorMessage emptyError+ }+ "(no error message)" @=?+ methodErrorMessage emptyError { methodErrorBody = [toVariant True]- }))- $expect (equal- "(no error message)"- (methodErrorMessage emptyError+ }+ "(no error message)" @=?+ methodErrorMessage emptyError { methodErrorBody = [toVariant ""]- }))- $expect (equal- "error"- (methodErrorMessage emptyError+ }+ "error" @=?+ methodErrorMessage emptyError { methodErrorBody = [toVariant "error"]- }))+ }
tests/DBusTests/ObjectPath.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,43 +15,43 @@ module DBusTests.ObjectPath (test_ObjectPath) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding (property)--import Data.List (intercalate)+import Data.List (intercalate)+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus -test_ObjectPath :: Suite-test_ObjectPath = suite "ObjectPath"+test_ObjectPath :: TestTree+test_ObjectPath = testGroup "ObjectPath" [ test_Parse , test_ParseInvalid ] -test_Parse :: Test-test_Parse = property "parse" prop where+test_Parse :: TestTree+test_Parse = testProperty "parse" prop where prop = forAll gen_ObjectPath check check x = case parseObjectPath x of Nothing -> False Just parsed -> formatObjectPath parsed == x -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- empty- $expect (nothing (parseObjectPath ""))+ Nothing @=? parseObjectPath "" -- bad char- $expect (nothing (parseObjectPath "/f!oo"))+ Nothing @=? parseObjectPath "/f!oo" -- ends with a slash- $expect (nothing (parseObjectPath "/foo/"))+ Nothing @=? parseObjectPath "/foo/" -- empty element- $expect (nothing (parseObjectPath "/foo//bar"))+ Nothing @=? parseObjectPath "/foo//bar" -- trailing chars- $expect (nothing (parseObjectPath "/foo!"))+ Nothing @=? parseObjectPath "/foo!" gen_ObjectPath :: Gen String gen_ObjectPath = gen where
tests/DBusTests/Serialization.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-} -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> --@@ -18,65 +17,65 @@ module DBusTests.Serialization (test_Serialization) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding ((.&.), property)--import Data.ByteString (ByteString)-import Data.Text (Text)-import Data.Int (Int16, Int32, Int64)-import Data.Word (Word8, Word16, Word32, Word64)-import Data.Map (Map)+import Data.ByteString (ByteString)+import Data.Int (Int16, Int32, Int64)+import Data.Map (Map)+import Data.Text (Text)+import Data.Word (Word8, Word16, Word32, Word64)+import Foreign.C.Types (CInt)+import System.Posix.Types (Fd)+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck import qualified Data.Map import qualified Data.Vector-import Foreign.C.Types (CInt)-import System.Posix.Types (Fd) -import DBus+import DBus import qualified DBus.Internal.Types -import DBusTests.BusName ()-import DBusTests.ErrorName ()-import DBusTests.InterfaceName ()-import DBusTests.MemberName ()-import DBusTests.ObjectPath ()-import DBusTests.Signature ()-import DBusTests.Util (smallListOf)+import DBusTests.BusName ()+import DBusTests.ErrorName ()+import DBusTests.InterfaceName ()+import DBusTests.MemberName ()+import DBusTests.ObjectPath ()+import DBusTests.Signature ()+import DBusTests.Util (smallListOf) -test_Serialization :: Suite-test_Serialization = suite "Serialization"+test_Serialization :: TestTree+test_Serialization = testGroup "Serialization" [ test_MethodCall , test_MethodReturn , test_MethodError , test_Signal ] -test_MethodCall :: Test-test_MethodCall = property "MethodCall" prop where+test_MethodCall :: TestTree+test_MethodCall = testProperty "MethodCall" prop where prop = forAll gen_MethodCall check check msg endianness serial = let Right bytes = marshal endianness serial msg Right received = unmarshal bytes in ReceivedMethodCall serial msg == received -test_MethodReturn :: Test-test_MethodReturn = property "MethodReturn" prop where+test_MethodReturn :: TestTree+test_MethodReturn = testProperty "MethodReturn" prop where prop = forAll gen_MethodReturn check check msg endianness serial = let Right bytes = marshal endianness serial msg Right received = unmarshal bytes in ReceivedMethodReturn serial msg == received -test_MethodError :: Test-test_MethodError = property "MethodError" prop where+test_MethodError :: TestTree+test_MethodError = testProperty "MethodError" prop where prop = forAll gen_MethodError check check msg endianness serial = let Right bytes = marshal endianness serial msg Right received = unmarshal bytes in ReceivedMethodError serial msg == received -test_Signal :: Test-test_Signal = property "Signal" prop where+test_Signal :: TestTree+test_Signal = testProperty "Signal" prop where prop = forAll gen_Signal check check msg endianness serial = let Right bytes = marshal endianness serial msg
tests/DBusTests/Signature.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -17,16 +15,18 @@ module DBusTests.Signature (test_Signature) where -import Test.Chell-import Test.Chell.QuickCheck-import Test.QuickCheck hiding ((.&.), property)+import Data.Maybe+import Test.QuickCheck+import Test.Tasty+import Test.Tasty.HUnit+import Test.Tasty.QuickCheck -import DBus+import DBus -import DBusTests.Util+import DBusTests.Util -test_Signature :: Suite-test_Signature = suite "Signature"+test_Signature :: TestTree+test_Signature = testGroup "Signature" [ test_BuildSignature , test_ParseSignature , test_ParseInvalid@@ -35,77 +35,80 @@ , test_ShowType ] -test_BuildSignature :: Test-test_BuildSignature = property "signature" prop where+test_BuildSignature :: TestTree+test_BuildSignature = testProperty "signature" prop where prop = forAll gen_SignatureTypes check check types = case signature types of Nothing -> False Just sig -> signatureTypes sig == types -test_ParseSignature :: Test-test_ParseSignature = property "parseSignature" prop where+test_ParseSignature :: TestTree+test_ParseSignature = testProperty "parseSignature" prop where prop = forAll gen_SignatureString check check (s, types) = case parseSignature s of Nothing -> False Just sig -> signatureTypes sig == types -test_ParseInvalid :: Test-test_ParseInvalid = assertions "parse-invalid" $ do+test_ParseInvalid :: TestTree+test_ParseInvalid = testCase "parse-invalid" $ do -- at most 255 characters- $expect (just (parseSignature (replicate 254 'y')))- $expect (just (parseSignature (replicate 255 'y')))- $expect (nothing (parseSignature (replicate 256 'y')))+ assertBool "valid parse failed" $+ isJust (parseSignature (replicate 254 'y'))+ assertBool "valid parse failed" $+ isJust (parseSignature (replicate 255 'y'))+ Nothing @=? parseSignature (replicate 256 'y') -- length also enforced by 'signature'- $expect (just (signature (replicate 255 TypeWord8)))- $expect (nothing (signature (replicate 256 TypeWord8)))+ assertBool "valid parse failed" $+ isJust (signature (replicate 255 TypeWord8))+ Nothing @=? signature (replicate 256 TypeWord8) -- struct code- $expect (nothing (parseSignature "r"))+ Nothing @=? parseSignature "r" -- empty struct- $expect (nothing (parseSignature "()"))- $expect (nothing (signature [TypeStructure []]))+ Nothing @=? parseSignature "()"+ Nothing @=? signature [TypeStructure []] -- dict code- $expect (nothing (parseSignature "e"))+ Nothing @=? parseSignature "e" -- non-atomic dict key- $expect (nothing (parseSignature "a{vy}"))- $expect (nothing (signature [TypeDictionary TypeVariant TypeVariant]))+ Nothing @=? parseSignature "a{vy}"+ Nothing @=? signature [TypeDictionary TypeVariant TypeVariant] -test_FormatSignature :: Test-test_FormatSignature = property "formatSignature" prop where+test_FormatSignature :: TestTree+test_FormatSignature = testProperty "formatSignature" prop where prop = forAll gen_SignatureString check check (s, _) = let Just sig = parseSignature s in formatSignature sig == s -test_IsAtom :: Test-test_IsAtom = assertions "IsAtom" $ do+test_IsAtom :: TestTree+test_IsAtom = testCase "IsAtom" $ do let Just sig = signature [] assertAtom TypeSignature sig -test_ShowType :: Test-test_ShowType = assertions "show-type" $ do- $expect (equal "Bool" (show TypeBoolean))- $expect (equal "Bool" (show TypeBoolean))- $expect (equal "Word8" (show TypeWord8))- $expect (equal "Word16" (show TypeWord16))- $expect (equal "Word32" (show TypeWord32))- $expect (equal "Word64" (show TypeWord64))- $expect (equal "Int16" (show TypeInt16))- $expect (equal "Int32" (show TypeInt32))- $expect (equal "Int64" (show TypeInt64))- $expect (equal "Double" (show TypeDouble))- $expect (equal "UnixFd" (show TypeUnixFd))- $expect (equal "String" (show TypeString))- $expect (equal "Signature" (show TypeSignature))- $expect (equal "ObjectPath" (show TypeObjectPath))- $expect (equal "Variant" (show TypeVariant))- $expect (equal "[Word8]" (show (TypeArray TypeWord8)))- $expect (equal "Dict Word8 (Dict Word8 Word8)" (show (TypeDictionary TypeWord8 (TypeDictionary TypeWord8 TypeWord8))))- $expect (equal "(Word8, Word16)" (show (TypeStructure [TypeWord8, TypeWord16])))+test_ShowType :: TestTree+test_ShowType = testCase "show-type" $ do+ "Bool" @=? show TypeBoolean+ "Bool" @=? show TypeBoolean+ "Word8" @=? show TypeWord8+ "Word16" @=? show TypeWord16+ "Word32" @=? show TypeWord32+ "Word64" @=? show TypeWord64+ "Int16" @=? show TypeInt16+ "Int32" @=? show TypeInt32+ "Int64" @=? show TypeInt64+ "Double" @=? show TypeDouble+ "UnixFd" @=? show TypeUnixFd+ "String" @=? show TypeString+ "Signature" @=? show TypeSignature+ "ObjectPath" @=? show TypeObjectPath+ "Variant" @=? show TypeVariant+ "[Word8]" @=? show (TypeArray TypeWord8)+ "Dict Word8 (Dict Word8 Word8)" @=? show (TypeDictionary TypeWord8 (TypeDictionary TypeWord8 TypeWord8))+ "(Word8, Word16)" @=? show (TypeStructure [TypeWord8, TypeWord16]) gen_SignatureTypes :: Gen [Type] gen_SignatureTypes = do
tests/DBusTests/Socket.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-} -- Copyright (C) 2012 John Millikin <john@john-millikin.com> --@@ -18,70 +17,64 @@ module DBusTests.Socket (test_Socket) where -import Test.Chell--import Control.Concurrent-import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Concurrent+import Control.Exception+import Test.Tasty+import Test.Tasty.HUnit import qualified Data.Map as Map -import DBus-import DBus.Socket-import DBus.Transport+import DBus+import DBus.Socket+import DBus.Transport -import DBusTests.Util (forkVar)+import DBusTests.Util (forkVar) -test_Socket :: Suite-test_Socket = suite "Socket"+test_Socket :: TestTree+test_Socket = testGroup "Socket" [ test_Listen , test_ListenWith_CustomAuth , test_SendReceive ] -test_Listen :: Test-test_Listen = assertions "listen" $ do- uuid <- liftIO randomUUID+test_Listen :: TestTree+test_Listen = testCase "listen" $ do+ uuid <- randomUUID let Just addr = address "unix" (Map.fromList [ ("abstract", formatUUID uuid) ]) - listener <- liftIO (listen addr)- afterTest (closeListener listener)-- acceptedVar <- forkVar (accept listener)- openedVar <- forkVar (open addr)-- sock1 <- liftIO (takeMVar acceptedVar)- afterTest (close sock1)+ bracket (listen addr) closeListener $ \listener -> do+ acceptedVar <- forkVar (accept listener)+ openedVar <- forkVar (open addr) - sock2 <- liftIO (takeMVar openedVar)- afterTest (close sock2)+ sock1 <- takeMVar acceptedVar+ sock2 <- takeMVar openedVar+ close sock1+ close sock2 -test_ListenWith_CustomAuth :: Test-test_ListenWith_CustomAuth = assertions "listenWith-custom-auth" $ do- uuid <- liftIO randomUUID+test_ListenWith_CustomAuth :: TestTree+test_ListenWith_CustomAuth = testCase "listenWith-custom-auth" $ do+ uuid <- randomUUID let Just addr = address "unix" (Map.fromList [ ("abstract", formatUUID uuid) ]) - listener <- liftIO (listenWith (defaultSocketOptions- { socketAuthenticator = dummyAuth- }) addr)- afterTest (closeListener listener)-- acceptedVar <- forkVar (accept listener)- openedVar <- forkVar (openWith (defaultSocketOptions- { socketAuthenticator = dummyAuth- }) addr)-- sock1 <- liftIO (takeMVar acceptedVar)- afterTest (close sock1)+ bracket (listenWith (defaultSocketOptions+ { socketAuthenticator = dummyAuth+ }) addr) closeListener $ \listener -> do+ acceptedVar <- forkVar (accept listener)+ openedVar <- forkVar (openWith (defaultSocketOptions+ { socketAuthenticator = dummyAuth+ }) addr) - sock2 <- liftIO (takeMVar openedVar)- afterTest (close sock2)+ sock1 <- takeMVar acceptedVar+ sock2 <- takeMVar openedVar+ close sock1+ close sock2 -test_SendReceive :: Test-test_SendReceive = assertions "send-receive" $ do- uuid <- liftIO randomUUID+test_SendReceive :: TestTree+test_SendReceive = testCase "send-receive" $ do+ uuid <- randomUUID let Just addr = address "unix" (Map.fromList [ ("abstract", formatUUID uuid) ])@@ -94,43 +87,37 @@ , methodCallBody = [toVariant True] } - listener <- liftIO (listen addr)- afterTest (closeListener listener)-- acceptedVar <- forkVar (accept listener)- openedVar <- forkVar (open addr)-- sock1 <- liftIO (takeMVar acceptedVar)- afterTest (close sock1)-- sock2 <- liftIO (takeMVar openedVar)- afterTest (close sock2)+ bracket (listen addr) closeListener $ \listener -> do+ acceptedVar <- forkVar (accept listener)+ openedVar <- forkVar (open addr) - -- client -> server- do- serialVar <- liftIO newEmptyMVar- sentVar <- forkVar (send sock2 msg (putMVar serialVar))- receivedVar <- forkVar (receive sock1)+ bracket (takeMVar acceptedVar) close $ \sock1 -> do+ bracket (takeMVar openedVar) close $ \sock2 -> do+ -- client -> server+ do+ serialVar <- newEmptyMVar+ sentVar <- forkVar (send sock2 msg (putMVar serialVar))+ receivedVar <- forkVar (receive sock1) - serial <- liftIO (takeMVar serialVar)- sent <- liftIO (takeMVar sentVar)- received <- liftIO (takeMVar receivedVar)+ serial <- takeMVar serialVar+ sent <- takeMVar sentVar+ received <- takeMVar receivedVar - $assert (equal sent ())- $assert (equal received (ReceivedMethodCall serial msg))+ sent @?= ()+ received @?= ReceivedMethodCall serial msg - -- server -> client- do- serialVar <- liftIO newEmptyMVar- sentVar <- forkVar (send sock1 msg (putMVar serialVar))- receivedVar <- forkVar (receive sock2)+ -- server -> client+ do+ serialVar <- newEmptyMVar+ sentVar <- forkVar (send sock1 msg (putMVar serialVar))+ receivedVar <- forkVar (receive sock2) - serial <- liftIO (takeMVar serialVar)- sent <- liftIO (takeMVar sentVar)- received <- liftIO (takeMVar receivedVar)+ serial <- takeMVar serialVar+ sent <- takeMVar sentVar+ received <- takeMVar receivedVar - $assert (equal sent ())- $assert (equal received (ReceivedMethodCall serial msg))+ sent @?= ()+ received @?= ReceivedMethodCall serial msg dummyAuth :: Transport t => Authenticator t dummyAuth = authenticator
tests/DBusTests/Transport.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-} -- Copyright (C) 2012 John Millikin <john@john-millikin.com> --@@ -18,62 +17,65 @@ module DBusTests.Transport (test_Transport) where -import Test.Chell--import Control.Concurrent-import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Concurrent+import Control.Monad.Extra (unlessM)+import Control.Monad.IO.Class (liftIO)+import Control.Monad.Trans.Resource+import Data.Function (fix)+import Data.List (isInfixOf)+import Network.Socket.ByteString (sendAll, recv)+import System.Directory (getTemporaryDirectory, removeFile)+import Test.Tasty+import Test.Tasty.HUnit import qualified Data.ByteString-import Data.Function (fix)-import Data.List (isPrefixOf) import qualified Data.Map as Map-import qualified Network as N import qualified Network.Socket as NS-import Network.Socket.ByteString (sendAll, recv)-import System.Directory (getTemporaryDirectory, removeFile) -import DBus-import DBus.Transport+import DBus+import DBus.Transport -import DBusTests.Util+import DBusTests.Util -test_Transport :: Suite-test_Transport = suite "Transport" $- suiteTests suite_TransportOpen ++- suiteTests suite_TransportListen ++- suiteTests suite_TransportAccept ++- [ test_TransportSendReceive+test_Transport :: TestTree+test_Transport = testGroup "Transport" $+ [ suite_TransportOpen+ , suite_TransportListen+ , suite_TransportAccept+ , test_TransportSendReceive , test_HandleLostConnection ] -suite_TransportOpen :: Suite-suite_TransportOpen = suite "transportOpen" $+suite_TransportOpen :: TestTree+suite_TransportOpen = testGroup "transportOpen" $ [ test_OpenUnknown- ] ++ suiteTests suite_OpenUnix- ++ suiteTests suite_OpenTcp+ , suite_OpenUnix+ , suite_OpenTcp+ ] -suite_TransportListen :: Suite-suite_TransportListen = suite "transportListen" $+suite_TransportListen :: TestTree+suite_TransportListen = testGroup "transportListen" $ [ test_ListenUnknown- ] ++ suiteTests suite_ListenUnix- ++ suiteTests suite_ListenTcp+ , suite_ListenUnix+ , suite_ListenTcp+ ] -suite_TransportAccept :: Suite-suite_TransportAccept = suite "transportAccept"+suite_TransportAccept :: TestTree+suite_TransportAccept = testGroup "transportAccept" [ test_AcceptSocket , test_AcceptSocketClosed ] -test_OpenUnknown :: Test-test_OpenUnknown = assertions "unknown" $ do+test_OpenUnknown :: TestTree+test_OpenUnknown = testCase "unknown" $ do let Just addr = address "noexist" Map.empty- $assert $ throwsEq+ assertException ((transportError "Unknown address method: \"noexist\"") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) -suite_OpenUnix :: Suite-suite_OpenUnix = suite "unix"+suite_OpenUnix :: TestTree+suite_OpenUnix = testGroup "unix" [ test_OpenUnix_Path , test_OpenUnix_Abstract , test_OpenUnix_TooFew@@ -81,82 +83,80 @@ , test_OpenUnix_NotListening ] -test_OpenUnix_Path :: Test-test_OpenUnix_Path = assertions "path" $ do+test_OpenUnix_Path :: TestTree+test_OpenUnix_Path = testCase "path" $ runResourceT $ do (addr, networkSocket) <- listenRandomUnixPath- afterTest (N.sClose networkSocket)- fdcountBefore <- countFileDescriptors t <- liftIO (transportOpen socketTransportOptions addr) liftIO (transportClose t) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)--test_OpenUnix_Abstract :: Test-test_OpenUnix_Abstract = assertions "abstract" $ do- (addr, networkSocket) <- listenRandomUnixAbstract- afterTest (N.sClose networkSocket)+ liftIO (fdcountBefore @=? fdcountAfter) +test_OpenUnix_Abstract :: TestTree+test_OpenUnix_Abstract = testCase "abstract" $ runResourceT $ do+ (addr, networkSocket, _) <- listenRandomUnixAbstract fdcountBefore <- countFileDescriptors t <- liftIO (transportOpen socketTransportOptions addr) liftIO (transportClose t) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ liftIO (fdcountBefore @=? fdcountAfter) -test_OpenUnix_TooFew :: Test-test_OpenUnix_TooFew = assertions "too-few" $ do+test_OpenUnix_TooFew :: TestTree+test_OpenUnix_TooFew = testCase "too-few" $ do fdcountBefore <- countFileDescriptors let Just addr = address "unix" Map.empty- $assert $ throwsEq+ assertException ((transportError "One of 'path' or 'abstract' must be specified for the 'unix' transport.") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenUnix_TooMany :: Test-test_OpenUnix_TooMany = assertions "too-many" $ do+test_OpenUnix_TooMany :: TestTree+test_OpenUnix_TooMany = testCase "too-many" $ do fdcountBefore <- countFileDescriptors let Just addr = address "unix" (Map.fromList [ ("path", "foo") , ("abstract", "bar") ])- $assert $ throwsEq+ assertException ((transportError "Only one of 'path' or 'abstract' may be specified for the 'unix' transport.") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenUnix_NotListening :: Test-test_OpenUnix_NotListening = assertions "not-listening" $ do+test_OpenUnix_NotListening :: TestTree+test_OpenUnix_NotListening = testCase "not-listening" $ runResourceT $ do fdcountBefore <- countFileDescriptors - (addr, networkSocket) <- listenRandomUnixAbstract- liftIO (NS.sClose networkSocket)- $assert $ throwsEq- ((transportError "connect: does not exist (Connection refused)")- { transportErrorAddress = Just addr- })+ (addr, networkSocket, key) <- listenRandomUnixAbstract+ release key++ liftIO $ assertThrows+ (\err -> and+ [ "Connection refused" `isInfixOf` transportErrorMessage err+ , transportErrorAddress err == Just addr+ ]) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ liftIO (fdcountBefore @=? fdcountAfter) -suite_OpenTcp :: Suite-suite_OpenTcp = suite "tcp"+suite_OpenTcp :: TestTree+suite_OpenTcp = testGroup "tcp" [ test_OpenTcp_IPv4- , skipWhen noIPv6 test_OpenTcp_IPv6+ , test_OpenTcp_IPv6 , test_OpenTcp_Unknown , test_OpenTcp_NoPort , test_OpenTcp_InvalidPort@@ -164,84 +164,80 @@ , test_OpenTcp_NotListening ] -test_OpenTcp_IPv4 :: Test-test_OpenTcp_IPv4 = assertions "ipv4" $ do- (addr, networkSocket) <- listenRandomIPv4- afterTest (N.sClose networkSocket)-+test_OpenTcp_IPv4 :: TestTree+test_OpenTcp_IPv4 = testCase "ipv4" $ runResourceT $ do+ (addr, networkSocket, _) <- listenRandomIPv4 fdcountBefore <- countFileDescriptors t <- liftIO (transportOpen socketTransportOptions addr) liftIO (transportClose t) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ liftIO (fdcountBefore @=? fdcountAfter) -test_OpenTcp_IPv6 :: Test-test_OpenTcp_IPv6 = assertions "ipv6" $ do+test_OpenTcp_IPv6 :: TestTree+test_OpenTcp_IPv6 = testCase "ipv6" $ unlessM noIPv6 $ runResourceT $ do (addr, networkSocket) <- listenRandomIPv6- afterTest (N.sClose networkSocket)- fdcountBefore <- countFileDescriptors t <- liftIO (transportOpen socketTransportOptions addr) liftIO (transportClose t) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ liftIO (fdcountBefore @=? fdcountAfter) -test_OpenTcp_Unknown :: Test-test_OpenTcp_Unknown = assertions "unknown-family" $ do+test_OpenTcp_Unknown :: TestTree+test_OpenTcp_Unknown = testCase "unknown-family" $ do fdcountBefore <- countFileDescriptors let Just addr = address "tcp" (Map.fromList [ ("family", "noexist") , ("port", "1234") ])- $assert $ throwsEq+ assertException ((transportError "Unknown socket family for TCP transport: \"noexist\"") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenTcp_NoPort :: Test-test_OpenTcp_NoPort = assertions "no-port" $ do+test_OpenTcp_NoPort :: TestTree+test_OpenTcp_NoPort = testCase "no-port" $ do fdcountBefore <- countFileDescriptors let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") ])- $assert $ throwsEq+ assertException ((transportError "TCP transport requires the `port' parameter.") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenTcp_InvalidPort :: Test-test_OpenTcp_InvalidPort = assertions "invalid-port" $ do+test_OpenTcp_InvalidPort :: TestTree+test_OpenTcp_InvalidPort = testCase "invalid-port" $ do fdcountBefore <- countFileDescriptors let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") , ("port", "123456") ])- $assert $ throwsEq+ assertException ((transportError "Invalid socket port for TCP transport: \"123456\"") { transportErrorAddress = Just addr }) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenTcp_NoUsableAddresses :: Test-test_OpenTcp_NoUsableAddresses = assertions "no-usable-addresses" $ do+test_OpenTcp_NoUsableAddresses :: TestTree+test_OpenTcp_NoUsableAddresses = testCase "no-usable-addresses" $ do fdcountBefore <- countFileDescriptors let Just addr = address "tcp" (Map.fromList@@ -249,35 +245,35 @@ , ("port", "1234") , ("host", "256.256.256.256") ])- $assert $ throws+ assertThrows (\err -> and- [ "getAddrInfo: does not exist" `isPrefixOf` transportErrorMessage err+ [ "getAddrInfo: does not exist" `isInfixOf` transportErrorMessage err , transportErrorAddress err == Just addr ]) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_OpenTcp_NotListening :: Test-test_OpenTcp_NotListening = assertions "too-many" $ do+test_OpenTcp_NotListening :: TestTree+test_OpenTcp_NotListening = testCase "too-many" $ runResourceT $ do fdcountBefore <- countFileDescriptors - (addr, networkSocket) <- listenRandomIPv4- liftIO (NS.sClose networkSocket)- $assert $ throwsEq- ((transportError "connect: does not exist (Connection refused)")- { transportErrorAddress = Just addr- })+ (addr, networkSocket, key) <- listenRandomIPv4+ release key+ liftIO $ assertThrows+ (\err -> and+ [ "Connection refused" `isInfixOf` transportErrorMessage err+ , transportErrorAddress err == Just addr+ ]) (transportOpen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ liftIO (fdcountBefore @=? fdcountAfter) -test_TransportSendReceive :: Test-test_TransportSendReceive = assertions "send-receive" $ do- (addr, networkSocket) <- listenRandomIPv4- afterTest (N.sClose networkSocket)+test_TransportSendReceive :: TestTree+test_TransportSendReceive = testCase "send-receive" $ runResourceT $ do+ (addr, networkSocket, _) <- listenRandomIPv4 -- a simple echo server, which sends back anything it receives. _ <- liftIO $ forkIO $ do@@ -290,8 +286,9 @@ sendAll s bytes loop - t <- liftIO (transportOpen socketTransportOptions addr)- afterTest (transportClose t)+ (_, t) <- allocate+ (transportOpen socketTransportOptions addr)+ transportClose -- small chunks of data are combined do@@ -300,7 +297,7 @@ liftIO (transportPut t "2") liftIO (transportPut t "3") bytes <- liftIO (readMVar var)- $assert (equal bytes "123")+ liftIO (bytes @?= "123") -- large chunks of data are read in full do@@ -308,35 +305,35 @@ var <- forkVar (transportGet t (4096 * 100)) liftIO (transportPut t sentBytes) bytes <- liftIO (readMVar var)- $assert (equal bytes sentBytes)+ liftIO (bytes @?= sentBytes) -test_HandleLostConnection :: Test-test_HandleLostConnection = assertions "handle-lost-connection" $ do- (addr, networkSocket) <- listenRandomIPv4- afterTest (N.sClose networkSocket)+test_HandleLostConnection :: TestTree+test_HandleLostConnection = testCase "handle-lost-connection" $ runResourceT $ do+ (addr, networkSocket, _) <- listenRandomIPv4 _ <- liftIO $ forkIO $ do (s, _) <- NS.accept networkSocket sendAll s "123" NS.sClose s - t <- liftIO (transportOpen socketTransportOptions addr)- afterTest (transportClose t)+ (_, t) <- allocate+ (transportOpen socketTransportOptions addr)+ transportClose bytes <- liftIO (transportGet t 4)- $assert (equal bytes "123")+ liftIO (bytes @?= "123") -test_ListenUnknown :: Test-test_ListenUnknown = assertions "unknown" $ do+test_ListenUnknown :: TestTree+test_ListenUnknown = testCase "unknown" $ do let Just addr = address "noexist" Map.empty- $assert $ throwsEq+ assertException ((transportError "Unknown address method: \"noexist\"") { transportErrorAddress = Just addr }) (transportListen socketTransportOptions addr) -suite_ListenUnix :: Suite-suite_ListenUnix = suite "unix"+suite_ListenUnix :: TestTree+suite_ListenUnix = testGroup "unix" [ test_ListenUnix_Path , test_ListenUnix_Abstract , test_ListenUnix_Tmpdir@@ -345,196 +342,205 @@ , test_ListenUnix_InvalidBind ] -test_ListenUnix_Path :: Test-test_ListenUnix_Path = assertions "path" $ do- path <- liftIO getTempPath+test_ListenUnix_Path :: TestTree+test_ListenUnix_Path = testCase "path" $ runResourceT $ do+ (_, path) <- allocate getTempPath removeFile let Just addr = address "unix" (Map.fromList [ ("path", path) ])- l <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose l)- afterTest (removeFile path)+ (_, l) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose -- listener address is random, so it can't be checked directly. let addrParams = addressParameters (transportListenerAddress l)- $expect (sameItems (Map.keys addrParams) ["path", "guid"])- $expect (equal (Map.lookup "path" addrParams) (Just path))+ liftIO (Map.keys addrParams @=? ["guid", "path"])+ liftIO (Map.lookup "path" addrParams @?= Just path) -test_ListenUnix_Abstract :: Test-test_ListenUnix_Abstract = assertions "abstract" $ do+test_ListenUnix_Abstract :: TestTree+test_ListenUnix_Abstract = testCase "abstract" $ runResourceT $ do path <- liftIO getTempPath let Just addr = address "unix" (Map.fromList [ ("abstract", path) ])- l <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose l)+ (_, l) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose -- listener address is random, so it can't be checked directly. let addrParams = addressParameters (transportListenerAddress l)- $expect (sameItems (Map.keys addrParams) ["abstract", "guid"])- $expect (equal (Map.lookup "abstract" addrParams) (Just path))+ liftIO (Map.keys addrParams @?= ["abstract", "guid"])+ liftIO (Map.lookup "abstract" addrParams @?= Just path) -test_ListenUnix_Tmpdir :: Test-test_ListenUnix_Tmpdir = assertions "tmpdir" $ do+test_ListenUnix_Tmpdir :: TestTree+test_ListenUnix_Tmpdir = testCase "tmpdir" $ runResourceT $ do tmpdir <- liftIO getTemporaryDirectory let Just addr = address "unix" (Map.fromList [ ("tmpdir", tmpdir) ])- l <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose l)+ (_, l) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose -- listener address is random, so it can't be checked directly. let addrKeys = Map.keys (addressParameters (transportListenerAddress l))- $expect ("path" `elem` addrKeys || "abstract" `elem` addrKeys)+ liftIO $ assertBool "invalid keys"+ ("path" `elem` addrKeys || "abstract" `elem` addrKeys) -test_ListenUnix_TooFew :: Test-test_ListenUnix_TooFew = assertions "too-few" $ do+test_ListenUnix_TooFew :: TestTree+test_ListenUnix_TooFew = testCase "too-few" $ do let Just addr = address "unix" Map.empty- $assert $ throwsEq+ assertException ((transportError "One of 'abstract', 'path', or 'tmpdir' must be specified for the 'unix' transport.") { transportErrorAddress = Just addr }) (transportListen socketTransportOptions addr) -test_ListenUnix_TooMany :: Test-test_ListenUnix_TooMany = assertions "too-many" $ do+test_ListenUnix_TooMany :: TestTree+test_ListenUnix_TooMany = testCase "too-many" $ do let Just addr = address "unix" (Map.fromList [ ("path", "foo") , ("abstract", "bar") ])- $assert $ throwsEq+ assertException ((transportError "Only one of 'abstract', 'path', or 'tmpdir' may be specified for the 'unix' transport.") { transportErrorAddress = Just addr }) (transportListen socketTransportOptions addr) -test_ListenUnix_InvalidBind :: Test-test_ListenUnix_InvalidBind = assertions "invalid-bind" $ do+test_ListenUnix_InvalidBind :: TestTree+test_ListenUnix_InvalidBind = testCase "invalid-bind" $ do fdcountBefore <- countFileDescriptors let Just addr = address "unix" (Map.fromList [ ("path", "/") ])- $assert $ throwsEq- ((transportError "bind: resource busy (Address already in use)")- { transportErrorAddress = Just addr- })+ assertThrows+ (\err -> and+ [ "Address already in use" `isInfixOf` transportErrorMessage err+ , transportErrorAddress err == Just addr+ ]) (transportListen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -suite_ListenTcp :: Suite-suite_ListenTcp = suite "tcp"+suite_ListenTcp :: TestTree+suite_ListenTcp = testGroup "tcp" [ test_ListenTcp_IPv4- , skipWhen noIPv6 test_ListenTcp_IPv6+ , test_ListenTcp_IPv6 , test_ListenTcp_Unknown , test_ListenTcp_InvalidPort , test_ListenTcp_InvalidBind ] -test_ListenTcp_IPv4 :: Test-test_ListenTcp_IPv4 = assertions "ipv4" $ do+test_ListenTcp_IPv4 :: TestTree+test_ListenTcp_IPv4 = testCase "ipv4" $ runResourceT $ do let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") ])- l <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose l)+ (_, l) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose let params = addressParameters (transportListenerAddress l)- $expect (equal (Map.lookup "family" params) (Just "ipv4"))- $expect ("port" `elem` Map.keys params)+ liftIO (Map.lookup "family" params @?= Just "ipv4")+ liftIO $ assertBool "no port" ("port" `elem` Map.keys params) -test_ListenTcp_IPv6 :: Test-test_ListenTcp_IPv6 = assertions "ipv6" $ do+test_ListenTcp_IPv6 :: TestTree+test_ListenTcp_IPv6 = testCase "ipv6" $ unlessM noIPv6 $ runResourceT $ do let Just addr = address "tcp" (Map.fromList [ ("family", "ipv6") ])- l <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose l)+ (_, l) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose let params = addressParameters (transportListenerAddress l)- $expect (equal (Map.lookup "family" params) (Just "ipv6"))- $expect ("port" `elem` Map.keys params)+ liftIO (Map.lookup "family" params @?= Just "ipv6")+ liftIO $ assertBool "no port" ("port" `elem` Map.keys params) -test_ListenTcp_Unknown :: Test-test_ListenTcp_Unknown = assertions "unknown-family" $ do+test_ListenTcp_Unknown :: TestTree+test_ListenTcp_Unknown = testCase "unknown-family" $ do let Just addr = address "tcp" (Map.fromList [ ("family", "noexist") , ("port", "1234") ])- $assert $ throwsEq+ assertException ((transportError "Unknown socket family for TCP transport: \"noexist\"") { transportErrorAddress = Just addr }) (transportListen socketTransportOptions addr) -test_ListenTcp_InvalidPort :: Test-test_ListenTcp_InvalidPort = assertions "invalid-port" $ do+test_ListenTcp_InvalidPort :: TestTree+test_ListenTcp_InvalidPort = testCase "invalid-port" $ do let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") , ("port", "123456") ])- $assert $ throwsEq+ assertException ((transportError "Invalid socket port for TCP transport: \"123456\"") { transportErrorAddress = Just addr }) (transportListen socketTransportOptions addr) -test_ListenTcp_InvalidBind :: Test-test_ListenTcp_InvalidBind = assertions "invalid-bind" $ do+test_ListenTcp_InvalidBind :: TestTree+test_ListenTcp_InvalidBind = testCase "invalid-bind" $ do fdcountBefore <- countFileDescriptors let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") , ("port", "1") ])- $assert $ throwsEq- ((transportError "bind: permission denied (Permission denied)")- { transportErrorAddress = Just addr- })+ assertThrows+ (\err -> and+ [ "Permission denied" `isInfixOf` transportErrorMessage err+ , transportErrorAddress err == Just addr+ ]) (transportListen socketTransportOptions addr) fdcountAfter <- countFileDescriptors- $assert (equal fdcountBefore fdcountAfter)+ fdcountBefore @=? fdcountAfter -test_AcceptSocket :: Test-test_AcceptSocket = assertions "socket" $ do+test_AcceptSocket :: TestTree+test_AcceptSocket = testCase "socket" $ runResourceT $ do path <- liftIO getTempPath let Just addr = address "unix" (Map.fromList [ ("abstract", path) ])- listener <- liftIO (transportListen socketTransportOptions addr)- afterTest (transportListenerClose listener)+ (_, listener) <- allocate+ (transportListen socketTransportOptions addr)+ transportListenerClose acceptedVar <- forkVar (transportAccept listener) openedVar <- forkVar (transportOpen socketTransportOptions addr) - accepted <- liftIO (readMVar acceptedVar)- opened <- liftIO (readMVar openedVar)- afterTest (transportClose accepted)- afterTest (transportClose opened)+ (_, accepted) <- allocate (readMVar acceptedVar) transportClose+ (_, opened) <- allocate (readMVar openedVar) transportClose liftIO (transportPut opened "testing") bytes <- liftIO (transportGet accepted 7) - $expect (equal bytes "testing")+ liftIO (bytes @?= "testing") -test_AcceptSocketClosed :: Test-test_AcceptSocketClosed = assertions "socket-closed" $ do- path <- liftIO getTempPath+test_AcceptSocketClosed :: TestTree+test_AcceptSocketClosed = testCase "socket-closed" $ do+ path <- getTempPath let Just addr = address "unix" (Map.fromList [ ("abstract", path) ])- listener <- liftIO (transportListen socketTransportOptions addr)+ listener <- transportListen socketTransportOptions addr let listeningAddr = transportListenerAddress listener- liftIO (transportListenerClose listener)+ transportListenerClose listener - $assert $ throwsEq- ((transportError "user error (accept: can't perform accept on socket ((AF_UNIX,Stream,0)) in status Closed)")- { transportErrorAddress = Just listeningAddr- })+ assertThrows+ (\err -> and+ [ "accept" `isInfixOf` transportErrorMessage err+ , "socket" `isInfixOf` transportErrorMessage err+ , "Closed" `isInfixOf` transportErrorMessage err+ , transportErrorAddress err == Just listeningAddr+ ]) (transportAccept listener) socketTransportOptions :: TransportOptions SocketTransport
tests/DBusTests/Util.hs view
@@ -1,5 +1,3 @@-{-# LANGUAGE TemplateHaskell #-}- -- Copyright (C) 2010-2012 John Millikin <john@john-millikin.com> -- -- This program is free software: you can redistribute it and/or modify@@ -19,6 +17,8 @@ ( assertVariant , assertValue , assertAtom+ , assertException+ , assertThrows , getTempPath , listenRandomUnixPath@@ -37,54 +37,52 @@ , clampedSize , smallListOf , smallListOf1++ , DBusTests.Util.requireLeft+ , DBusTests.Util.requireRight ) where -import Control.Concurrent-import Control.Exception (IOException, try, bracket, bracket_)-import Control.Monad.IO.Class (MonadIO, liftIO)-import Data.Bits ((.&.))+import Control.Concurrent+import Control.Exception (Exception, IOException, try, bracket, bracket_)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.Trans.Resource+import Data.Bits ((.&.))+import Data.Char (chr)+import System.Directory (getTemporaryDirectory, removeFile)+import System.FilePath ((</>))+import Test.QuickCheck hiding ((.&.))+import Test.Tasty.HUnit import qualified Data.ByteString import qualified Data.ByteString.Lazy-import Data.Char (chr) import qualified Data.Map as Map-import qualified Data.Set import qualified Data.Text as T import qualified Network as N import qualified Network.Socket as NS-import System.Directory (getTemporaryDirectory, removeFile) import qualified System.Posix as Posix-import System.FilePath ((</>)) -import Test.Chell-import Test.QuickCheck hiding ((.&.))--import DBus-import DBus.Internal.Types+import DBus+import DBus.Internal.Types -assertVariant :: (Eq a, Show a, IsVariant a) => Type -> a -> Assertions ()+assertVariant :: (Eq a, Show a, IsVariant a) => Type -> a -> Test.Tasty.HUnit.Assertion assertVariant t a = do- $expect $ equal t (variantType (toVariant a))- $expect $ equal (fromVariant (toVariant a)) (Just a)- $expect $ equal (toVariant a) (toVariant a)--$([d||])+ t @=? variantType (toVariant a)+ Just a @=? fromVariant (toVariant a)+ toVariant a @=? toVariant a -assertValue :: (Eq a, Show a, IsValue a) => Type -> a -> Assertions ()+assertValue :: (Eq a, Show a, IsValue a) => Type -> a -> Test.Tasty.HUnit.Assertion assertValue t a = do- $expect $ equal t (DBus.typeOf a)- $expect $ equal t (DBus.Internal.Types.typeOf a)- $expect $ equal t (valueType (toValue a))- $expect $ equal (fromValue (toValue a)) (Just a)- $expect $ equal (toValue a) (toValue a)+ t @=? DBus.typeOf a+ t @=? DBus.Internal.Types.typeOf a+ t @=? valueType (toValue a)+ fromValue (toValue a) @?= Just a+ toValue a @=? toValue a assertVariant t a -$([d||])--assertAtom :: (Eq a, Show a, IsAtom a) => Type -> a -> Assertions ()+assertAtom :: (Eq a, Show a, IsAtom a) => Type -> a -> Test.Tasty.HUnit.Assertion assertAtom t a = do- $expect $ equal t (atomType (toAtom a))- $expect $ equal (fromAtom (toAtom a)) (Just a)- $expect $ equal (toAtom a) (toAtom a)+ t @=? (atomType (toAtom a))+ fromAtom (toAtom a) @?= (Just a)+ toAtom a @=? toAtom a assertValue t a getTempPath :: IO String@@ -93,64 +91,73 @@ uuid <- randomUUID return (tmp </> formatUUID uuid) -listenRandomUnixPath :: Assertions (Address, N.Socket)+listenRandomUnixPath :: MonadResource m => m (Address, N.Socket) listenRandomUnixPath = do path <- liftIO getTempPath let sockAddr = NS.SockAddrUnix path- sock <- liftIO (NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol)+ (_, sock) <- allocate+ (NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol)+ N.sClose liftIO (NS.bindSocket sock sockAddr) liftIO (NS.listen sock 1)- afterTest (removeFile path)+ _ <- register (removeFile path) let Just addr = address "unix" (Map.fromList [ ("path", path) ]) return (addr, sock) -listenRandomUnixAbstract :: MonadIO m => m (Address, N.Socket)-listenRandomUnixAbstract = liftIO $ do+listenRandomUnixAbstract :: MonadResource m => m (Address, N.Socket, ReleaseKey)+listenRandomUnixAbstract = do uuid <- liftIO randomUUID let sockAddr = NS.SockAddrUnix ('\x00' : formatUUID uuid) - sock <- NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol- NS.bindSocket sock sockAddr- NS.listen sock 1+ (key, sock) <- allocate+ (NS.socket NS.AF_UNIX NS.Stream NS.defaultProtocol)+ N.sClose + liftIO $ NS.bindSocket sock sockAddr+ liftIO $ NS.listen sock 1+ let Just addr = address "unix" (Map.fromList [ ("abstract", formatUUID uuid) ])- return (addr, sock)+ return (addr, sock, key) -listenRandomIPv4 :: MonadIO m => m (Address, N.Socket)-listenRandomIPv4 = liftIO $ do- hostAddr <- NS.inet_addr "127.0.0.1"+listenRandomIPv4 :: MonadResource m => m (Address, N.Socket, ReleaseKey)+listenRandomIPv4 = do+ hostAddr <- liftIO $ NS.inet_addr "127.0.0.1" let sockAddr = NS.SockAddrInet 0 hostAddr - sock <- NS.socket NS.AF_INET NS.Stream NS.defaultProtocol- NS.bindSocket sock sockAddr- NS.listen sock 1+ (key, sock) <- allocate+ (NS.socket NS.AF_INET NS.Stream NS.defaultProtocol)+ N.sClose+ liftIO $ NS.bindSocket sock sockAddr+ liftIO $ NS.listen sock 1 - sockPort <- NS.socketPort sock+ sockPort <- liftIO $ NS.socketPort sock let Just addr = address "tcp" (Map.fromList [ ("family", "ipv4") , ("host", "localhost") , ("port", show (toInteger sockPort)) ])- return (addr, sock)+ return (addr, sock, key) -listenRandomIPv6 :: MonadIO m => m (Address, N.Socket)-listenRandomIPv6 = liftIO $ do- addrs <- NS.getAddrInfo Nothing (Just "::1") Nothing+listenRandomIPv6 :: MonadResource m => m (Address, N.Socket)+listenRandomIPv6 = do+ addrs <- liftIO $ NS.getAddrInfo Nothing (Just "::1") Nothing let sockAddr = case addrs of [] -> error "listenRandomIPv6: no address for localhost?" a:_ -> NS.addrAddress a - sock <- NS.socket NS.AF_INET6 NS.Stream NS.defaultProtocol- NS.bindSocket sock sockAddr- NS.listen sock 1+ (_, sock) <- allocate+ (NS.socket NS.AF_INET6 NS.Stream NS.defaultProtocol)+ N.sClose+ liftIO $ NS.bindSocket sock sockAddr+ liftIO $ NS.listen sock 1 - sockPort <- NS.socketPort sock+ sockPort <- liftIO $ NS.socketPort sock let Just addr = address "tcp" (Map.fromList [ ("family", "ipv6") , ("host", "::1")@@ -265,3 +272,25 @@ dropWhileEnd :: (Char -> Bool) -> String -> String dropWhileEnd p = T.unpack . T.dropWhileEnd p . T.pack++requireLeft :: Show b => Either a b -> IO a+requireLeft (Left a) = return a+requireLeft (Right b) = assertFailure ("Right " ++ show b ++ " is not Left") >> undefined++requireRight :: Show a => Either a b -> IO b+requireRight (Right b) = return b+requireRight (Left a) = assertFailure ("Left " ++ show a ++ " is not Right") >> undefined++assertException :: (Eq e, Exception e) => e -> IO a -> Test.Tasty.HUnit.Assertion+assertException e f = do+ result <- try f+ case result of+ Left ex -> ex @?= e+ Right _ -> assertFailure "expected exception not thrown"++assertThrows :: Exception e => (e -> Bool) -> IO a -> Test.Tasty.HUnit.Assertion+assertThrows check f = do+ result <- try f+ case result of+ Left ex -> assertBool ("unexpected exception " ++ show ex) (check ex)+ Right _ -> assertFailure "expected exception not thrown"
tests/DBusTests/Variant.hs view
@@ -17,36 +17,35 @@ module DBusTests.Variant (test_Variant) where -import Prelude hiding (fail)--import Test.Chell+import Test.Tasty+import Test.Tasty.HUnit +import Data.Int (Int16, Int32, Int64)+import Data.Word (Word8, Word16, Word32, Word64)+import System.Posix.Types (Fd) import qualified Data.ByteString import qualified Data.ByteString.Lazy-import qualified Data.Text as T+import qualified Data.Map import qualified Data.Text+import qualified Data.Text as T import qualified Data.Text.Lazy-import Data.Word (Word8, Word16, Word32, Word64)-import Data.Int (Int16, Int32, Int64)-import qualified Data.Map import qualified Data.Vector-import System.Posix.Types (Fd) -import DBus-import DBus.Internal.Types (toValue)+import DBus+import DBus.Internal.Types (toValue) -import DBusTests.Util+import DBusTests.Util -test_Variant :: Suite-test_Variant = suite "Variant"+test_Variant :: TestTree+test_Variant = testGroup "Variant" [ test_IsAtom , test_IsValue , test_Show , test_ByteStorage ] -test_IsAtom :: Test-test_IsAtom = assertions "IsAtom" $ do+test_IsAtom :: TestTree+test_IsAtom = testCase "IsAtom" $ do assertAtom TypeBoolean True assertAtom TypeWord8 (0 :: Word8) assertAtom TypeWord16 (0 :: Word16)@@ -63,8 +62,8 @@ assertAtom TypeObjectPath (objectPath_ "/") assertAtom TypeSignature (signature_ []) -test_IsValue :: Test-test_IsValue = assertions "IsValue" $ do+test_IsValue :: TestTree+test_IsValue = testCase "IsValue" $ do assertValue TypeVariant (toVariant True) assertValue (TypeArray TypeBoolean) [True] assertValue (TypeArray TypeBoolean) (Data.Vector.fromList [True])@@ -86,70 +85,61 @@ assertValue (TypeStructure (replicate 14 TypeBoolean)) (True, True, True, True, True, True, True, True, True, True, True, True, True, True) assertValue (TypeStructure (replicate 15 TypeBoolean)) (True, True, True, True, True, True, True, True, True, True, True, True, True, True, True) -test_Show :: Test-test_Show = assertions "show" $ do- $expect $ equal "Variant True" (show (toVariant True))- $expect $ equal "Variant 0" (show (toVariant (0 :: Word8)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Word16)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Word32)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Word64)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Int16)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Int32)))- $expect $ equal "Variant 0" (show (toVariant (0 :: Int64)))- $expect $ equal "Variant 0.1" (show (toVariant (0.1 :: Double)))- $expect $ equal "Variant (UnixFd 1)" (show (toVariant (1 :: Fd)))- $expect $ equal "Variant \"\"" (show (toVariant (T.pack "")))- $expect $ equal "Variant (ObjectPath \"/\")" (show (toVariant (objectPath_ "/")))- $expect $ equal "Variant (Signature \"\")" (show (toVariant (signature_ [])))- $expect $ equal "Variant (Variant True)" (show (toVariant (toVariant True)))- $expect $ equal "Variant [True, False]" (show (toVariant [True, False]))+test_Show :: TestTree+test_Show = testCase "show" $ do+ "Variant True" @=? show (toVariant True)+ "Variant 0" @=? show (toVariant (0 :: Word8))+ "Variant 0" @=? show (toVariant (0 :: Word16))+ "Variant 0" @=? show (toVariant (0 :: Word32))+ "Variant 0" @=? show (toVariant (0 :: Word64))+ "Variant 0" @=? show (toVariant (0 :: Int16))+ "Variant 0" @=? show (toVariant (0 :: Int32))+ "Variant 0" @=? show (toVariant (0 :: Int64))+ "Variant 0.1" @=? show (toVariant (0.1 :: Double))+ "Variant (UnixFd 1)" @=? show (toVariant (1 :: Fd))+ "Variant \"\"" @=? show (toVariant (T.pack ""))+ "Variant (ObjectPath \"/\")" @=? show (toVariant (objectPath_ "/"))+ "Variant (Signature \"\")" @=? show (toVariant (signature_ []))+ "Variant (Variant True)" @=? show (toVariant (toVariant True))+ "Variant [True, False]" @=? show (toVariant [True, False]) - $expect $ equal "Variant b\"\"" (show (toVariant Data.ByteString.empty))- $expect $ equal "Variant b\"\"" (show (toVariant Data.ByteString.Lazy.empty))- $expect $ equal "Variant b\"\"" (show (toVariant ([] :: [Word8])))+ "Variant b\"\"" @=? show (toVariant Data.ByteString.empty)+ "Variant b\"\"" @=? show (toVariant Data.ByteString.Lazy.empty)+ "Variant b\"\"" @=? show (toVariant ([] :: [Word8])) - $expect $ equal "(Variant {False: True, True: False})" (showsPrec 11 (toVariant (Data.Map.fromList [(True, False), (False, True)])) "")- $expect $ equal "(Variant (True, False))" (showsPrec 11 (toVariant (True, False)) "")+ "(Variant {False: True, True: False})" @=? showsPrec 11 (toVariant (Data.Map.fromList [(True, False), (False, True)])) ""+ "(Variant (True, False))" @=? showsPrec 11 (toVariant (True, False)) "" -test_ByteStorage :: Test-test_ByteStorage = assertions "byte-storage" $ do+test_ByteStorage :: TestTree+test_ByteStorage = testCase "byte-storage" $ do -- Vector Word8 -> Vector Word8- $assert $ equal- (toValue (Data.Vector.fromList [0 :: Word8]))- (toValue (Data.Vector.fromList [0 :: Word8]))+ toValue (Data.Vector.fromList [0 :: Word8])+ @=? toValue (Data.Vector.fromList [0 :: Word8]) -- Vector Word8 -> ByteString- $assert $ equal- (toValue (Data.Vector.fromList [0 :: Word8]))- (toValue (Data.ByteString.pack [0]))+ toValue (Data.Vector.fromList [0 :: Word8])+ @=? toValue (Data.ByteString.pack [0]) -- Vector Word8 -> Lazy.ByteString- $assert $ equal- (toValue (Data.Vector.fromList [0 :: Word8]))- (toValue (Data.ByteString.Lazy.pack [0]))+ toValue (Data.Vector.fromList [0 :: Word8])+ @=? toValue (Data.ByteString.Lazy.pack [0]) -- ByteString -> Vector Word8- $assert $ equal- (toValue (Data.ByteString.pack [0]))- (toValue (Data.Vector.fromList [0 :: Word8]))+ toValue (Data.ByteString.pack [0])+ @=? toValue (Data.Vector.fromList [0 :: Word8]) -- ByteString -> ByteString- $assert $ equal- (toValue (Data.ByteString.pack [0]))- (toValue (Data.ByteString.pack [0]))+ toValue (Data.ByteString.pack [0])+ @=? toValue (Data.ByteString.pack [0]) -- ByteString -> Lazy.ByteString- $assert $ equal- (toValue (Data.ByteString.pack [0]))- (toValue (Data.ByteString.Lazy.pack [0]))+ toValue (Data.ByteString.pack [0])+ @=? toValue (Data.ByteString.Lazy.pack [0]) -- Lazy.ByteString -> Vector Word8- $assert $ equal- (toValue (Data.ByteString.Lazy.pack [0]))- (toValue (Data.Vector.fromList [0 :: Word8]))+ toValue (Data.ByteString.Lazy.pack [0])+ @=? toValue (Data.Vector.fromList [0 :: Word8]) -- Lazy.ByteString -> ByteString- $assert $ equal- (toValue (Data.ByteString.Lazy.pack [0]))- (toValue (Data.ByteString.pack [0]))+ toValue (Data.ByteString.Lazy.pack [0])+ @=? toValue (Data.ByteString.pack [0]) -- Lazy.ByteString -> Lazy.ByteString- $assert $ equal- (toValue (Data.ByteString.Lazy.pack [0]))- (toValue (Data.ByteString.Lazy.pack [0]))+ toValue (Data.ByteString.Lazy.pack [0])+ @=? toValue (Data.ByteString.Lazy.pack [0])
tests/DBusTests/Wire.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE TemplateHaskell #-} -- Copyright (C) 2012 John Millikin <john@john-millikin.com> --@@ -18,27 +17,29 @@ module DBusTests.Wire (test_Wire) where -import Test.Chell+import Data.Either+import Test.Tasty+import Test.Tasty.HUnit import qualified Data.ByteString.Char8 () -import DBus+import DBus -test_Wire :: Suite-test_Wire = suite "Wire" $- suiteTests test_Unmarshal+test_Wire :: TestTree+test_Wire = testGroup "Wire" $+ [ test_Unmarshal+ ] -test_Unmarshal :: Suite-test_Unmarshal = suite "unmarshal"+test_Unmarshal :: TestTree+test_Unmarshal = testGroup "unmarshal" [ test_UnmarshalUnexpectedEof ] -test_UnmarshalUnexpectedEof :: Test-test_UnmarshalUnexpectedEof = assertions "unexpected-eof" $ do+test_UnmarshalUnexpectedEof :: TestTree+test_UnmarshalUnexpectedEof = testCase "unexpected-eof" $ do let unmarshaled = unmarshal "0"- $assert (left unmarshaled)+ assertBool "invalid unmarshalled parse" (isLeft unmarshaled) let Left err = unmarshaled- $assert (equal- (unmarshalErrorMessage err)- "Unexpected end of input while parsing message header.")+ unmarshalErrorMessage err+ @=? "Unexpected end of input while parsing message header."