summaryrefslogtreecommitdiff
path: root/tests/Language/Elna/NameAnalysisSpec.hs
blob: c94e6c71c36669660da803ffd2fdb92bc3283ad5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
module Language.Elna.NameAnalysisSpec
    ( spec
    ) where

import Data.Text (Text)
import Text.Megaparsec (runParser)
import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy, pendingWith)
import Language.Elna.NameAnalysis (Error(..), nameAnalysis)
import Language.Elna.SymbolTable (Info(..), SymbolTable)
import qualified Language.Elna.SymbolTable as SymbolTable
import qualified Language.Elna.Parser as AST
import Language.Elna.Types (intType)
import Control.Exception (throwIO)

nameAnalysisOnText :: Text -> IO (Either Error SymbolTable)
nameAnalysisOnText sourceText = nameAnalysis
    <$> either throwIO pure (runParser AST.programP "" sourceText)

spec :: Spec
spec = describe "nameAnalysis" $ do
    it "adds type to the symbol table" $ do
        let given = "type A = int"
            expected = Right $ Just $ TypeInfo intType
        actual <- nameAnalysisOnText given

        actual `shouldSatisfy` (expected ==) . fmap (SymbolTable.lookup "A")

    it "errors when the aliased type is not defined" $ do
        let given = "type A = B"
            expected = Left $ UndefinedTypeError "B"
        actual <- nameAnalysisOnText given

        actual `shouldBe` expected

    it "errors if the aliased identifier is not a type" $ do
        let given = "proc main() {} type A = main"
            expected = Left
                $ UnexpectedTypeInfoError
                $ ProcedureInfo mempty mempty
        actual <- nameAnalysisOnText given

        actual `shouldBe` expected

    it "replaces the alias with an equivalent base type" $
        pendingWith "Not implemented"