packages feed

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"