packages feed

opt-env-conf-test-0.0.0.0: test/OptEnvConf/NonDetSpec.hs

{-# LANGUAGE ApplicativeDo #-}

module OptEnvConf.NonDetSpec (spec) where

import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import OptEnvConf.NonDet
import Test.Syd

spec :: Spec
spec = do
  describe "runNonDet" $ do
    it "can guard against previous values" $
      runNonDet
        ( do
            a <- liftNonDetTList [1, 2 :: Int]
            b <- liftNonDetTList [3, 4]
            guard $ even $ a + b
            pure (a, b)
        )
        `shouldBe` [(1, 3), (2, 4)]
    it "can recover from failures with <|>" $
      runNonDet
        ( do
            a <- liftNonDetTList [1, 2 :: Int]
            f <- liftNonDetTList [even] <|> liftNonDetTList [odd]
            guard $ f a
            pure a
        )
        `shouldBe` [1, 2]

  describe "runNonDetT" $ do
    it "can recover from underlying errors" $ do
      let f :: NonDetT (Either String) Int
          f = do
            i <- liftNonDetTList [1, 2]
            if odd i
              then do
                () <- empty
                lift (Left "err")
              else pure i

      runNonDetT f `shouldBe` Right [2]