1 -- !!! Testing the Prelude's Enum instances.
2 module Main(main) where
10 putStrLn "Testing Enum Int: "
13 putStrLn "Testing Enum Integer: "
16 putStrLn "Testing Enum Char: "
19 putStrLn "Testing Enum (): "
22 putStrLn "Testing Enum Ordering (derived): "
25 putStrLn "Testing Enum Bool: "
28 putStrLn "Testing Enum Rational: "
31 putStrLn "Testing Enum (Ratio Int): "
35 Here's the properties that's supposed to
36 hold for arithmetic sequences over Int:
38 - [e1..] = [e1, (e1+1), (e1+2), ..., maxBound]
40 - [e1,e2..] = [e1, (e1+i), (e1+2*i), ... upper]
46 | i == 0 = maxBound -- this really shouldn't matter (I feel.)
47 - [e1..e3] = [e1, (e1+i), (e1+2*i),..e3]
58 | i >= 0 && e3 < e1 = []
59 | i < 0 && e3 >= e1 = [] -- (*)
60 | otherwise = [e1, (e1+i), (e1 + 2*i), .. e3]
63 (*) - I think this instead should be (i < 0 && e3 > e1), since, as is,
68 which does not look right, symmetrically speaking.
71 The same properties hold for other Prelude types that
72 are instances of Enum as well as being Bounded.
74 For non-Bounded types (e.g., Float and Double), the properties are similar,
75 except that the boundary tests become slightly different, i.e., when an
76 element becomes greater than (e3 + i/2) (or less than (e3 + i/2) for negative
79 Q - does [(x::Double)..] have an upper bound? (ditto for Float.)
81 OK - on with the regression testing.
84 #define printTest(x) (do{ putStr ( " " ++ "x" ++ " = " ) ; print (x) })
90 printTest ((succ (0::Int)))
91 printTest ((succ (minBound::Int)))
92 mayBomb (printTest ((succ (maxBound::Int))))
95 printTest (pred (1::Int))
96 printTest (pred (maxBound::Int))
97 mayBomb (printTest (pred (minBound::Int)))
100 printTest ((map (toEnum::Int->Int) [1,minBound,maxBound]))
103 printTest ((map fromEnum [(1::Int),minBound,maxBound]))
105 -- [x..] aka enumFrom
106 printTest ((take 7 [(1::Int)..]))
107 printTest ((take 7 [((maxBound::Int)-5)..])) -- just in case it doesn't catch the upper bound..
109 -- [x,y..] aka enumFromThen
110 printTest ((take 7 [(1::Int),2..]))
111 printTest ((take 7 [(1::Int),7..]))
112 printTest ((take 7 [(1::Int),1..]))
113 printTest ((take 7 [(1::Int),0..]))
114 printTest ((take 7 [(5::Int),2..]))
115 let x = (minBound::Int) + 1
116 printTest ((take 7 [x, x-1 ..]))
117 let x = (minBound::Int) + 5
118 printTest ((take 7 [x, x-1 ..]))
119 let x = (maxBound::Int) - 5
120 printTest ((take 7 [x, (x+1) ..]))
122 -- [x..y] aka enumFromTo
123 printTest ((take 7 ([(1::Int) .. 5])))
124 printTest ((take 4 ([(1::Int) .. 1])))
125 printTest ((take 7 ([(1::Int) .. 0])))
126 printTest ((take 7 ([(5::Int) .. 0])))
127 printTest ((take 7 ([(maxBound-(5::Int)) .. maxBound])))
128 printTest ((take 7 ([(minBound+(5::Int)) .. minBound])))
130 -- [x,y..z] aka enumFromThenTo
131 printTest ((take 7 [(5::Int),4..1]))
132 printTest ((take 7 [(5::Int),3..1]))
133 printTest ((take 7 [(5::Int),3..2]))
134 printTest ((take 7 [(1::Int),2..1]))
135 printTest ((take 7 [(2::Int),1..2]))
136 printTest ((take 7 [(2::Int),1..1]))
137 printTest ((take 7 [(2::Int),3..1]))
139 let x = (maxBound::Int) - 4
140 printTest ((take 7 [x,(x+1)..maxBound]))
141 let x = (minBound::Int) + 5
142 printTest ((take 7 [x,(x-1)..minBound]))
144 testEnumChar :: IO ()
147 printTest ((succ 'a'))
148 printTest ((succ (minBound::Char)))
149 mayBomb (printTest ((succ (maxBound::Char))))
152 printTest ((pred 'b'))
153 printTest (pred (maxBound::Char))
154 mayBomb (printTest (pred (minBound::Char)))
157 printTest ((map (toEnum::Int->Char) [123,ord (minBound::Char), ord(maxBound::Char)]))
158 mayBomb (printTest ((toEnum::Int->Char) (minBound::Int)))
161 printTest ((map fromEnum ['X',minBound,maxBound]))
163 -- [x..] aka enumFrom
164 printTest ((take 7 ['\NUL' .. ]))
165 printTest ((take 7 ['\250' .. ]))
167 -- [x,y..] aka enumFromThen
168 printTest ((take 7 ['a','b'..]))
169 printTest ((take 7 ['a','e'..]))
170 printTest ((take 7 ['a','a'..]))
171 printTest ((take 7 ['z','y'..]))
172 printTest ((take 7 ['z','v'..]))
174 printTest ((take 7 ['\1', '\0' ..]))
176 printTest ((take 7 ['\5', '\4' ..]))
177 let x = (maxBound::Int) - 5
178 printTest ((take 7 ['\250', '\251' ..]))
180 -- [x..y] aka enumFromTo
181 printTest ((take 7 (['a' .. 'e'])))
182 printTest ((take 4 (['a' .. 'a'])))
183 printTest ((take 7 (['b' .. 'a'])))
184 printTest ((take 7 (['e' .. 'a'])))
185 printTest ((take 7 (['\250' .. '\255'])))
186 printTest ((take 7 (['\5' .. '\0'])))
188 -- [x,y..z] aka enumFromThenTo
189 printTest ((take 7 ['f','e' .. 'b']))
190 printTest ((take 7 ['g','e' .. 'b']))
191 printTest ((take 7 ['g','d' .. 'c']))
192 printTest ((take 7 ['b','c' .. 'b']))
193 printTest ((take 7 ['c','b' .. 'c']))
194 printTest ((take 7 ['c','b' .. 'b']))
195 printTest ((take 7 ['c','d' .. 'b']))
196 printTest ((take 7 ['\251', '\252' .. maxBound]))
197 printTest ((take 7 ['\5', '\4' .. minBound]))
200 testEnumUnit :: IO ()
203 mayBomb (printTest ((succ ())))
204 mayBomb (printTest ((succ (minBound::()))))
205 mayBomb (printTest ((succ (maxBound::()))))
208 mayBomb (printTest ((pred ())))
209 mayBomb (printTest ((pred (minBound::()))))
210 mayBomb (printTest ((pred (maxBound::()))))
213 printTest ((toEnum 0)::())
214 mayBomb (printTest ((toEnum 1)::()))
217 printTest ((fromEnum ()))
223 printTest (([(),()..]))
226 printTest (([()..()]))
229 printTest (([(),()..()]))
231 testEnumOrdering :: IO ()
232 testEnumOrdering = do
234 printTest ((succ LT))
235 printTest ((succ (minBound::Ordering)))
236 mayBomb (printTest ((succ (maxBound::Ordering))))
239 printTest ((pred GT))
240 printTest ((pred (maxBound::Ordering)))
241 mayBomb (printTest ((pred (minBound::Ordering))))
244 printTest ((toEnum 0)::Ordering)
245 mayBomb (printTest ((toEnum 5)::Ordering))
248 printTest ((fromEnum LT))
249 printTest ((fromEnum EQ))
250 printTest ((fromEnum GT))
253 printTest (([LT ..]))
254 printTest (([EQ ..]))
255 printTest (([GT ..]))
258 printTest (([LT,EQ ..]))
259 printTest (([EQ,GT ..]))
260 printTest (([EQ,LT ..]))
261 printTest (([LT,GT ..]))
262 printTest (([GT,LT ..]))
263 printTest (take 7 (([GT,GT ..])))
264 printTest (take 7 (([LT,LT ..])))
267 printTest (([LT .. GT]))
268 printTest (([LT .. EQ]))
269 printTest (([LT .. LT]))
270 printTest (([GT .. LT]))
271 printTest (([GT .. EQ]))
272 printTest (([GT .. GT]))
275 printTest (([LT,EQ .. GT]))
276 printTest (([GT,EQ .. LT]))
277 printTest (([GT,EQ .. EQ]))
278 printTest (([GT,EQ .. GT]))
279 printTest (([GT,EQ .. LT]))
280 printTest (([LT,EQ .. LT]))
281 printTest (([LT,EQ .. GT]))
282 printTest (take 7 (([LT,LT .. GT])))
283 printTest (take 7 (([GT,GT .. LT])))
285 testEnumBool :: IO ()
288 printTest ((succ False))
289 printTest ((succ (minBound::Bool)))
290 mayBomb (printTest ((succ (maxBound::Bool))))
293 printTest ((pred True))
294 printTest ((pred (maxBound::Bool)))
295 mayBomb (printTest ((pred (minBound::Bool))))
298 printTest ((toEnum 0)::Bool)
299 mayBomb (printTest ((toEnum 5)::Bool))
302 printTest ((fromEnum False))
303 printTest ((fromEnum True))
306 printTest (([False ..]))
307 printTest (([True ..]))
310 printTest (([False,True ..]))
311 printTest (([True,False ..]))
312 printTest ((take 7 ([False,False ..])))
313 printTest ((take 7 ([True,True ..])))
316 printTest (([False .. True]))
317 printTest (([True .. False]))
320 printTest (take 7 ([False,False .. False]))
321 printTest (take 7 ([False,False .. True]))
322 printTest (take 7 ([False,True .. False]))
323 printTest (take 7 ([False,True .. True]))
324 printTest (take 7 ([True,False .. False]))
325 printTest (take 7 ([True,False .. True]))
326 printTest (take 7 ([True,True .. False]))
327 printTest (take 7 ([True,True .. True]))
330 testEnumInteger :: IO ()
333 printTest ((succ (0::Integer)))
334 printTest ((succ ((-1)::Integer)))
337 printTest (pred (1::Integer))
338 printTest (pred (0::Integer))
341 printTest ((map (toEnum::Int->Integer) [1,minBound,maxBound]))
344 printTest ((map fromEnum [(1::Integer),42,45]))
346 -- [x..] aka enumFrom
347 printTest ((take 7 [(1::Integer)..]))
348 printTest ((take 7 [(-5::Integer)..]))
350 -- [x,y..] aka enumFromThen
351 printTest ((take 7 [(1::Integer),2..]))
352 printTest ((take 7 [(1::Integer),7..]))
353 printTest ((take 7 [(1::Integer),1..]))
354 printTest ((take 7 [(1::Integer),0..]))
355 printTest ((take 7 [(5::Integer),2..]))
357 -- [x..y] aka enumFromTo
358 printTest ((take 7 ([(1::Integer) .. 5])))
359 printTest ((take 4 ([(1::Integer) .. 1])))
360 printTest ((take 7 ([(1::Integer) .. 0])))
361 printTest ((take 7 ([(5::Integer) .. 0])))
363 -- [x,y..z] aka enumFromThenTo
364 printTest ((take 7 [(5::Integer),4..1]))
365 printTest ((take 7 [(5::Integer),3..1]))
366 printTest ((take 7 [(5::Integer),3..2]))
367 printTest ((take 7 [(1::Integer),2..1]))
368 printTest ((take 7 [(2::Integer),1..2]))
369 printTest ((take 7 [(2::Integer),1..1]))
370 printTest ((take 7 [(2::Integer),3..1]))
372 testEnumRational :: IO ()
373 testEnumRational = do
375 printTest ((succ (0::Rational)))
376 printTest ((succ ((-1)::Rational)))
379 printTest (pred (1::Rational))
380 printTest (pred (0::Rational))
383 printTest ((map (toEnum::Int->Rational) [1,minBound,maxBound]))
386 printTest ((map fromEnum [(1::Rational),42,45]))
388 -- [x..] aka enumFrom
389 printTest ((take 7 [(1::Rational)..]))
390 printTest ((take 7 [(-5::Rational)..]))
392 -- [x,y..] aka enumFromThen
393 printTest ((take 7 [(1::Rational),2..]))
394 printTest ((take 7 [(1::Rational),7..]))
395 printTest ((take 7 [(1::Rational),1..]))
396 printTest ((take 7 [(1::Rational),0..]))
397 printTest ((take 7 [(5::Rational),2..]))
399 -- [x..y] aka enumFromTo
400 printTest ((take 7 ([(1::Rational) .. 5])))
401 printTest ((take 4 ([(1::Rational) .. 1])))
402 printTest ((take 7 ([(1::Rational) .. 0])))
403 printTest ((take 7 ([(5::Rational) .. 0])))
405 -- [x,y..z] aka enumFromThenTo
406 printTest ((take 7 [(5::Rational),4..1]))
407 printTest ((take 7 [(5::Rational),3..1]))
408 printTest ((take 7 [(5::Rational),3..2]))
409 printTest ((take 7 [(1::Rational),2..1]))
410 printTest ((take 7 [(2::Rational),1..2]))
411 printTest ((take 7 [(2::Rational),1..1]))
412 printTest ((take 7 [(2::Rational),3..1]))
414 testEnumRatioInt :: IO ()
415 testEnumRatioInt = do
417 printTest ((succ (0::Ratio Int)))
418 printTest ((succ ((-1)::Ratio Int)))
421 printTest (pred (1::Ratio Int))
422 printTest (pred (0::Ratio Int))
425 printTest ((map (toEnum::Int->Ratio Int) [1,minBound,maxBound]))
428 printTest ((map fromEnum [(1::Ratio Int),42,45]))
430 -- [x..] aka enumFrom
431 printTest ((take 7 [(1::Ratio Int)..]))
432 printTest ((take 7 [(-5::Ratio Int)..]))
433 printTest ((take 7 [((toEnum ((maxBound::Int)-5))::Ratio Int)..]))
435 -- [x,y..] aka enumFromThen
436 printTest ((take 7 [(1::Ratio Int),2..]))
437 printTest ((take 7 [(1::Ratio Int),7..]))
438 printTest ((take 7 [(1::Ratio Int),1..]))
439 printTest ((take 7 [(1::Ratio Int),0..]))
440 printTest ((take 7 [(5::Ratio Int),2..]))
441 let x = (toEnum ((minBound::Int) + 1))::Ratio Int
442 printTest ((take 7 [x, x-1 ..]))
443 let x = (toEnum ((minBound::Int) + 5))::Ratio Int
444 printTest ((take 7 [x, x-1 ..]))
445 let x = (toEnum ((maxBound::Int) - 5))::Ratio Int
446 printTest ((take 7 [x, (x+1) ..]))
448 -- [x..y] aka enumFromTo
449 printTest ((take 7 ([(1::Ratio Int) .. 5])))
450 printTest ((take 4 ([(1::Ratio Int) .. 1])))
451 printTest ((take 7 ([(1::Ratio Int) .. 0])))
452 printTest ((take 7 ([(5::Ratio Int) .. 0])))
453 let x = (toEnum (maxBound - (5::Int))) :: Ratio Int
454 let y = (toEnum (maxBound::Int)) :: Ratio Int
455 printTest ((take 7 ([x..y])))
456 let x = (toEnum (minBound + (5::Int))) :: Ratio Int
457 let y = (toEnum (minBound::Int)) :: Ratio Int
458 printTest ((take 7 ([x..y])))
460 -- [x,y..z] aka enumFromThenTo
461 printTest ((take 7 [(5::Ratio Int),4..1]))
462 printTest ((take 7 [(5::Ratio Int),3..1]))
463 printTest ((take 7 [(5::Ratio Int),3..2]))
464 printTest ((take 7 [(1::Ratio Int),2..1]))
465 printTest ((take 7 [(2::Ratio Int),1..2]))
466 printTest ((take 7 [(2::Ratio Int),1..1]))
467 printTest ((take 7 [(2::Ratio Int),3..1]))
469 let x = (toEnum ((maxBound::Int) - 4)) :: Ratio Int
470 let y = (toEnum (maxBound::Int)) :: Ratio Int
471 printTest ((take 7 [x,(x+1)..y]))
472 let x = (toEnum ((minBound::Int) + 5)) :: Ratio Int
473 let y = (toEnum (minBound::Int)) :: Ratio Int
474 printTest ((take 7 [x,(x-1)..y]))
483 mayBomb x = catchAllIO x errorHandler
485 errorHandler :: Exception -> IO ()
488 Just t -> putStrLn ("error " ++ show t)
492 test :: Show a => String -> String -> a -> IO ()
493 test test_nm expected val = do
495 if expected == got then
496 putStrLn ": SUCCEEDED"
499 putStrLn ("( expected: " ++ show expected ++ " , got: " ++ show got ++ " )")