Haskell - 从任一数据类型生成缺少参数的错误消息

时间:2016-06-30 19:39:22

标签: haskell testing optionparser

我有以下代码;

module Billing.Options
  (
      GlobalOpts(..)
    , globalOptsParser
    , parseDb
    , parseSql
  ) 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]

我正在使用以下代码测试我的参数解析器;

error' = let mp = runParser AllowOpts globalOptsParser ["-d", "billing"]
          opts = ParserPrefs "suffix" False False False 80
      in fst $ runP mp opts

所需的参数是,

  -d <DB name>
  --sql <SQL SELECT statement>

我想测试我收到错误消息

Missing: --sql <SQL SELECT statement>

当我只指定“-d billing”时。

如果我打印结果,上面的测试代码会给出以下输出

Left (MissingError (MultNode [MultNode [MultNode [AltNode [Leaf (Chunk {unChunk = Just --sql <SQL SELECT statement>})]]]]))

有没有办法从上面的结果生成预期的错误消息(String)(两种数据类型)? Haskell是否提供了一个明显的功能用于此目的,因为我在文档中找不到某些内容,谷歌搜索示例也没有产生任何答案。

1 个答案:

答案 0 :(得分:2)

如果查看optparse-applicative (link)的源代码存储库,您会发现它本身在tests子目录中有一个测试套件。

tests/Test.hs文件checkHelpTextWith :: Show a => ExitCode -> ParserPrefs -> String -> ParserInfo a -> [String] -> Assertion checkHelpTextWith ecode pprefs name p args = do let result = execParserPure pprefs p args assertError result $ \failure -> do expected <- readFile $ name ++ ".err.txt" let (msg, code) = renderFailure failure name expected @=? msg ++ "\n" ecode @=? code checkHelpTextWith看起来像你想要的那样的例程:

execParserPure :: ParserPrefs -> ParserInfo a -> [String] -> ParserResult a

renderFailure :: ParserFailure ParserHelp -> String -> (String, ExitCode)

此函数需要选项解析器失败,并将错误消息与文件内容进行比较。

感兴趣的主要功能是:

renderFailure

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script> <script> document.domain = 'company.com'; if (sessionStorage.getItem('url') == null) { window.location; } else { document.getElementById("MSOPageViewerWebPart_WebPartWPQ2").src = sessionStorage.getItem('url'); }; $(window).bind("load", function() { sessionStorage.removeItem('url'); setTimeout(refresh, 30000); }); function refresh () { var myURL = document.getElementById("MSOPageViewerWebPart_WebPartWPQ2").contentDocument.location.href; sessionStorage.setItem('url', myURL); top.parent.location.href = top.parent.location.href; }; </script> 返回的字符串是错误消息。