keiki-0.2.0.0: test/Keiki/CompositionStatefulSpec.hs
module Keiki.CompositionStatefulSpec (spec) where
import Control.Exception (evaluate)
import Data.Text qualified as Text
import Keiki.Composition (compose)
import Keiki.Core
import Keiki.Fixtures.ComposeStateful
import Keiki.Render.Pretty (prettyPred)
import Keiki.Symbolic (isSingleValuedSym, withSymPred)
import Test.Hspec
spec :: Spec
spec = do
describe "compose counterSource lastValueSink" $
it "stores the pre-increment count in the sink" $ do
let pipeline = compose counterSource lastValueSink
case step pipeline (initial pipeline, initialRegs pipeline) Tick of
Just (_, regs, outputs) -> do
readSourceCount regs `shouldBe` 1
readSinkLast regs `shouldBe` 0
outputs `shouldBe` [OutVal 0]
Nothing -> expectationFailure "expected the composed counter step to succeed"
describe "compose pairSource twoPhaseSink" $
it "fires phase 1 then phase 2 and ends at phase 2" $ do
let pipeline = compose pairSource twoPhaseSink
case step pipeline (initial pipeline, initialRegs pipeline) Go of
Just (_, regs, outputs) -> do
readPhase regs `shouldBe` 2
outputs `shouldBe` [Stage1 10, Stage2 20]
Nothing -> expectationFailure "expected the composed two-phase step to succeed"
describe "compose m2aSource wrongOrderSink" $ do
it "steps via the M2A edge without raising" $ do
let pipeline = compose m2aSource wrongOrderSink
result <- evaluate (step pipeline (initial pipeline, initialRegs pipeline) ProduceA)
case result of
Just (_, _, outputs) -> outputs `shouldBe` [SawA 5]
Nothing -> expectationFailure "expected the matching M2A edge to fire"
it "is safe for symbolic, pretty-printing, and replay walkers" $ do
let pipeline = compose m2aSource wrongOrderSink
renderedGuards = map (prettyPred . guard) (edgesOut pipeline (initial pipeline))
isSingleValuedSym (withSymPred pipeline) `shouldBe` True
sum (map Text.length renderedGuards) `shouldSatisfy` (> 0)
case reconstitute pipeline [SawA 5] of
Just _ -> pure ()
Nothing -> expectationFailure "expected the valid SawA event to replay"