-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSet11bTest.hs
139 lines (118 loc) · 5.06 KB
/
Set11bTest.hs
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}
module Set11aTest where
import Mooc.Test
import Mooc.Th
import Control.Monad
import Data.List
import Data.IORef
import GHC.IO.Handle
import System.Directory
import System.IO
import Test.QuickCheck
import Test.QuickCheck.Monadic
import Set11b hiding (counter)
main = score tests
tests = [(1,"appendAll",[ex1])
,(2,"swapIORefs",[ex2])
,(3,"doubleCall",[ex3_doubleCall, ex3_doubleCall_2])
,(4,"composeIO",[ex4_composeIO_1, ex4_composeIO_2])
,(5,"hFetchLines",[ex5])
,(6,"hSelectLines",[ex6_hSelectLines])
,(7,"interact'",[ex7_interact_terminates, ex7_interact_example, ex7_interact_loop])]
-- -- -- -- --
word = listOf1 (choose ('a','z'))
ex1 = forAllBlind word $ \init ->
forAllBlind (listOf word) $ \ws ->
counterexample ("appendAll ref " ++ show ws) $
counterexample (" Initial value of ref was: " ++ show init) $
monadicIO $ do ref <- run $ newIORef init
run $ appendAll ref ws
out <- run $ readIORef ref
stop_ $ counterexample " Final value in ref" $ out ?== concat (init:ws)
ex2 = forAllBlind word $ \w1 ->
forAllBlind word $ \w2 ->
counterexample "swapIORefs r1 r2" $
counterexample (" Initial value of r1: "++show w1) $
counterexample (" Initial value of r2: "++show w2) $
monadicIO $ do r1 <- run $ newIORef w1
r2 <- run $ newIORef w2
run $ swapIORefs r1 r2
o1 <- run $ readIORef r1
o2 <- run $ readIORef r2
stop_ $ conjoin [counterexample " readIORef r1" $ o1 ?== w2
,counterexample " readIORef r2" $ o2 ?== w1]
ex3_doubleCall =
forAllBlind (choose (0,20::Int)) $ \i ->
counterexample ("doubleCall (return (return "++show i++"))") $
($ doubleCall (return (return i))) . withNoInput $
check (?=="") (?==i)
ex3_doubleCall_2 =
forAllBlind word $ \w1 ->
forAllBlind word $ \w2 ->
counterexample ("doubleCall (do putStrLn "++show w1++"; return (putStrLn "++show w2++"))") $
($ doubleCall (do putStrLn w1; return (putStrLn w2))) . withNoInput $
check (?==(w1++"\n"++w2++"\n")) (?==())
ex4_composeIO_1 =
forAllBlind word $ \w ->
forAllBlind word $ \v ->
counterexample ("compose putStrLn (\\x -> do putStrLn x; getLine) " ++ show w) $
($ compose putStrLn (\x -> do putStrLn x; getLine) w) . withInput (v++"\n") $
checkOutput (?==w++"\n"++v++"\n")
ex4_composeIO_2 =
forAll_ $ \(i::Int) ->
counterexample ("compose (\\x -> return (x*2)) (\\y -> return (y+1)) " ++ show i) $
($ compose (return . (*2)) (return . (+1)) i) . withNoInput $
checkResult (?== (i+1)*2)
ex5 = forAllBlind (listOf1 word) $ \lines ->
counterexample ("Contents of handle h:\n"++unlines lines) $
counterexample "hFetchLines h" $
monadicIO $ do
dir <- run $ getTemporaryDirectory
(_,h) <- run $ openTempFile dir "hSelectLines.in"
run $ hPutStr h $ unlines lines
run $ hSeek h AbsoluteSeek 0
outs <- run $ hFetchLines h
length outs `seq` do
run $ hClose h
stop_ $ outs ?== lines
ex6_hSelectLines =
forAllBlind (listOf1 word) $ \lines ->
forAllBlind (fmap (nub.sort) . listOf1 $ choose (1,length lines)) $ \inds ->
counterexample ("Contents of handle h:\n"++unlines lines) $
counterexample ("hSelectLines h "++show inds) $
monadicIO $ do
dir <- run $ getTemporaryDirectory
(path,h) <- run $ openTempFile dir "hSelectLines.in"
run $ hPutStr h $ unlines lines
run $ hSeek h AbsoluteSeek 0
outs <- run $ hSelectLines h inds
length (concat outs) `seq` do
run $ hClose h
stop_ $ counterexample (" was: "++show outs) $
conjoin [counterexample "Length of result" $ length outs ?== length inds
,conjoin [counterexample ("result!!"++show i) $ outs!!i ?== lines!!((inds!!i)-1)
| i <- [0..length inds-1]]]
counter :: (String,Integer) -> (Bool,String,Integer)
counter ("inc",n) = (True,"done",n+1)
counter ("print",n) = (True,show n,n)
counter ("quit",n) = (False,"bye bye",n)
ex7_interact_terminates =
forAllBlind word $ \w1 ->
forAllBlind word $ \w2 ->
forAllBlind (choose (0::Int,100)) $ \state ->
counterexample ("let f (input,state) = (False,input,state) in interact' f "++show state) $
($ let f (input,state) = (False,input,state) in interact' f state) . withInput (unlines [w1,w2]) $
check (?==(w1++"\n")) (?==state)
ex7_interact_example =
$(testing' [|interact' counter 1|]) . withInput (unlines ["print","inc","inc","print","quit"]) $
check (?==unlines ["1","done","done","3","bye bye"]) (?==3)
ex7_interact_loop =
forAllBlind (choose (0::Int,100)) $ \state ->
forAllBlind (choose (0::Int,5)) $ \steps ->
forAllBlind word $ \w ->
forAllBlind (word `suchThat` (/=w)) $ \end ->
let input = unlines $ replicate steps w ++ [end]
output = unlines $ map show [state..state+steps]
in counterexample ("let f (input,state) = (input=="++show w++",show state,state+1) in interact' f "++show state) $
($ let f (input,state) = (input==w,show state,state+1) in interact' f state) . withInput input $
check (?==output) (?==state+steps+1)