cimple-0.0.26: test/Language/Cimple/DescribeAstSpec.hs
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Language.Cimple.DescribeAstSpec where
import Test.Hspec (Spec, describe, it, shouldBe,
shouldNotContain)
import Control.Monad (unless)
import Data.List (isInfixOf)
import qualified Data.List.Extra as List
import Data.Text (Text)
import qualified Data.Text as Text
import Language.Cimple.IO (parseExpr, parseStmt, parseText)
import Language.CimpleSpec (sampleToken)
import Test.QuickCheck (Testable (property))
expected :: (Text -> Either String a) -> Text -> String
expected parse code =
case parse code of
Left err -> snd $ List.breakOn "expected " err
Right _ -> ""
spec :: Spec
spec = do
describe "error messages" $ do
it "has useful suggestions" $ do
parseText "int a() {}" `shouldBe` Left
":1:10: Parse error near right brace: \"}\"; expected statement or declaration"
expected parseText "Beep Boop" `shouldBe`
"expected variable name"
expected parseText "const *a() {}" `shouldBe`
"expected type specifier"
expected parseText "int a() { int }" `shouldBe`
"expected variable name"
expected parseStmt "(int){" `shouldBe`
"expected constant or literal"
it "has suggestions for any sequence of tokens in top level" $ do
property $ \tokens -> do
let msg = expected parseText (Text.intercalate " " (map sampleToken tokens))
unless ("\"ifndefDefine\"" `isInfixOf` msg) $
msg `shouldNotContain` "expected one of"
it "has suggestions for any sequence of tokens in expressions" $ do
property $ \tokens ->
expected parseExpr (Text.intercalate " " (map sampleToken tokens)) `shouldNotContain`
"expected one of"
it "has suggestions for any sequence of tokens in statements" $ do
property $ \tokens ->
expected parseStmt (Text.intercalate " " (map sampleToken tokens)) `shouldNotContain`
"expected one of"
it "does not support multiple declarators per declaration" $ do
let ast = parseText "int main() { int a, b; }"
ast `shouldBe` Left
":1:19: Parse error near comma: \",\"; expected '=' or ';'"