-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHongTest.hs
More file actions
70 lines (59 loc) · 2.71 KB
/
Copy pathHongTest.hs
File metadata and controls
70 lines (59 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
-- | This module tests the Hong game, all tests are pure (no side effects).
-- The reason why the tests take some seconds to run is simply that
-- we must have a high sampling rate in order to ensure to logic is
-- correct, and thus we also must look at many samples which takes time.
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
module HongTest (specs) where
import Test.Hspec
import Test.Hspec.HUnit ()
import Fal
import GameState
import UserControl
import HongConstants
run :: State -> [State]
run s0 = runBehavior (pong' s0 uc) (repeat Nothing, [0, 0.002..])
ever, never :: (State -> Bool) -> [State] -> Bool
ever f ss = any f $ take 20000 ss
never f = not . ever f
outside :: State -> Bool
outside s = abs (xPosition s) > (planeHalfWidth + epsilon)
|| abs (yPosition s) > (planeHalfHeight + epsilon)
alwaysInside :: [State] -> Bool
alwaysInside = never outside
specs :: Spec
specs = describe "Hong" $ do
it "tests the test framework" True
describe "bounces on walls" $ do
let ss = run startState{ xVelocity = 0 }
it "always have ball inside" $ alwaysInside ss
it "bounces roof" $ ever (\s -> yVelocity s < 0) ss
it "bounces floor" $
ever (\s -> yPosition s < 0 && yVelocity s > 0) ss
describe "bounces on paddles" $ do
let ss = run startState{ yVelocity = 0 }
it "keeps bouncing" $ alwaysInside ss
it "bounces on right paddle" $ ever (\s -> xVelocity s < 0) ss
it "bounces on left paddle" $
ever (\s -> xPosition s < 0 && xVelocity s > 0) ss
describe "avoids bounces when paddle not present" $ do
let s0 = startState { yVelocity = 0
, leftPaddle = 1000
, rightPaddle = (-1000) }
let ss = run s0{ xVelocity = 1 }
in it "no bounce on right paddle" $
ever (\s -> xPosition s > 2*planeHalfWidth) ss
let ss = run s0{ xVelocity = (-1) }
in it "no bounce on left paddle" $
ever (\s -> xPosition s < (-2)*planeHalfWidth) ss
describe "paddles move correctly" $ do
let ts = [0.01..]
ucl = lift1 (signum . (10-)) time
ucr = lift1 (negate . signum . (10-)) time
uc = lift2 UserControl ucl ucr
ss = runBehavior (pong' startState uc) (repeat Nothing, ts)
maxHeight = highestPaddlePoint + epsilon
it "can move left paddle" $ ever (\s -> leftPaddle s > planeHalfHeight/2) ss
it "can move right paddle" $ ever (\s -> rightPaddle s > planeHalfHeight/2) ss
it "has bounded left paddle" $ never (\s -> abs (leftPaddle s) > maxHeight) ss
it "has bounded right paddle" $ never (\s -> abs (rightPaddle s) > maxHeight) ss