summaryrefslogtreecommitdiff
path: root/lambda-calcul/haskell/test
diff options
context:
space:
mode:
Diffstat (limited to 'lambda-calcul/haskell/test')
-rw-r--r--lambda-calcul/haskell/test/Minilang/REPL/NetSpec.hs13
-rw-r--r--lambda-calcul/haskell/test/Minilang/REPLSpec.hs20
-rw-r--r--lambda-calcul/haskell/test/Minilang/ServerSpec.hs20
3 files changed, 36 insertions, 17 deletions
diff --git a/lambda-calcul/haskell/test/Minilang/REPL/NetSpec.hs b/lambda-calcul/haskell/test/Minilang/REPL/NetSpec.hs
index 0c2be66..7f77eeb 100644
--- a/lambda-calcul/haskell/test/Minilang/REPL/NetSpec.hs
+++ b/lambda-calcul/haskell/test/Minilang/REPL/NetSpec.hs
@@ -68,17 +68,20 @@ spec :: Spec
spec = around withServer $
describe "MiniLang Network REPL" $ do
it "evaluates expression and returns evaluation result" $ \Server {serverPort} -> do
- let inp = [In "((lam (x) x) y)"]
- expectedOutput = [Right $ Evaluated (AST.Sym "y") (Var "y") (TyVar "b")]
+ let inp = [Com (Set (SelectLanguage Typed)), In "((lam (x) x) y)"]
+ expectedOutput =
+ [ Right (Msg "Language set to Typed"),
+ Right $ Evaluated (AST.Sym "y") (Var "y") (TyVar "b")
+ ]
res <- runTestClient serverPort ".newenv1" inp
res `shouldBe` expectedOutput
it "allows retrieving empty initial env" $ \Server {serverPort} -> do
- let inp = [Com (Set (SelectLanguage Untyped)), Com DumpEnv]
+ let inp = [Com (Set (SelectLanguage Typed)), Com DumpEnv]
expectedOutput =
- [ Right (Msg "Language set to Untyped"),
- Right $ CurrentEnv newEnv newContext Untyped
+ [ Right (Msg "Language set to Typed"),
+ Right $ CurrentEnv newEnv newContext Typed
]
res <- runTestClient serverPort ".newenv2" inp
diff --git a/lambda-calcul/haskell/test/Minilang/REPLSpec.hs b/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
index 5469a59..cf6ef01 100644
--- a/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
+++ b/lambda-calcul/haskell/test/Minilang/REPLSpec.hs
@@ -13,17 +13,17 @@ import Prelude hiding (lines, readFile, writeFile)
spec :: Spec
spec = parallel $
describe "MiniLang REPL" $ do
- it "evaluates MiniLang terms read from pure Monad" $ do
+ it "evaluates untyped MiniLang terms read from pure Monad" $ do
let out =
withInput
["((lam (x) x) y)"]
out
`shouldBe` [ "Bye!",
- "y : b"
+ "y : <?>"
]
- it "defaults to try to typecheck terms" $ do
+ it "defaults untyped terms" $ do
let out =
withInput
[ "(let ((Succ (lam (n z s) (s n))) \
@@ -33,13 +33,13 @@ spec = parallel $
out
`shouldBe` [ "Bye!",
- "Cannot unify type variable f with type (e -> f -> e) -> e due to circularity: The variable already occurs in the type."
+ "(lam (z s) (s ((lam (n z s) (s n)) (lam (z s) z)))) : <?>"
]
- it "do not typecheck term when language is set to 'untyped'" $ do
+ it "do typecheck term when language is set to 'Typed'" $ do
let out =
withInput
- [ ":lang Untyped",
+ [ ":lang Typed",
"(let ((Succ (lam (n z s) (s n))) \
\ (Zero (lam (z s) z))) \
\ (Succ (Succ Zero)))"
@@ -47,8 +47,8 @@ spec = parallel $
out
`shouldBe` [ "Bye!",
- "(lam (z s) (s ((lam (n z s) (s n)) (lam (z s) z)))) : <?>",
- "Language set to Untyped"
+ "Cannot unify type variable f with type (e -> f -> e) -> e due to circularity: The variable already occurs in the type.",
+ "Language set to Typed"
]
it "shows error when trying to load a non-existent file" $ do
@@ -65,7 +65,7 @@ spec = parallel $
fileName
"(let ((Succ (lam (n z s) (s n))) \
\ (Zero (lam (z s) z))) \
- \ Zero)"
+ \ (Succ Zero))"
_ <- withFile fileName ReadMode $ \hin ->
withFile outputFileName AppendMode $ \hout ->
@@ -74,7 +74,7 @@ spec = parallel $
out <- readFile outputFileName
out
- `shouldBe` "\955\928> (lam (z s) z) : c -> d -> c\n\955\928> Bye!\n"
+ `shouldBe` "\955\928> (lam (z s) (s (lam (z s) z))) : <?>\n\955\928> Bye!\n"
withTempFile :: (String -> IO ()) -> IO ()
withTempFile =
diff --git a/lambda-calcul/haskell/test/Minilang/ServerSpec.hs b/lambda-calcul/haskell/test/Minilang/ServerSpec.hs
index 309ded8..6a25ec5 100644
--- a/lambda-calcul/haskell/test/Minilang/ServerSpec.hs
+++ b/lambda-calcul/haskell/test/Minilang/ServerSpec.hs
@@ -1,15 +1,31 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
module Minilang.ServerSpec where
+import Data.Aeson (eitherDecode, FromJSON)
+import Minilang.API (Score)
import Minilang.Server (serveAPI)
import Network.Wai (Application)
import Test.Hspec (Spec, it)
-import Test.Hspec.Wai (get, shouldRespondWith, with)
+import Test.Hspec.Wai (get, matchBody, shouldRespondWith, with)
+import Test.Hspec.Wai.Matcher (MatchBody (..))
+import Data.Data (Proxy (..))
spec :: Spec
spec = with app $
it "GET /api/leaderboard returns empty list of scores" $ do
get "/api/leaderboard"
- `shouldRespondWith` "[]"
+ `shouldRespondWith` 200 {matchBody = arrayOfLengthOf (Proxy @Score) 2}
+
+arrayOfLengthOf :: forall elem proxy . (FromJSON elem) => proxy elem -> Int -> MatchBody
+arrayOfLengthOf _ len = MatchBody $ \_ actual ->
+ case eitherDecode actual of
+ Right (scores :: [elem]) ->
+ if length scores == len
+ then Nothing
+ else Just $ "Expected array of length " ++ show len ++ ", but got " ++ show (length scores)
+ Left err -> Just $ "Failed to decode JSON: " ++ err
app :: IO Application
app = pure serveAPI