2016-06-30 8 views
1

Ich habe das folgende Stück Code;Haskell - generieren fehlende Argument Fehlermeldung von beiden Datentyp

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] 

Ich teste meinen Argument Parser mit dem folgenden Code;

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

Die erforderlichen Argumente sind,

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

ich, dass ich die Fehlermeldung, erhalten testen wollen nur

Missing: --sql <SQL SELECT statement> 

, wenn ich "-d billing" angeben.

Der obige Test-Code gibt die folgende Ausgabe, wenn ich das Ergebnis drucken,

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

Gibt es eine Möglichkeit, die erwartete Fehlermeldung (String) aus dem obigen Ergebnis (entweder Datentyp) zu generieren? Hat Haskell eine offensichtliche Funktion für diesen Zweck zu verwenden, da ich etwas in der Dokumentation nicht finden kann und googlen für Beispiele auch keine Antworten produziert.

+3

Es gibt eine Vielzahl von Befehlszeilenbibliotheken für Haskell, also sollten Sie uns wirklich mitteilen, welche Bibliothek Sie verwenden und Ihre Importe einschließen. – ErikR

+0

Entschuldigung, ich habe meine Frage aktualisiert. –

+0

@TresiaBurger Also .... verwenden Sie dann http: // hackage.haskell.org/package/optarse-applicative? –

Antwort

2

Wenn Sie das Quellcode-Repository für optparse-applicative(link) betrachten, werden Sie sehen, dass es selbst eine Testsuite im tests Unterverzeichnis hat.

Eine Routine, die wie es aussieht, tut viel wie das, was Sie wollen checkHelpTextWith in der Datei ist 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 

Diese Funktion eine Option Parser die Fehlermeldung mit dem Inhalt einer Datei zu scheitern und vergleicht erwartet .

Die wichtigsten Funktionen von Interesse sind:

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

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

Der String zurückgegeben von renderFailure ist die Fehlermeldung.

Verwandte Themen