module Language.ParserSpec where

import Test.Hspec

import Language.Lexer
import Language.Parser
import Language.Expr

spec :: Spec
spec = do
    describe "parser" $ do
        context "BinOp" $ do
            it "should parse binary addition" $ do
                let input = [NumberTok "12", AddTok, NumberTok "12"]
                expr input `shouldBe` ProgEnd (BinOp Add (Number "12") (Number "12"))

            it "should parse addition of more than one term" $ do
                let input = [NumberTok "12", AddTok, NumberTok "12", AddTok, NumberTok "12"]
                expr input `shouldBe` ProgEnd (BinOp Add (BinOp Add (Number "12") (Number "12")) (Number "12"))

            it "should parse order of operations correctly" $ do
                let input = [NumberTok "12", AddTok, NumberTok "12", AddTok, NumberTok "12"]
                expr input `shouldBe` ProgEnd (BinOp Add (BinOp Add (Number "12") (Number "12")) (Number "12"))

        context "should be able to handle multiple expressions" $ do
            it "should parse the entire expression" $ do
                let input = [NumberTok "1", AddTok, NumberTok "1", TerminatorTok, NumberTok "1", AddTok, NumberTok "1"]
                expr input `shouldBe` ProgCont
                    (BinOp Add (Number "1") (Number "1"))
                    (ProgEnd (BinOp Add (Number "1") (Number "1")))

            it "should not result in a parse error" $ do
                let input = [NumberTok "1", AddTok, NumberTok "1", TerminatorTok]
                expr input `shouldBe` ProgEnd (BinOp Add (Number "1") (Number "1"))

main :: IO ()
main = hspec spec
