Skip to content

Commit 8a0a6d7

Browse files
authored
Merge pull request #385 from rbasso/hspec-zipper
zipper: Rewrite tests to use hspec with fail-fast.
2 parents f169b92 + 7d103e7 commit 8a0a6d7

File tree

3 files changed

+81
-87
lines changed

3 files changed

+81
-87
lines changed

exercises/zipper/package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ tests:
1616
source-dirs: test
1717
dependencies:
1818
- zipper
19-
- HUnit
19+
- hspec

exercises/zipper/src/Zipper.hs

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,44 @@
1-
module Zipper (
2-
BinTree(..),
3-
Zipper,
4-
5-
fromTree,
6-
toTree,
7-
8-
value,
9-
left,
10-
right,
11-
up,
12-
13-
setValue,
14-
setLeft,
15-
setRight
16-
) where
17-
18-
-- | A binary tree.
19-
data BinTree a = BT {
20-
btValue :: a -- ^ Value
21-
, btLeft :: Maybe (BinTree a) -- ^ Left child
22-
, btRight :: Maybe (BinTree a) -- ^ Right child
23-
} deriving (Eq, Show)
24-
25-
-- | A zipper for a binary tree.
26-
data Zipper a -- Complete this definition
27-
28-
-- | Get a zipper focussed on the root node.
1+
module Zipper
2+
( BinTree(BT)
3+
, fromTree
4+
, left
5+
, right
6+
, setLeft
7+
, setRight
8+
, setValue
9+
, toTree
10+
, up
11+
, value
12+
) where
13+
14+
data BinTree a = BT { btValue :: a
15+
, btLeft :: Maybe (BinTree a)
16+
, btRight :: Maybe (BinTree a)
17+
} deriving (Eq, Show)
18+
2919
fromTree :: BinTree a -> Zipper a
3020
fromTree = undefined
3121

32-
-- | Get the complete tree from a zipper.
3322
toTree :: Zipper a -> BinTree a
3423
toTree = undefined
3524

36-
-- | Get the value of the focus node.
3725
value :: Zipper a -> a
38-
value = undefined
26+
value = undefined
3927

40-
-- | Get the left child of the focus node, if any.
4128
left :: Zipper a -> Maybe (Zipper a)
4229
left = undefined
4330

44-
-- | Get the right child of the focus node, if any.
4531
right :: Zipper a -> Maybe (Zipper a)
4632
right = undefined
4733

48-
-- | Get the parent of the focus node, if any.
4934
up :: Zipper a -> Maybe (Zipper a)
5035
up = undefined
5136

52-
-- | Set the value of the focus node.
5337
setValue :: a -> Zipper a -> Zipper a
5438
setValue = undefined
5539

56-
-- | Replace a left child tree.
5740
setLeft :: Maybe (BinTree a) -> Zipper a -> Zipper a
58-
setLeft = undefined
41+
setLeft = undefined
5942

60-
-- | Replace a right child tree.
6143
setRight :: Maybe (BinTree a) -> Zipper a -> Zipper a
6244
setRight = undefined

exercises/zipper/test/Tests.hs

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,64 @@
1-
import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..))
2-
import System.Exit (ExitCode(..), exitWith)
3-
import Data.Maybe (fromJust)
1+
import Data.Maybe (fromJust)
2+
import Test.Hspec (Spec, describe, it, shouldBe)
3+
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
4+
45
import Zipper
6+
( BinTree(BT)
7+
, fromTree
8+
, left
9+
, right
10+
, setLeft
11+
, setRight
12+
, setValue
13+
, toTree
14+
, up
15+
, value
16+
)
517

6-
exitProperly :: IO Counts -> IO ()
7-
exitProperly m = do
8-
counts <- m
9-
exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess
18+
main :: IO ()
19+
main = hspecWith defaultConfig {configFastFail = True} specs
1020

11-
testCase :: String -> Assertion -> Test
12-
testCase label assertion = TestLabel label (TestCase assertion)
21+
specs :: Spec
22+
specs = describe "zipper" $ do
1323

14-
main :: IO ()
15-
main = exitProperly $ runTestTT $ TestList
16-
[ TestList zipperTests ]
17-
18-
empty :: Maybe (BinTree a)
19-
empty = Nothing
20-
21-
bt :: Int -> Maybe (BinTree Int) -> Maybe (BinTree Int) -> Maybe (BinTree Int)
22-
bt v l r = Just (BT v l r)
23-
24-
leaf :: Int -> Maybe (BinTree Int)
25-
leaf v = bt v Nothing Nothing
26-
27-
t1, t2, t3, t4 :: BinTree Int
28-
t1 = BT 1 (bt 2 empty (leaf 3)) (leaf 4)
29-
t2 = BT 1 (bt 5 empty (leaf 3)) (leaf 4)
30-
t3 = BT 1 (bt 2 (leaf 5) (leaf 3)) (leaf 4)
31-
t4 = BT 1 (leaf 2) (leaf 4)
32-
33-
zipperTests :: [Test]
34-
zipperTests =
35-
[ testCase "data is retained" $
36-
t1 @=? toTree (fromTree t1)
37-
, testCase "left, right and value" $
38-
3 @=? (value . fromJust . right . fromJust . left . fromTree $ t1)
39-
, testCase "dead end" $
40-
Nothing @=? (left . fromJust . left . fromTree $ t1)
41-
, testCase "tree from deep focus" $
42-
t1 @=? (toTree . fromJust . right . fromJust . left . fromTree $ t1)
43-
, testCase "setValue" $
44-
t2 @=? (toTree . setValue 5 . fromJust . left . fromTree $ t1)
45-
, testCase "setLeft with Just" $
46-
t3 @=? (toTree . setLeft (Just (BT 5 Nothing Nothing)) . fromJust . left . fromTree $ t1)
47-
, testCase "setRight with Nothing" $
48-
t4 @=? (toTree . setRight Nothing . fromJust . left . fromTree $ t1)
49-
, testCase "different paths to same zipper" $
50-
(right . fromTree $ t1) @=?
51-
(right . fromJust . up . fromJust . left . fromTree $ t1)
52-
]
24+
-- As of 2016-09-27, there was no reference file
25+
-- for the test cases in `exercism/x-common`.
26+
27+
let leaf v = node v Nothing Nothing
28+
node v l r = Just (BT v l r :: BinTree Int)
29+
t1 = BT 1 (node 2 Nothing $ leaf 3) $ leaf 4
30+
t2 = BT 1 (node 5 Nothing $ leaf 3) $ leaf 4
31+
t3 = BT 1 (node 2 (leaf 5) $ leaf 3) $ leaf 4
32+
t4 = BT 1 (leaf 2 ) $ leaf 4
33+
34+
it "data is retained" $
35+
toTree (fromTree t1)
36+
`shouldBe` t1
37+
38+
it "left, right and value" $
39+
(value . fromJust . right . fromJust . left . fromTree) t1
40+
`shouldBe` 3
41+
42+
it "dead end" $
43+
(left . fromJust . left . fromTree) t1
44+
`shouldBe` Nothing
45+
46+
it "tree from deep focus" $
47+
(toTree . fromJust . right . fromJust . left . fromTree) t1
48+
`shouldBe` t1
49+
50+
it "setValue" $
51+
(toTree . setValue 5 . fromJust . left . fromTree) t1
52+
`shouldBe` t2
53+
54+
it "setLeft with Just" $
55+
(toTree . setLeft (leaf 5) . fromJust . left . fromTree) t1
56+
`shouldBe` t3
57+
58+
it "setRight with Nothing" $
59+
(toTree . setRight Nothing . fromJust . left . fromTree) t1
60+
`shouldBe` t4
61+
62+
it "different paths to same zipper" $
63+
(right . fromJust . up . fromJust . left . fromTree) t1
64+
`shouldBe` (right . fromTree) t1

0 commit comments

Comments
 (0)