cimple-0.0.26: test/Language/Cimple/ParserSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Language.Cimple.ParserSpec where
import Data.Fix (Fix (..))
import Data.Text (Text)
import qualified Data.Text as Text
import Test.Hspec (Spec, describe, it, shouldBe,
shouldSatisfy)
import Language.Cimple (AlexPosn (..), Lexeme (..),
LexemeClass (..), Node, NodeF (..),
Scope (..))
import Language.Cimple.IO (parseText)
isRight1 :: Either a [b] -> Bool
isRight1 (Right [_]) = True
isRight1 _ = False
parseLines :: [Text] -> Either String [Node (Lexeme Text)]
parseLines = parseText . Text.unlines
spec :: Spec
spec = do
describe "C parsing" $ do
it "should parse a simple function" $ do
let ast = parseText "int a(void) { return 3; }"
ast `shouldSatisfy` isRight1
it "should parse per-param non_null and nullable annotations" $ do
let ast = parseText "int a(char *_Nonnull p, int *_Nullable q);"
ast `shouldSatisfy` isRight1
it "should parse a type declaration" $ do
let ast = parseText "typedef struct Foo { int x; } Foo;"
ast `shouldSatisfy` isRight1
it "should parse a struct with bit fields" $ do
let ast = parseText "typedef struct Foo { int x : 123; } Foo;"
ast `shouldSatisfy` isRight1
it "should parse a struct with preprocessor conditionals" $ do
let ast = parseText $ Text.unlines
[ "struct Foo {"
, " int x;"
, "#ifndef HAVE_FOO_BAR"
, " int foo_bar;"
, "#endif /* HAVE_FOO_BAR */"
, " int y;"
, "};"
]
ast `shouldSatisfy` isRight1
it "should parse a comment" $ do
let ast = parseText "/* hello */"
ast `shouldSatisfy` isRight1
it "supports single declarators" $ do
let ast = parseText "int main() { int a; }"
ast `shouldBe` Right
[ Fix (FunctionDefn Global
(Fix (FunctionPrototype
(Fix (TyStd (L (AlexPn 0 1 1) IdStdType "int")))
(L (AlexPn 4 1 5) IdVar "main")
[]))
(Fix (CompoundStmt
[ Fix (VarDeclStmt
(Fix (VarDecl
(Fix (TyStd (L (AlexPn 13 1 14) IdStdType "int")))
(L (AlexPn 17 1 18) IdVar "a")
[])) Nothing)])))
]