Skip to content

robot-simulator: Rewrite tests to use hspec with fail-fast. #251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exercises/robot-simulator/package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ tests:
source-dirs: test
dependencies:
- robot-simulator
- HUnit
- hspec
1 change: 0 additions & 1 deletion exercises/robot-simulator/src/Example.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module Robot (Bearing(..),
Robot,
mkRobot,
coordinates,
bearing,
Expand Down
7 changes: 3 additions & 4 deletions exercises/robot-simulator/src/Robot.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Robot
( Bearing (..)
, Robot
( Bearing(East,North,South,West)
, bearing
, coordinates
, mkRobot
Expand All @@ -15,8 +14,8 @@ data Bearing = North
| West
deriving (Eq, Show)

-- The task is to create the data type `Robot`, with `Eq`
-- and `Show` instances, and implement the functions below.
-- The task is to create the data type `Robot`
-- and implement the functions below.

bearing :: Robot -> Bearing
bearing = undefined
Expand Down
145 changes: 101 additions & 44 deletions exercises/robot-simulator/test/Tests.hs
Original file line number Diff line number Diff line change
@@ -1,48 +1,105 @@
import Test.HUnit (Assertion, (@=?), runTestTT, Test(..), Counts(..))
import System.Exit (ExitCode(..), exitWith)
import Robot (Bearing(..), Robot, mkRobot,
coordinates, simulate,
bearing, turnRight, turnLeft)
{-# OPTIONS_GHC -fno-warn-type-defaults #-}

exitProperly :: IO Counts -> IO ()
exitProperly m = do
counts <- m
exitWith $ if failures counts /= 0 || errors counts /= 0 then ExitFailure 1 else ExitSuccess
import Test.Hspec (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

testCase :: String -> Assertion -> Test
testCase label assertion = TestLabel label (TestCase assertion)
import Robot
( Bearing ( East
, North
, South
, West
)
, bearing
, coordinates
, mkRobot
, simulate
, turnLeft
, turnRight
)

main :: IO ()
main = exitProperly $ runTestTT $ TestList
[ TestList robotTests ]

robotTests :: [Test]
robotTests =
[ testCase "turning cases" $ do
West @=? turnLeft North
South @=? turnLeft West
East @=? turnLeft South
North @=? turnLeft East
East @=? turnRight North
South @=? turnRight East
West @=? turnRight South
North @=? turnRight West
, testCase "robbie" $ do
let robbie :: Robot
robbie = mkRobot East (-2, 1)
East @=? bearing robbie
(-2, 1) @=? coordinates robbie
let movedRobbie = simulate robbie "RLAALAL"
West @=? bearing movedRobbie
(0, 2) @=? coordinates movedRobbie
mkRobot West (0, 2) @=? movedRobbie
, testCase "clutz" $ do
let clutz = mkRobot North (0, 0)
mkRobot West (-4, 1) @=? simulate clutz "LAAARALA"
, testCase "sphero" $ do
let sphero = mkRobot East (2, -7)
mkRobot South (-3, -8) @=? simulate sphero "RRAAAAALA"
, testCase "roomba" $ do
let roomba = mkRobot South (8, 4)
mkRobot North (11, 5) @=? simulate roomba "LAAARRRALLLL"
]
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = describe "robot-simulator" $ do

-- Test cases adapted from `exercism/x-common/robot-simulator.json`
-- on 2016-08-02. Some deviations exist and are noted in comments.

describe "mkRobot" $ do

-- The function described by the reference file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why we gave it a name...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

guess it's always been that way (assume we ported from clojure) exercism/exercism@33216cf

-- as `create` is called `mkRobot` in this track.

it "A robot is created with a position and a direction" $ do
let robot = mkRobot North (0, 0)
coordinates robot `shouldBe` (0, 0)
bearing robot `shouldBe` North

it "Negative positions are allowed" $ do
let robot = mkRobot South (-1, -1)
coordinates robot `shouldBe` (-1, -1)
bearing robot `shouldBe` South

-- The reference tests for `turnLeft` and `turnRight` describe
-- functions that are applied to robots positioned at (0, 0).
-- In this track, they are functions over directions, so those
-- test cases cannot be completely implemented.

describe "turnRight" $ do

it "turn from North" $ turnRight North `shouldBe` East
it "turn from East" $ turnRight East `shouldBe` South
it "turn from South" $ turnRight South `shouldBe` West
it "turn from West" $ turnRight West `shouldBe` North

describe "turnLeft" $ do

it "turn from North" $ turnLeft North `shouldBe` West
it "turn from West" $ turnLeft West `shouldBe` South
it "turn from South" $ turnLeft South `shouldBe` East
it "turn from East" $ turnLeft East `shouldBe` North

describe "simulate advance" $ do

-- The function described by the reference file as `advance`
-- doesn't exist in this track, so we test `simulate` with "A".

let dir `from` pos = simulate (mkRobot dir pos) "A"

it "does not change the direction" $
bearing (North `from` (0, 0)) `shouldBe` North

it "increases the y coordinate one when facing north" $
coordinates (North `from` (0, 0)) `shouldBe` (0, 1)

it "decreases the y coordinate by one when facing south" $
coordinates (South `from` (0, 0)) `shouldBe` (0, -1)

it "increases the x coordinate by one when facing east" $
coordinates (East `from` (0, 0)) `shouldBe` (1, 0)

it "decreases the x coordinate by one when facing west" $
coordinates (West `from` (0, 0)) `shouldBe `(-1, 0)

describe "simulate" $ do

-- The function described by the reference file as
-- `instructions` is called `simulate` in this track.

let simulation pos dir = simulate (mkRobot dir pos)

it "instructions to move west and north" $ do
let robot = simulation (0, 0) North "LAAARALA"
coordinates robot `shouldBe` (-4, 1)
bearing robot `shouldBe` West

it "instructions to move west and south" $ do
let robot = simulation (2, -7) East "RRAAAAALA"
coordinates robot `shouldBe` (-3, -8)
bearing robot `shouldBe` South

it "instructions to move east and north" $ do
let robot = simulation (8, 4) South "LAAARRRALLLL"
coordinates robot `shouldBe` (11, 5)
bearing robot `shouldBe` North