SharedSpecs.hs 1.68 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
import Control.Monad.State

import Data.Text (Text)
import Data.Label

import PCF
import Test.Hspec

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

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

  it "should apply a function" $
Sven Keidel's avatar
Sven Keidel committed
23
    eval [] (app (lam "x" (succ "x")) zero) `shouldBe` Right (fromInt 1)
24 25

  it "should fail when applying something other than a function" $
Sven Keidel's avatar
Sven Keidel committed
26
    eval [] (app zero zero) `shouldBe` Left "Expected a closure"
27 28

  it "should compute 0 + 1 + 1 = 2" $
Sven Keidel's avatar
Sven Keidel committed
29
    eval [] (succ (succ zero)) `shouldBe` Right (fromInt 2)
30 31

  it "should fail when using succ on something other than a number" $
Sven Keidel's avatar
Sven Keidel committed
32
    eval [] (succ (lam "x" zero)) `shouldBe` Left "Expected a number as argument for 'succ'"
33 34

  it "should fail when using pred on something other than a number" $
Sven Keidel's avatar
Sven Keidel committed
35
    eval [] (pred (lam "x" zero)) `shouldBe` Left "Expected a number as argument for 'pred'"
36 37

  it "should execute the then branch on IfZero on zero" $
38
    eval [] (ifZero zero (succ zero) zero)
Sven Keidel's avatar
Sven Keidel committed
39
      `shouldBe` Right (fromInt 1)
40 41

  it "should execute the else branch on IfZero on completely non-zero" $
42
    eval [] (ifZero (succ zero) (succ zero) zero)
Sven Keidel's avatar
Sven Keidel committed
43
      `shouldBe` Right (fromInt 0)
44 45

  it "should fail when using a non-number condition for IfZero" $
Sven Keidel's avatar
Sven Keidel committed
46
    eval [] (ifZero (lam "x" zero) zero zero) `shouldBe` Left "Expected a number as condition for 'ifZero'"