{-# LANGUAGE OverloadedStrings #-} module Main where import Test.Framework (defaultMain, testGroup) import Test.Framework.Providers.HUnit import Test.HUnit import Control.Monad (when) import Control.Monad.State import qualified Data.Set as Set import Data.Monoid import Data.List import System.Exit (exitFailure) import DBus (objectPath_, busName_) import Bustle.Types import Bustle.Renderer main :: IO () main = defaultMain tests where tests = [ testGroup "Disconnections don't affect participants" [ testCase "One participant, no disconnection" test_participants , testCase "One participant, which disconnects" test_participants_with_disconnect ] , testGroup "Incremential rendering matches all-at-once rendering" [ testCase "rrCentreOffset" $ test_incremental_simple rrCentreOffset , testCase "rrTopOffset" $ test_incremental_simple rrTopOffset , testCase "rrShapes" $ test_incremental_list rrShapes , testCase "rrRegions" $ test_incremental_list rrRegions , testCase "rrApplications" $ test_incremental_simple rrApplications , testCase "rrWarnings" $ test_incremental_simple rrWarnings ] ] -- Tests that services visible in a log are listed as participants even if they -- disconnect from the bus before the end of the log. This is a regression test -- for a bug I almost introduced. activeService = UniqueName ":1.1" swaddle messages timestamps = map (\(e, ts) -> Detailed ts e Nothing) (zip messages timestamps) sessionLogWithoutDisconnect = [ NOCEvent $ Connected activeService , MessageEvent $ Signal (U activeService) Nothing $ Member (objectPath_ "/") Nothing "Hello" ] sessionLogWithDisconnect = sessionLogWithoutDisconnect ++ [ NOCEvent $ Disconnected activeService ] expectedParticipants = [ (activeService, Set.empty) ] test_ l expected = expected @=? ps where rr = process (swaddle l [1..]) [] ps = sessionParticipants (rrApplications rr) test_participants = test_ sessionLogWithoutDisconnect expectedParticipants test_participants_with_disconnect = test_ sessionLogWithDisconnect expectedParticipants -- Test that incremental rendering matches all-at-once rendering u1 = UniqueName ":1.1" u2 = UniqueName ":2.2" -- This is enough names that the log needs to be rejustified to the top os = map (OtherName . busName_ . ("Foo." ++) . (:"potato")) ['a'..'z'] m = Member "/" Nothing "Hi" bareLog = [ NOCEvent $ Connected u1 , MessageEvent $ Signal (U u1) Nothing m , NOCEvent $ Connected u2 ] ++ map (\o -> NOCEvent (NameChanged o (Claimed u2))) os ++ [ MessageEvent $ MethodCall 0 (U u1) (O (head os)) m ] sessionLog = swaddle bareLog [1,3..] systemLog = swaddle bareLog [2,4..] test_incremental_simple :: (Show b, Eq b) => (RendererResult Participants -> b) -> Assertion test_incremental_simple f = test_incremental $ \full incremental -> f full @=? f incremental test_incremental_list :: (Show b, Eq b) => (RendererResult Participants -> [b]) -> Assertion test_incremental_list f = test_incremental $ \fullRR incrementalRR -> do let full = f fullRR incr = f incrementalRR -- Compare each element in turn mapM_ (uncurry (@=?)) $ zip full incr when (length full /= length incr) $ full @=? incr test_incremental :: ( RendererResult Participants -> RendererResult Participants -> Assertion ) -> Assertion test_incremental f = f fullRR incrementalRR -- TODO: it should be possible to make this work for side-by-side logs too. -- Currently it doesn't seem to... fullRR, incrementalRR :: RendererResult Participants fullRR = process sessionLog [] incrementalRR = mconcat rrs where processOne m = state $ processSome [m] [] (rrs, _) = runState (mapM processOne sessionLog) rendererStateNew