mediabus-0.4.0.0: specs/Data/MediaBus/Media/SyncStreamSpec.hs
module Data.MediaBus.Media.SyncStreamSpec
( spec
) where
import Control.Lens
import Control.Monad.State
import Data.Function
import Data.MediaBus
import Debug.Trace
import Test.Hspec
import Test.QuickCheck
newtype FakePayload = FP
{ fakeDuration :: Ticks64At8000
} deriving (Eq, Show, Num, Arbitrary, Ord)
instance HasDuration FakePayload where
getDuration = view (to fakeDuration . nominalDiffTime)
spec :: Spec
spec =
describe "setSequenceNumberAndTimestamp" $ do
it "increases the sequence number by one (only) for each frame" $
let prop :: (NonEmptyList (SyncStream () () FakePayload)) -> Bool
prop (NonEmpty inStr) =
let expectedLastSeqNum =
let isNext (MkStream (Next _)) = True
isNext _ = False
in max 0 (fromIntegral (length (filter isNext inStr)) - 1)
actualLastSeqNum =
let outStr =
let z :: (SeqNum16, Ticks64At8000)
z = (0, 0)
in evalState
(mapM
(state . setSequenceNumberAndTimestamp)
inStr)
z
in case last outStr of
MkStream (Next f) -> f ^. seqNum
MkStream (Start f) -> max 0 (f ^. seqNum - 1)
in expectedLastSeqNum == actualLastSeqNum
in property prop
it "increases the sequence number monotonic" $
let prop :: (NonEmptyList (SyncStream () () FakePayload)) -> Bool
prop (NonEmpty inStr) =
let seqNumDiffs =
let outFrames =
let isNext (MkStream (Next _)) = True
isNext _ = False
outStr =
let z :: (SeqNum16, Ticks64At8000)
z = (0, 0)
in evalState
(mapM
(state . setSequenceNumberAndTimestamp)
inStr)
z
in filter isNext outStr
in zipWith ((-) `on` (view seqNum)) (drop 1 outFrames) outFrames
in all (== 1) seqNumDiffs
in property prop
it "increases the timestamps by the duration of each frame" $
let prop :: (NonEmptyList (SyncStream () () FakePayload)) -> Bool
prop (NonEmpty inStr) =
let isNext (MkStream (Next _)) = True
isNext _ = False
outFrames :: [Stream () SeqNum16 Ticks64At8000 () FakePayload]
outFrames =
let outStr =
let z :: (SeqNum16, Ticks64At8000)
z = (0, MkTicks 0)
in evalState
(mapM
(state . setSequenceNumberAndTimestamp)
inStr)
z
in filter isNext outStr
timestamps = map (view timestamp) outFrames
expectedTimestamps :: [Ticks64At8000]
expectedTimestamps =
let inFramesWithoutLast =
(filter isNext inStr)
inDurations =
map (view (from nominalDiffTime) . getDuration)
inFramesWithoutLast
in scanl (+) 0 inDurations
in if and (zipWith (==) timestamps expectedTimestamps)
then True
else traceShow ( timestamps
, expectedTimestamps
, outFrames) False
in property prop