SharedSpecs.hs 1.72 KB
Newer Older
1 2 3
{-# LANGUAGE OverloadedStrings #-}
module SharedSpecs where

4
import Prelude hiding (succ,pred)
5

6 7 8 9 10 11 12 13 14 15
import Control.Monad.State

import Data.Error
import Data.Text (Text)
import Data.Label

import PCF
import Test.Hspec

sharedSpec :: (Show v, Eq v) => ([(Text,v)] -> State Label Expr -> Error String v) -> (Int -> v)-> Spec
16 17
sharedSpec eval fromInt = describe "shared language behavior" $ do
  it "should look up a bound variable" $
Sven Keidel's avatar
Sven Keidel committed
18
    eval [("x",fromInt 5)] "x" `shouldBe` Success (fromInt 5)
19 20

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

  it "should apply a function" $
24
    eval [] (app (lam "x" (succ "x")) zero) `shouldBe` Success (fromInt 1)
25 26

  it "should fail when applying something other than a function" $
27
    eval [] (app zero zero) `shouldBe` Error "Expected a closure"
28 29

  it "should compute 0 + 1 + 1 = 2" $
30
    eval [] (succ (succ zero)) `shouldBe` Success (fromInt 2)
31 32

  it "should fail when using succ on something other than a number" $
33
    eval [] (succ (lam "x" zero)) `shouldBe` Error "Expected a number as argument for 'succ'"
34 35

  it "should fail when using pred on something other than a number" $
36
    eval [] (pred (lam "x" zero)) `shouldBe` Error "Expected a number as argument for 'pred'"
37 38

  it "should execute the then branch on IfZero on zero" $
39
    eval [] (ifZero zero (succ zero) zero)
40 41 42
      `shouldBe` Success (fromInt 1)

  it "should execute the else branch on IfZero on completely non-zero" $
43
    eval [] (ifZero (succ zero) (succ zero) zero)
44 45 46
      `shouldBe` Success (fromInt 0)

  it "should fail when using a non-number condition for IfZero" $
47
    eval [] (ifZero (lam "x" zero) zero zero) `shouldBe` Error "Expected a number as condition for 'ifZero'"