telescope-0.4.1: test/Test/ParserSpec.hs
module Test.ParserSpec where
import Data.List (isInfixOf)
import Effectful
import Effectful.Error.Static
import Effectful.NonDet
import Skeletest
import Skeletest.Predicate qualified as P
import Telescope.Data.Parser
spec :: Spec
spec = do
describe "Data.Parser" $ do
describe "parsing" $ do
it "parses something" $ do
res <- runParseTest $ do
pure "hello"
res `shouldBe` Right ("hello" :: String)
it "can handle alternatives" $ do
let pa = pure ()
res <- runParseTest pa
res `shouldBe` Right ()
let pb = pure ()
res2 <- runParseTest $ runParserAlts (parseFail "Empty") empty
res2 `shouldSatisfy` P.left P.anything
res3 <- runParseTest $ runParserAlts (parseFail "Empty") (empty <|> pb)
res3 `shouldBe` Right ()
describe "location " $ do
it "changes failure to location" $ do
res <- runParseTest $ do
parseAt (Child "hello") $ parseAt (Index 2) $ do
parseFail "nope"
case res of
Left (ParseFailure path err) -> do
path `shouldBe` Path [Child "hello", Index 2]
err `shouldBe` "nope"
Right _ -> failTest "Expected failure"
it "gives good expected messages" $ do
res :: Either ParseError () <- runParseTest $ do
parseAt (Child "child") $ parseAt (Index 2) $ expected "Number" (1 :: Int)
("child/2" `isInfixOf` show res) `shouldBe` True
("1" `isInfixOf` show res) `shouldBe` True
("Number" `isInfixOf` show res) `shouldBe` True
runParseTest :: Eff [Parser, Error ParseError, IOE] a -> IO (Either ParseError a)
runParseTest eff = do
runEff . runErrorNoCallStack @ParseError . runParser $ eff