packages feed

madlang-0.1.0.0: test/Spec.hs

{-# LANGUAGE OverloadedStrings #-}

import Test.Hspec
import Test.Hspec.Megaparsec
import Text.Madlibs
import Text.Megaparsec
import Control.Monad.IO.Class
import Control.Monad.State
import Data.Function
import Control.Exception
import qualified Data.Text as T
import System.IO.Unsafe

main :: IO ()
main = hspec $ do
    describe "parseTok" $ do
        it "parses a .mad string" $ do
            parseTok madFile `shouldParse` (List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])])
        it "fails when quotes aren't closed" $ do
            parseTok `shouldFailOn` madFileFailure
        it "parses when functions are out of order" $ do
            parseTok `shouldSucceedOn` madComplexFile
        it "returns a correct string from the template when evaluating a token" $ do
            (testIO . run) exampleTok `shouldSatisfy` (\a -> on (||) (a ==) "heads" "tails")
        it "throws exception when two `:return`s are declared" $ do
            (parseTok `shouldFailOn` semErrFile) `shouldThrow` semErr
            --this is still behaving weirdly but I don't care
            --also we need a parse error one but that shouldn't be too hard idk

semErr :: Selector SemanticError
semErr = const True

exampleTok :: RandTok
exampleTok = List [(1.0,List [(0.5,Value "heads"),(0.5,Value "tails")])]

madFile :: T.Text
madFile = ":define something\n    0.5 \"heads\"\n    0.5 \"tails\"\n:return\n    1.0 something"

madFileFailure :: T.Text
madFileFailure = ":define something\
\    0.5 \"heads\"\
\    0.5 \"tails\
\:return\
\    1.0 something"

madComplexFile :: T.Text
madComplexFile = ":define person\
\    0.7 \"I will \"\
\    0.3 \"You will \"\
\:define goodfortune\
\    0.1 person \"make nice things happen today\"\
\    0.9 \"nice things will happen today\"\
\:define fortune\
\    0.5 \"drink a boatload of milk\"\
\    0.5 \"get heckin angry\"\
\:return\
\    0.8 person fortune\
\    0.2 goodfortune"

semErrFile :: T.Text
semErrFile = ":define something\
\    0.5 \"heads\"\
\    0.5 \"tails\"\
\:return\
\    1.0 something\
\:return\
\    0.5 something\
\    0.5 \"it doesn't matter b/c this is gonna blow up in our faces anyways\""

-- | for the testing framework; to 
testIO :: IO a -> a
testIO = unsafePerformIO