packages feed

commandert-0.1.0.0: test/Test.hs

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE BlockArguments #-}
module Main where

import Test.Hspec
import Control.Monad.IO.Class
import Control.Monad.Commander
import Control.Applicative

main :: IO ()
main = hspec $ do
  describe "Control.Monad.Commander" do
    describe "runCommanderT" do
      it "runs Victory to Just" do
        runCommanderT (Victory ()) () `shouldReturn` Just ()
      it "runs Defeat to Nothing" do
        runCommanderT Defeat () `shouldReturn` Nothing @()
      it "runs pure to Just" do
        runCommanderT (pure ()) () `shouldReturn` Just ()
      it "runs a stateful action to completion" do
        let action = Action \n -> pure (if n > 0 then action else pure (), n - 1)
        runCommanderT action 100 `shouldReturn` Just ()
      it "backtracks successfully" do
        runCommanderT (Defeat <|> pure 10) () `shouldReturn` Just 10
        runCommanderT (Defeat <|> (Action \() -> pure (Defeat, ()))) () `shouldReturn` Nothing @()
        runCommanderT (Defeat <|> (Action \() -> pure (Defeat, ())) <|> pure 10) () `shouldReturn` Just 10
    it "has a reasonable functor instance" do
      runCommanderT (fmap (+ 1) (pure 10)) () `shouldReturn` Just 11
      x <- runCommanderT (fmap (+ 1) $ fmap (+ 2) (pure 10)) ()
      y <- runCommanderT (fmap ((+ 1) . (+ 2)) (pure 10)) ()
      x `shouldBe` y
    it "has a reasonable applicative instance" do
      runCommanderT (pure (+ 10) <*> pure 10) () `shouldReturn` Just 20
    it "has a reasonable monad instance" do
      runCommanderT (do { x <- pure 10; y <- pure 11; pure (x + y) }) () `shouldReturn` Just 21