exitcode-0.1.0.0: test/Tests.hs
import Control.Lens (review, (^.), (^?))
import Control.Monad.Trans.Maybe (MaybeT (MaybeT))
import Data.Functor.Classes (Eq1)
import Data.Functor.Identity (Identity (..), runIdentity)
import Data.Monoid ((<>))
import Test.QuickCheck (Arbitrary (..), suchThat)
import Test.QuickCheck.Checkers (EqProp (..), Test, TestBatch, eq)
import Test.QuickCheck.Classes (applicative, functor)
import Test.Tasty (TestTree, defaultMain, testGroup)
import Test.Tasty.HUnit (testCase, (@?=))
import Test.Tasty.QuickCheck (testProperty)
import Control.Exitcode (Exitcode, ExitcodeT, exitCode,
exitfailure0, exitsuccess,
exitsuccess0, runExitcode,
_ExitFailure, _ExitSuccess)
import System.Exit (ExitCode (..))
newtype EW f a = EW { unEW :: ExitcodeT f a } deriving (Eq, Show)
instance (Applicative f, Arbitrary a) => Arbitrary (EW f a) where
arbitrary = fmap (EW . pure) arbitrary
instance Functor f => Functor (EW f) where
fmap f = EW . fmap f . unEW
instance Applicative f => Applicative (EW f) where
pure = EW . pure
EW f <*> EW a = EW (f <*> a)
instance (Eq1 f, Eq a) => EqProp (EW f a) where
(=-=) = eq
type CheckMe = EW [] (Integer, Integer, Integer)
newtype NonZero = NonZero Int deriving Show
instance Arbitrary NonZero where
arbitrary = NonZero <$> suchThat arbitrary (/= 0)
main :: IO ()
main = defaultMain test_Exitcode
test_Exitcode :: TestTree
test_Exitcode =
testGroup "Exitcode" [
tastyCheckersBatch $ functor (undefined :: CheckMe)
, tastyCheckersBatch $ applicative (undefined :: CheckMe)
, applicativeTest
, exitFailurePrismTest
, exitSuccessPrismTest
, exitfailure0Test
, exitCodePrismTest
]
applicativeTest :: TestTree
applicativeTest =
testGroup "Applicative" [
testCase "Sticks to the Right" $
pure (<> "bar") <*> pure "foo" @?= (exitsuccess "foobar" :: Exitcode String)
]
exitFailurePrismTest :: TestTree
exitFailurePrismTest =
testGroup "_ExitFailure Prism" [
testProperty "review non-zero input" $
\(NonZero n) -> review _ExitFailure n == exitfailure0 n
, testCase "review 0" $
review _ExitFailure 0 @?= exitsuccess0
, testProperty "view non-zero input" $
\(NonZero n) -> exitfailure0 n ^? _ExitFailure == Just n
, testCase "view 0" $
exitfailure0 0 ^? _ExitFailure @?= Nothing
]
exitSuccessPrismTest :: TestTree
exitSuccessPrismTest =
testGroup "_ExitSuccess Prism" [
testCase "review" $
review _ExitSuccess () @?= exitsuccess0
, testCase "view exitsuccess0" $
exitsuccess0 ^? _ExitSuccess @?= Just ()
, testProperty "view exitfailure0 non-zero" $
\(NonZero n) -> exitfailure0 n ^? _ExitSuccess == Nothing
, testCase "view exitfailure0 0" $
exitfailure0 0 ^? _ExitSuccess @?= Just ()
]
exitfailure0Test :: TestTree
exitfailure0Test =
testGroup "exitfailure0" [
testProperty "non-zero input" $
\(NonZero n) -> (runIdentity . runExitcode) (exitfailure0 n) == Left n
, testCase "0" $
(runIdentity . runExitcode) (exitfailure0 0) @?= Right ()
]
exitCodePrismTest :: TestTree
exitCodePrismTest =
testGroup "exitCode Prism" [
testProperty "`exitfailure0 n`, where n is non-zero" $
\(NonZero n) -> (review exitCode (exitfailure0 n)) == Identity (ExitFailure n)
, testCase "review `exitfailure 0`" $
runIdentity (review exitCode (exitfailure0 0)) @?= ExitSuccess
, testCase "review `exitsuccess0`" $
runIdentity (review exitCode exitsuccess0) @?= ExitSuccess
, testProperty "view ExitFailure n, where n is non-zero" $
\(NonZero n) -> Identity (ExitFailure n) ^? exitCode == Just (exitfailure0 n)
, testCase "view ExitFailure 0" $
runExitcode (Identity (ExitFailure 0) ^. exitCode) @?= (MaybeT (Identity Nothing))
, testCase "view ExitSuccess" $
Identity ExitSuccess ^? exitCode @?= Just exitsuccess0
]
tastyCheckersBatch :: TestBatch -> TestTree
tastyCheckersBatch (name, tests) =
testGroup (name <> " laws") (tastyCheckersProperty <$> tests)
tastyCheckersProperty :: Test -> TestTree
tastyCheckersProperty =
uncurry testProperty