-
Notifications
You must be signed in to change notification settings - Fork 0
/
test-lib.hs
66 lines (59 loc) · 2.18 KB
/
test-lib.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
module Main where
-- base:
import Control.Applicative
import Control.Monad
import System.Exit
-- bytestring:
import qualified Data.ByteString.Lazy as L
-- binary:
import Data.Binary
import Data.Binary.Put
import Data.Binary.Get
-- QuickCheck:
import Test.QuickCheck
import Test.QuickCheck.Test
-- partly:
import System.Disk.Partitions.MBR
-- | Generate a random lazy ByteString of some N bytes.
genBytes :: Int -> Gen L.ByteString
genBytes = fmap L.pack . flip vectorOf arbitrary
-- | Test whether a Get succeeds for any bytestring of some n bytes.
succeeds :: Int -> Get a -> Gen Bool
succeeds n get = isRight . runGetOrFail get <$> genBytes n
where isRight (Right _) = True; isRight _ = False;
-- | Test whether a getter and a putter are the exact inverses for
-- bytestrings of some length.
bijective :: Int -> Get b -> (b -> Put) -> Gen Bool
bijective n get put = (`fmap` genBytes n) $ \bs ->
bs == (runPut . put . runGet get $ bs)
testSuccess :: String -> Int -> Get t -> IO Bool
testSuccess s i g = do
putStrLn $ "--> " ++ s
r <- quickCheckResult $ succeeds i g
return $ resultToBool r
testBijective :: String -> Int -> Get b -> (b -> Put) -> IO Bool
testBijective s i g p = do
putStrLn $ "--> " ++ s
r <- quickCheckResult $ bijective i g p
return $ resultToBool r
resultToBool :: Result -> Bool
resultToBool (Success _ _ _) = True
resultToBool (GaveUp _ _ _) = False
resultToBool (Failure _ _ _ _ _ _ _) = False
main :: IO ()
main = do
putStrLn "Testing whether 'runGet' succeeds for any set of bytes:"
ss <- all id <$> sequence
[ testSuccess "CHS" 3 (get :: Get CHS)
, testSuccess "PartitionEntry" 16 (get :: Get PartitionEntry)
, testSuccess "PartitionTable" 64 (get :: Get PartitionTable)
, testSuccess "BootRecord" 512 (get :: Get BootRecord) ]
putStrLn ""
putStrLn "Testing that 'runGet get' and 'runPut . put' form an isomorphism:"
bs <- all id <$> sequence
[ testBijective "CHS" 3 (get :: Get CHS) put
, testBijective "PartitionEntry" 16 (get :: Get PartitionEntry) put
, testBijective "PartitionTable" 64 (get :: Get PartitionTable) put
, testBijective "BootRecord" 512 (get :: Get BootRecord) put ]
unless (ss && bs) exitFailure
return ()