packages feed

hedn-0.1.3.0: tests/TestParser.hs

{-# LANGUAGE OverloadedStrings, Rank2Types #-}

module Main where

import Data.Attoparsec.Lazy as A
import qualified Data.ByteString.Lazy.Char8 as BSL

import Data.EDN.Parser as P
import Data.EDN.Types as E

import Control.Monad (forM_)
import qualified System.Console.ANSI as ANSI

main :: IO ()
main = forM_ cases $ checkCase (parse P.parseTagged) (parserResult)

parserResult :: Eq a => Result a -> a -> Bool
parserResult result output = case result of
    Done "" o -> o == output
    _         -> False

checkCase :: forall a a1. (Show a1, Show a) => (BSL.ByteString -> a1)
                                            -> (a1 -> a -> Bool)
                                            -> (BSL.ByteString, a)
                                            -> IO ()
checkCase runner checker (input, output) = do
    putStr "Checking: '"
    BSL.putStr input
    putStrLn "'"

    putStrLn $ "Should be: " ++ show output

    let result = runner input
    let correct = checker result output

    ANSI.setSGR [ANSI.SetColor ANSI.Foreground ANSI.Vivid (if correct then ANSI.Green else ANSI.Red)]
    putStr "Result: "
    ANSI.setSGR [ANSI.Reset]
    print result
    putStrLn ""

cases :: [(BSL.ByteString, E.TaggedValue)]
cases = map (\(i, o) -> (i, E.NoTag o)) noTags ++ haveTags

noTags :: [(BSL.ByteString, E.Value)]
noTags = [ ("nil", Nil)

         , ("true", E.Boolean True)
         , ("false", E.Boolean False)

         , ("\"a nice string\"", E.String "a nice string")
         , ("\"split\\second \\t\\rai\\n\"", E.String "split\\second \t\rai\n")
         , ("\"test \\\"sausage\\\" shmest\"", E.String "test \"sausage\" shmest")
         , ("\"\"", E.String "")

         , ("\\c", E.Character 'c')
         , ("\\\\", E.Character '\\')
         , ("\\newline", E.Character '\n')
         , ("\\space", E.Character ' ')
         , ("\\tab", E.Character '\t')

         , ("justasymbol", E.Symbol "" "justasymbol")
         , ("with#stuff:inside", E.Symbol "" "with#stuff:inside")
         , ("my-namespace/foo", E.Symbol "my-namespace" "foo")
         , ("/", E.Symbol "" "/")

         , (":fred", E.Keyword "fred")
         , (":my/fred", E.Keyword "my/fred")

         , ("42", E.Integer 42)
         , ("-1", E.Integer (-1))

         , ("100.50", E.Floating 100.5)
         , ("-3.14", E.Floating (-3.14))
         -- ...and many other strange stuff...

         , ("(a b 42)", sampleList)
         , ("()", E.List [])

         , ("[a b 42]", sampleVec)
         , ("[]", E.makeVec [])

         , ("{:a 1 \"foo\" :bar [1 2 3] four}", sampleMap)
         , ("{}", E.makeMap [])

         , ("#{a b [1 2 3]}", sampleSet)
         , ("#{}", E.makeSet [])

         , ("[a b #_foo 42]", sampleDiscard)
         , ("(1 2 ;more to go!\n 3 4)", sampleComment)
         ]

haveTags :: [(BSL.ByteString, E.TaggedValue)]
haveTags = [ ("#myapp/Person {:first \"Fred\" :last \"Mertz\"}", E.Tagged sampleTaggedMap "myapp" "Person")
           , ("{:first \"Fred\" :last \"Mertz\"}", E.NoTag sampleTaggedMap)
           ]

sampleList :: E.Value
sampleList = E.makeList [E.Symbol "" "a", E.Symbol "" "b", E.Integer 42]

sampleVec :: E.Value
sampleVec = E.makeVec [E.Symbol "" "a", E.Symbol "" "b", E.Integer 42]

sampleMap :: E.Value
sampleMap = E.makeMap [ (E.Keyword "a",                                     E.Integer 1)
                      , (E.String "foo",                                    E.Keyword "bar")
                      , (E.makeVec [E.Integer 1, E.Integer 2, E.Integer 3], E.Symbol "" "four")
                      ]

sampleSet :: E.Value
sampleSet = E.makeSet [ E.Symbol "" "a"
                      , E.Symbol "" "b"
                      , E.makeVec [E.Integer 1, E.Integer 2, E.Integer 3]
                      ]

sampleDiscard :: E.Value
sampleDiscard = E.makeVec [E.Symbol "" "a", E.Symbol "" "b", E.Integer 42]

sampleComment :: E.Value
sampleComment = E.makeList [E.Integer 1, E.Integer 2, E.Integer 3, E.Integer 4]

sampleTaggedMap :: E.Value
sampleTaggedMap = E.makeMap [ (E.Keyword "first", E.String "Fred")
                            , (E.Keyword "last", E.String "Mertz")
                            ]