I'm new to Haskell.
I have written the following piece of code which will parse the arguments sent to a script;
module Billing.Options
(
GlobalOpts(..)
, globalOptsParser
, parseDb
) where
import Options.Applicative
import Options.Applicative.Simple
import Options.Applicative.Types
import System.FilePath.Posix
import Text.Regex.PCRE
-- ------------------------------------------------------------
data GlobalOpts = GlobalOpts
{
optDb :: String,
optSql :: String
} deriving Show
-- ------------------------------------------------------------
globalOptsParser :: Parser GlobalOpts
globalOptsParser = GlobalOpts
<$> option (parseDb =<< readerAsk)
( long "db"
<> short 'd'
<> metavar "<DB name>"
<> help "dmt | report"
)
<*> option parseSql
( long "sql"
<> metavar "<SQL SELECT statement>"
<> help "sql select statement to use in order to generate JSON config file"
)
-- ------------------------------------------------------------
matches :: String -> String -> Bool
matches = (=~)
-- ------------------------------------------------------------
parseDb :: String -> ReadM String
parseDb val = do
if not (elem val ["dmt", "report"])
then readerError $ "Unknown DB, '" ++ val ++ "'"
else return val
-- ------------------------------------------------------------
parseSql :: ReadM String
parseSql = do
val <- readerAsk
if not (val `matches` "(?i)select .+ from .+")
then readerError $ "Please provide a valid SQL SELECT statement"
else return val
-- [EOF]
I want to test the "parseDb" function above with hspec. I want to ensure that a "readerError" will be thrown when an unknown database is specified. Thus I want to test that the function call parseDb "unknown" generates a "readerError" call which according to me should throw an exception.
I have tried the hspec shouldThrow function but it doesn't work. Seems no exception was thrown. The return type for readerError is "ReadM a". After spending a few days reading up on monads and reader monads I'm still stuck (and confused) and have no idea how to test this and whether it is even possible to test it. Couldn't find any relevant examples when I googled.