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

4
import Prelude hiding (succ,pred)
5

6 7 8 9
import Control.Monad.State

import Data.Label

Sven Keidel's avatar
Sven Keidel committed
10
import Syntax
11 12
import Test.Hspec

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

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

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

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

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

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

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

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

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

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