docopt-0.6.0: test/LangAgnosticTests.hs
{-# LANGUAGE FlexibleInstances #-}
import Control.Monad (when, unless)
import System.Exit
import System.Console.ANSI
--import System.Directory
import System.Console.Docopt
import System.Console.Docopt.Types
import System.Console.Docopt.ParseUtils
import System.Console.Docopt.UsageParse (pDocopt)
import System.Console.Docopt.OptParse (getArguments)
import Data.Map (Map)
import qualified Data.Map as M
import Data.List.Split
import Data.Char (isSpace)
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as BS
instance ToJSON ArgValue where
toJSON x = case x of
MultiValue vs -> toJSON $ reverse vs
Value v -> toJSON v
NoValue -> toJSON Null
Counted n -> toJSON n
Present -> toJSON True
NotPresent -> toJSON False
instance ToJSON (Map Option ArgValue) where
toJSON argmap =
let argmap' = M.mapKeys humanize argmap
in toJSON argmap'
coloredString :: Color -> String -> String
coloredString c str = (setSGRCode [SetColor Foreground Dull c]) ++
str ++
(setSGRCode [Reset])
green = coloredString Green
red = coloredString Red
yellow = coloredString Yellow
blue = coloredString Blue
magenta = coloredString Magenta
forEach xs = sequence_ . (flip map) xs
main = do
--putStrLn =<< getCurrentDirectory
testFile <- readFile "test/testcases.docopt"
--putStrLn rawTests
let notCommentLine x = (null x) || ('#' /= head x)
testFileClean = unlines $ filter notCommentLine $ lines testFile
caseGroups = filter (not . null) $ splitOn "r\"\"\"" testFileClean
--putStrLn $ head caseGroups
forEach caseGroups $ \caseGroup -> do
let [usage, rawCases] = splitOn "\"\"\"" caseGroup
cases = filter (/= "\n") $ splitOn "$ " rawCases
optFormat <- case runParser pDocopt M.empty "Usage" usage of
Left e -> do
putStrLn "couldn't parse usage text"
return (Sequence [], M.empty)
Right o -> return o
putStrLn $ "Docopt:\n" ++ blue usage
putStrLn $ "Pattern:\n" ++ magenta (show optFormat)
--putStrLn $ "Cases: " ++ show cases
forEach cases $ \testcase -> do
let (cmdline, rawTarget_) = break (== '\n') testcase
rawTarget = filter (/= '\n') rawTarget_
maybeTargetJSON = decode (BS.pack rawTarget) :: Maybe Value
rawArgs = tail $ words cmdline
parsedArgs <- case getArguments optFormat rawArgs of
Left e -> do
putStrLn $ "Parse Error: " ++ (red $ show e)
return M.empty
Right a -> return a
let parsedArgsJSON = toJSON parsedArgs
testCaseSuccess = if (rawTarget == "\"user-error\"")
then M.null parsedArgs
else (maybeTargetJSON == Just parsedArgsJSON)
putStrLn $ "Case Cmd: " ++ yellow cmdline
putStrLn $ "Case Target: " ++ (if testCaseSuccess then green else magenta) rawTarget
unless testCaseSuccess $
putStrLn $ "Failure: " ++ red (BS.unpack $ encode parsedArgsJSON)
putStrLn ""
exitSuccess