@@ -0,0 +1,43 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+module Notify (testNotify) where
3+
4+import Control.Applicative
5+import Control.Concurrent
6+import Control.Monad
7+import Data.Function
8+import Data.List
9+import Database.PostgreSQL.Simple
10+import Database.PostgreSQL.Simple.Notification
11+import Test.HUnit
12+
13+import qualified Data.ByteString as B
14+
15+-- TODO: Test with payload, but only for PostgreSQL >= 9.0
16+-- (when that feature was introduced).
17+
18+testNotify :: Connection -> ((Connection -> IO ()) -> IO ()) -> Test
19+testNotify conn withConn =
20+ TestCase $
21+ withConn $ \conn2 -> do
22+ execute_ conn "LISTEN foo"
23+ execute_ conn "LISTEN bar"
24+
25+ results_mv <- newEmptyMVar
26+ forkIO $ replicateM 2 (getNotification conn)
27+ >>= putMVar results_mv
28+
29+ threadDelay 100000
30+
31+ execute_ conn2 "NOTIFY foo"
32+ execute_ conn2 "NOTIFY bar"
33+
34+ [n1, n2] <- sortBy (compare `on` notificationChannel)
35+ <$> takeMVar results_mv
36+
37+ assertEqual "n1" "bar" (notificationChannel n1)
38+ assertEqual "n2" "foo" (notificationChannel n2)
39+
40+ -- Other sanity checks
41+ assertEqual "Server PIDs match" (notificationPid n1) (notificationPid n2)
42+ assertBool "notificationData is empty" $
43+ all (B.null . notificationData) [n1, n2]