module Test.Hspec.NeedEnv
(
EnvMode(..),
needEnv,
needEnvParse,
needEnvRead,
needEnvHostPort
) where
import Control.Applicative ((<$>), (<*>))
import Data.Monoid ((<>))
import System.Environment (lookupEnv)
import Test.Hspec.Core.Spec (pendingWith)
import Test.Hspec.Expectations (expectationFailure)
import Text.Read (readEither)
data EnvMode = Need
| Want
deriving (Int -> EnvMode -> ShowS
[EnvMode] -> ShowS
EnvMode -> String
(Int -> EnvMode -> ShowS)
-> (EnvMode -> String) -> ([EnvMode] -> ShowS) -> Show EnvMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EnvMode] -> ShowS
$cshowList :: [EnvMode] -> ShowS
show :: EnvMode -> String
$cshow :: EnvMode -> String
showsPrec :: Int -> EnvMode -> ShowS
$cshowsPrec :: Int -> EnvMode -> ShowS
Show,EnvMode -> EnvMode -> Bool
(EnvMode -> EnvMode -> Bool)
-> (EnvMode -> EnvMode -> Bool) -> Eq EnvMode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EnvMode -> EnvMode -> Bool
$c/= :: EnvMode -> EnvMode -> Bool
== :: EnvMode -> EnvMode -> Bool
$c== :: EnvMode -> EnvMode -> Bool
Eq,Eq EnvMode
Eq EnvMode
-> (EnvMode -> EnvMode -> Ordering)
-> (EnvMode -> EnvMode -> Bool)
-> (EnvMode -> EnvMode -> Bool)
-> (EnvMode -> EnvMode -> Bool)
-> (EnvMode -> EnvMode -> Bool)
-> (EnvMode -> EnvMode -> EnvMode)
-> (EnvMode -> EnvMode -> EnvMode)
-> Ord EnvMode
EnvMode -> EnvMode -> Bool
EnvMode -> EnvMode -> Ordering
EnvMode -> EnvMode -> EnvMode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: EnvMode -> EnvMode -> EnvMode
$cmin :: EnvMode -> EnvMode -> EnvMode
max :: EnvMode -> EnvMode -> EnvMode
$cmax :: EnvMode -> EnvMode -> EnvMode
>= :: EnvMode -> EnvMode -> Bool
$c>= :: EnvMode -> EnvMode -> Bool
> :: EnvMode -> EnvMode -> Bool
$c> :: EnvMode -> EnvMode -> Bool
<= :: EnvMode -> EnvMode -> Bool
$c<= :: EnvMode -> EnvMode -> Bool
< :: EnvMode -> EnvMode -> Bool
$c< :: EnvMode -> EnvMode -> Bool
compare :: EnvMode -> EnvMode -> Ordering
$ccompare :: EnvMode -> EnvMode -> Ordering
$cp1Ord :: Eq EnvMode
Ord,Int -> EnvMode
EnvMode -> Int
EnvMode -> [EnvMode]
EnvMode -> EnvMode
EnvMode -> EnvMode -> [EnvMode]
EnvMode -> EnvMode -> EnvMode -> [EnvMode]
(EnvMode -> EnvMode)
-> (EnvMode -> EnvMode)
-> (Int -> EnvMode)
-> (EnvMode -> Int)
-> (EnvMode -> [EnvMode])
-> (EnvMode -> EnvMode -> [EnvMode])
-> (EnvMode -> EnvMode -> [EnvMode])
-> (EnvMode -> EnvMode -> EnvMode -> [EnvMode])
-> Enum EnvMode
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: EnvMode -> EnvMode -> EnvMode -> [EnvMode]
$cenumFromThenTo :: EnvMode -> EnvMode -> EnvMode -> [EnvMode]
enumFromTo :: EnvMode -> EnvMode -> [EnvMode]
$cenumFromTo :: EnvMode -> EnvMode -> [EnvMode]
enumFromThen :: EnvMode -> EnvMode -> [EnvMode]
$cenumFromThen :: EnvMode -> EnvMode -> [EnvMode]
enumFrom :: EnvMode -> [EnvMode]
$cenumFrom :: EnvMode -> [EnvMode]
fromEnum :: EnvMode -> Int
$cfromEnum :: EnvMode -> Int
toEnum :: Int -> EnvMode
$ctoEnum :: Int -> EnvMode
pred :: EnvMode -> EnvMode
$cpred :: EnvMode -> EnvMode
succ :: EnvMode -> EnvMode
$csucc :: EnvMode -> EnvMode
Enum,EnvMode
EnvMode -> EnvMode -> Bounded EnvMode
forall a. a -> a -> Bounded a
maxBound :: EnvMode
$cmaxBound :: EnvMode
minBound :: EnvMode
$cminBound :: EnvMode
Bounded)
needEnv :: EnvMode
-> String
-> IO String
needEnv :: EnvMode -> String -> IO String
needEnv EnvMode
mode String
envkey = do
Maybe String
mval <- String -> IO (Maybe String)
lookupEnv String
envkey
case Maybe String
mval of
Maybe String
Nothing -> do
String -> Expectation
signalMsg (String
"Environment variable " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
envkey String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" is not set.")
String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
""
Just String
str -> String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
str
where
signalMsg :: String -> Expectation
signalMsg = case EnvMode
mode of
EnvMode
Need -> HasCallStack => String -> Expectation
String -> Expectation
expectationFailure
EnvMode
Want -> HasCallStack => String -> Expectation
String -> Expectation
pendingWith
needEnvParse :: EnvMode
-> (String -> Either String a)
-> String
-> IO a
needEnvParse :: EnvMode -> (String -> Either String a) -> String -> IO a
needEnvParse EnvMode
mode String -> Either String a
parseEnvVal String
envkey = do
String
val_str <- EnvMode -> String -> IO String
needEnv EnvMode
mode String
envkey
case String -> Either String a
parseEnvVal String
val_str of
Right a
val -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
val
Left String
e -> do
let error_msg :: String
error_msg = String
"Fail to parse environment variable " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
envkey String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
": " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
e
HasCallStack => String -> Expectation
String -> Expectation
expectationFailure String
error_msg
String -> IO a
forall a. HasCallStack => String -> a
error String
error_msg
needEnvRead :: (Read a)
=> EnvMode -> String -> IO a
needEnvRead :: EnvMode -> String -> IO a
needEnvRead EnvMode
mode = EnvMode -> (String -> Either String a) -> String -> IO a
forall a. EnvMode -> (String -> Either String a) -> String -> IO a
needEnvParse EnvMode
mode String -> Either String a
forall a. Read a => String -> Either String a
readEither
needEnvHostPort :: EnvMode
-> String
-> IO (String,Int)
needEnvHostPort :: EnvMode -> String -> IO (String, Int)
needEnvHostPort EnvMode
mode String
prefix = (,) (String -> Int -> (String, Int))
-> IO String -> IO (Int -> (String, Int))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
needStr String
"_HOST" IO (Int -> (String, Int)) -> IO Int -> IO (String, Int)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> IO Int
forall a. Read a => String -> IO a
needInt String
"_PORT"
where
needStr :: String -> IO String
needStr String
suffix = EnvMode -> String -> IO String
needEnv EnvMode
mode (String
prefix String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
suffix)
needInt :: String -> IO a
needInt String
suffix = EnvMode -> String -> IO a
forall a. Read a => EnvMode -> String -> IO a
needEnvRead EnvMode
mode (String
prefix String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
suffix)