{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_HADDOCK hide #-}
module Protocols.Experimental.Hedgehog.Internal where
import Data.Proxy (Proxy (Proxy))
import GHC.Stack (HasCallStack)
import Prelude
import Protocols.Experimental.Df qualified as DfExperimental
import Protocols.Experimental.Hedgehog.Types
import Protocols.Experimental.Simulate
import Protocols.Internal.TH
import Clash.Prelude (type (*), type (+), type (<=))
import Clash.Prelude qualified as C
import Hedgehog qualified as H
import Hedgehog.Internal.Property qualified as H
defExpectOptions :: ExpectOptions
defExpectOptions =
ExpectOptions
{
eoStopAfterEmpty = Nothing
, eoSampleMax = 1000
, eoStallsMax = 10
, eoConsecutiveStalls = 10
, eoResetCycles = 30
, eoDriveEarly = True
, eoTimeoutMs = Nothing
, eoTrace = False
}
instance (TestType a, C.KnownDomain dom) => Test (DfExperimental.Df dom a) where
expectN ::
forall m.
(HasCallStack, H.MonadTest m) =>
Proxy (DfExperimental.Df dom a) ->
ExpectOptions ->
[Maybe a] ->
m [a]
expectN Proxy eOpts sampled = do
go eOpts.eoSampleMax maxEmptyCycles sampled
where
maxEmptyCycles = expectedEmptyCycles eOpts
go :: (HasCallStack) => Int -> Int -> [Maybe a] -> m [a]
go _timeout _n [] =
error "unexpected end of signal"
go 0 _ _ =
H.failWith
Nothing
( "Sample limit reached after sampling "
<> show eOpts.eoSampleMax
<> " samples. "
<> "Consider increasing 'eoSampleMax' in 'ExpectOptions'."
)
go _ 0 _ =
pure []
go sampleTimeout _emptyTimeout (Just a : as) =
(a :) <$> go (sampleTimeout - 1) maxEmptyCycles as
go sampleTimeout emptyTimeout (Nothing : as) =
go sampleTimeout (emptyTimeout - 1) as
instance
( Test a
, C.KnownNat n
, 1 <= (n * SimulateChannels a)
, 1 <= n
) =>
Test (C.Vec n a)
where
expectN ::
forall m.
(HasCallStack, H.MonadTest m) =>
Proxy (C.Vec n a) ->
ExpectOptions ->
C.Vec n (SimulateFwdType a) ->
m (C.Vec n (ExpectType a))
expectN Proxy opts = mapM (expectN (Proxy @a) opts)
instance Test () where
expectN _ _ _ = pure ()
instance
( Test a
, Test b
, 1 <= (SimulateChannels a + SimulateChannels b)
) =>
Test (a, b)
where
expectN ::
forall m.
(HasCallStack, H.MonadTest m) =>
Proxy (a, b) ->
ExpectOptions ->
(SimulateFwdType a, SimulateFwdType b) ->
m (ExpectType a, ExpectType b)
expectN Proxy opts (sampledA, sampledB) = do
trimmedA <- expectN (Proxy @a) opts sampledA
trimmedB <- expectN (Proxy @b) opts sampledB
pure (trimmedA, trimmedB)
testTupleInstances 3 9