haskell-homework/test/Homework/Ch01/HanoiSpec.hs

109 lines
4.1 KiB
Haskell
Raw Normal View History

2021-10-01 00:04:16 +00:00
module Homework.Ch01.HanoiSpec where
import Homework.Ch01.Hanoi
import Test.Hspec
spec :: Spec
spec = describe "Hanoi" $ do
-- Testing the solver function
describe "hanoi" $ do
-- helper to construct a hanoi function with preconfigured labels
let hanoiOf = hanoi "a" "b" "c"
it "can solve for a stack of 1 disc" $ do
2021-10-07 14:06:19 +00:00
moves <- hanoiOf 1 -- a@[1] b@[] c@[]
moves
`shouldBe` [ Move "a" "c" -- a@[] b@[] c@[1]
]
it "can solve for a stack of 2 discs" $ do
2021-10-07 14:06:19 +00:00
moves <- hanoiOf 2 -- a@[2, 1] b@[] c@[]
moves
`shouldBe` [ Move "a" "c", -- a@[2] b@[] c@[1]
Move "a" "b", -- a@[] b@[2] c@[1]
Move "c" "a", -- a@[1] b@[2] c@[]
Move "a" "c", -- a@[1] b@[] c@[2]
Move "a" "c" -- a@[] b@[] c@[2, 1]
]
it "can solve for a stack of 3 discs" $ do
2021-10-07 14:06:19 +00:00
moves <- hanoiOf 3 -- a@[3, 2, 1] b@[] c@[]
moves
`shouldBe` [ Move "a" "c", -- a@[3, 2] b@[] c@[1]
Move "a" "b", -- a@[3] b@[2] c@[1]
Move "c" "b", -- a@[3] b@[2, 1] c@[]
Move "a" "c", -- a@[] b@[2, 1] c@[3]
Move "b" "a", -- a@[1] b@[2] c@[3]
Move "b" "c", -- a@[1] b@[] c@[3, 2]
Move "a" "c" -- a@[] b@[] c@[3, 2, 1]
]
2021-10-07 13:56:19 +00:00
{----------------------------------------------------------------------------}
{- MOVE ---------------------------------------------------------------------}
{----------------------------------------------------------------------------}
-- Testing individual moves
describe "move" $ do
it "moves the smallest peg from peg A to peg C if peg C's disc is bigger" $ do
let emptyPegs = initPegs "a" "b" "c" 0
pegs =
emptyPegs
{ pegsPegA = (emptyPeg "a") {pegDiscs = [Disc 3, Disc 1]},
pegsPegC = (emptyPeg "c") {pegDiscs = [Disc 2]}
}
2021-10-07 14:06:19 +00:00
-- run the function
(moveMade, pegsAfterMove) <- runPegs move pegs
-- a move should have been made
moveMade `shouldBe` Just (Move "a" "c")
-- the pegs should have changed
pegsAfterMove
`shouldBe` pegs
{ pegsPegA = (pegsPegA pegs) {pegDiscs = [Disc 3]},
2021-10-07 14:06:19 +00:00
pegsPegC = (pegsPegC pegs) {pegDiscs = [Disc 2, Disc 1]},
pegsMoves = [Move {moveFrom = "a", moveTo = "c"}]
}
2021-10-07 13:56:19 +00:00
{----------------------------------------------------------------------------}
{- PEGS ---------------------------------------------------------------------}
{----------------------------------------------------------------------------}
-- Testing constructor for a set of pegs
describe "initPegs" $ do
it "creates pegs with labels and fills the first peg with discs" $ do
initPegs "a" "b" "c" 3
`shouldBe` Pegs
{ pegsPegA = Peg {pegLabel = "a", pegDiscs = [Disc 3, Disc 2, Disc 1]},
pegsPegB = Peg {pegLabel = "b", pegDiscs = []},
2021-10-07 14:06:19 +00:00
pegsPegC = Peg {pegLabel = "c", pegDiscs = []},
pegsMoves = []
}
2021-10-07 13:56:19 +00:00
{----------------------------------------------------------------------------}
{- PEG ----------------------------------------------------------------------}
{----------------------------------------------------------------------------}
-- Testing constructor for a peg with discs
2021-10-06 20:39:05 +00:00
describe "fillPeg" $ do
it "creates a list of disks from biggest to smallest" $ do
2021-10-06 20:39:05 +00:00
fillPeg "a" 3
`shouldBe` Peg
{ pegLabel = "a",
pegDiscs = [Disc 3, Disc 2, Disc 1]
}
-- Testing constructor for a peg without discs
describe "emptyPeg" $ do
it "creates an empty peg" $ do
emptyPeg "a"
`shouldBe` Peg
{ pegLabel = "a",
pegDiscs = []
2021-10-06 20:39:05 +00:00
}
-- Testing constructor for a stack of discs
describe "stackDiscs" $ do
it "should create a stack of discs from largest to smallest" $ do
stackDiscs 3 `shouldBe` [Disc 3, Disc 2, Disc 1]