wasp/waspc/test/AnalyzerTest.hs
Martin Šošić 4773ae36e3
Wrote initial version of new Wasp AST: AppSpec (#353)
* Introduced AppSpec, replacement for previous Wasp.hs as a core IR in Wasp.

* Organized AppSpec into Core and Domain.

* Removed Domain from AppSpec.

* Moved ExternalCode.File to AppSpec.

* Added some TODOs.

* Added IsDecl to AppSpec.

* Removed ExternalCode File reexports.

* Added comments.
2021-11-10 16:27:27 +01:00

87 lines
2.8 KiB
Haskell

{-# LANGUAGE TypeApplications #-}
module AnalyzerTest where
import Analyzer
import qualified Analyzer.TypeChecker as TC
import AppSpec.App (App)
import qualified AppSpec.App as App
import qualified AppSpec.AuthMethod as AuthMethod
import AppSpec.Core.Ref (Ref (..))
import AppSpec.Page (Page)
import qualified AppSpec.Page as Page
import Data.Either (isRight)
import Test.Tasty.Hspec
spec_Analyzer :: Spec
spec_Analyzer = do
describe "Analyzer" $ do
it "Analyzes a well-typed example" $ do
let source =
unlines
[ "app Todo {",
" title: \"Todo App\",",
" authMethod: EmailAndPassword,",
" defaultPage: HomePage",
"}",
"page HomePage { content: \"Hello world\" }"
]
let decls = analyze source
let expectedApps =
[ ( "Todo",
App.App
{ App.title = "Todo App",
App.authMethod = AuthMethod.EmailAndPassword,
App.defaultPage = Ref "HomePage"
}
)
]
takeDecls @App <$> decls `shouldBe` Right expectedApps
let expectedPages =
[ ( "HomePage",
Page.Page
{ Page.content = "Hello world"
}
)
]
takeDecls @Page <$> decls `shouldBe` Right expectedPages
it "Returns a type error if unexisting declaration is referenced" $ do
let source =
unlines
[ "page HomePage { content: \"Hello world\" }",
"app Todo {",
" title: \"Todo App\",",
" authMethod: EmailAndPassword,",
" defaultPage: NonExistentPage",
"}"
]
takeDecls @App <$> analyze source `shouldBe` Left (TypeError $ TC.UndefinedIdentifier "NonExistentPage")
it "Returns a type error if referenced declaration is of wrong type" $ do
let source =
unlines
[ "app Todo {",
" title: \"Todo App\",",
" authMethod: EmailAndPassword,",
" defaultPage: Todo",
"}"
]
takeDecls @App <$> analyze source `shouldSatisfy` isAnalyzerOutputTypeError
it "Works when referenced declaration is declared after the reference." $ do
let source =
unlines
[ "app Todo {",
" title: \"Todo App\",",
" authMethod: EmailAndPassword,",
" defaultPage: HomePage",
"}",
"page HomePage { content: \"Hello world\" }"
]
isRight (analyze source) `shouldBe` True
isAnalyzerOutputTypeError :: Either AnalyzeError a -> Bool
isAnalyzerOutputTypeError (Left (TypeError _)) = True
isAnalyzerOutputTypeError _ = False