SharedSpecs.hs 1.76 KB
Newer Older
1 2 3 4 5 6 7 8 9
{-# LANGUAGE OverloadedStrings #-}
module SharedSpecs where

import           Data.Error
import           Data.Text (Text)
import           PCF (Expr)
import qualified PCF as E
import           Test.Hspec

Sven Keidel's avatar
Sven Keidel committed
10
sharedSpec :: (Show v, Eq v) => ([(Text,v)] -> Expr -> Error String v) -> (Int -> v)-> Spec
11 12
sharedSpec eval fromInt = describe "shared language behavior" $ do
  it "should look up a bound variable" $
Sven Keidel's avatar
Sven Keidel committed
13
    eval [("x",fromInt 5)] "x" `shouldBe` Success (fromInt 5)
14 15

  it "should fail when looking up an unbound variable" $
Sven Keidel's avatar
Sven Keidel committed
16
    eval [] "x" `shouldBe` Error "Variable \"x\" not bound"
17 18

  it "should apply a function" $
Sven Keidel's avatar
Sven Keidel committed
19
    eval [] (E.App (E.Lam "x" (E.Succ "x")) E.Zero) `shouldBe` Success (fromInt 1)
20 21

  it "should fail when applying something other than a function" $
Sven Keidel's avatar
Sven Keidel committed
22
    eval [] (E.App E.Zero E.Zero) `shouldBe` Error "Expected a closure"
23 24

  it "should compute 0 + 1 + 1 = 2" $
Sven Keidel's avatar
Sven Keidel committed
25
    eval [] (E.Succ (E.Succ E.Zero)) `shouldBe` Success (fromInt 2)
26 27

  it "should fail when using succ on something other than a number" $
Sven Keidel's avatar
Sven Keidel committed
28
    eval [] (E.Succ (E.Lam "x" E.Zero)) `shouldBe` Error "Expected a number as argument for 'succ'"
29 30

  it "should fail when using pred on something other than a number" $
Sven Keidel's avatar
Sven Keidel committed
31
    eval [] (E.Pred (E.Lam "x" E.Zero)) `shouldBe` Error "Expected a number as argument for 'pred'"
32 33

  it "should execute the then branch on IfZero on zero" $
Sven Keidel's avatar
Sven Keidel committed
34
    eval [] (E.IfZero E.Zero (E.Succ E.Zero) E.Zero)
35 36 37
      `shouldBe` Success (fromInt 1)

  it "should execute the else branch on IfZero on completely non-zero" $
Sven Keidel's avatar
Sven Keidel committed
38
    eval [] (E.IfZero (E.Succ E.Zero) (E.Succ E.Zero) E.Zero)
39 40 41
      `shouldBe` Success (fromInt 0)

  it "should fail when using a non-number condition for IfZero" $
Sven Keidel's avatar
Sven Keidel committed
42
    eval [] (E.IfZero (E.Lam "x" E.Zero) E.Zero E.Zero) `shouldBe` Error "Expected a number as condition for 'ifZero'"