module Main where
import Test.Hspec
import Control.Concurrent.STM
import Control.Concurrent.STM.Firehose
import Control.Monad
import Test.HUnit
import Control.Applicative
intFH :: STM (Firehose Int)
intFH = newFirehose
main :: IO ()
main = hspec $ parallel $ do
describe "Fire hose with no subscriptions" $ do
it "must not block" $ do
fh <- atomically intFH
mapM_ (atomically . writeEvent fh) [1..10000]
atomically (mapM_ (writeEvent fh) [1..10000])
describe "Fire hose with a single subscription" $ do
it "must give the oldest items in case of overflow" $ do
out <- atomically $ do
fh <- intFH
sub <- subscribe 10 fh
mapM_ (writeEvent fh) [1..10000]
replicateM 10 (readEvent sub)
map Just [1..10] @=? out
it "must not block or close when unsubscribed" $ do
out <- atomically $ do
fh <- intFH
sub <- subscribe 10 fh
mapM_ (writeEvent fh) [1..100]
unsubscribe sub
mapM_ (writeEvent fh) [101..200]
sub' <- subscribe 10 fh
mapM_ (writeEvent fh) [201..300]
replicateM 10 (readEvent sub')
map Just [201..210] @=? out
describe "Fire hose with multiple subscriptions" $ do
it "must accept multiple subscriptions" $ do
(o1,o2,o3,o4) <- atomically $ do
fh <- intFH
sub1 <- subscribe 10 fh
writeEvent fh 1
sub2 <- subscribe 10 fh
writeEvent fh 2
sub3 <- subscribe 10 fh
writeEvent fh 3
sub4 <- subscribe 10 fh
mapM_ (writeEvent fh) [201..300]
(,,,) <$> replicateM 10 (readEvent sub1) <*> replicateM 10 (readEvent sub2) <*> replicateM 10 (readEvent sub3) <*> replicateM 10 (readEvent sub4)
map Just (take 10 ([1,2,3] ++ [201..])) @=? o1
map Just (take 10 ([2,3] ++ [201..])) @=? o2
map Just (take 10 ([3] ++ [201..])) @=? o3
map Just (take 10 ([201..])) @=? o4