packages feed

pureMD5-0.2.0: Test/MD5.hs

{-# LANGUAGE ExistentialQuantification #-}
module Test.MD5 where

import Test.QuickCheck
import Data.Digest.Pure.MD5
import qualified Data.ByteString.Lazy as L
import Control.Monad (forM)
import Data.Word (Word8)
import Data.Binary

instance Arbitrary Word8 where
    arbitrary = (arbitrary :: Gen Int) >>= return . fromIntegral

instance Arbitrary L.ByteString where
    arbitrary = do
        len <- choose (0,10000) :: Gen Int
        words <- forM [0..len] (\_ -> arbitrary)
        return $ L.pack words

prop_PartsEqWhole lps =
    let lpsChunks   = map (L.fromChunks . (:[])) (L.toChunks lps)
        incremental = foldl md5Update md5InitialContext lpsChunks
        final = md5Finalize incremental
    in md5 lps == final

prop_ShowLen bs = 32 == (length $ show (md5 bs))

prop_BinaryLen bs = 16 == (L.length $ encode (md5 bs))

prop_GetPut bs =
    let dg = md5 bs
    in decode (encode dg) == dg

prop_ShowElem bs =
    let digest = md5 bs
        valids = \c -> (c >= 'a' && c <= 'f') || (c >= '0' && c <= '9')
    in [] == filter (not . valids) (show digest)

prop_KnownAnswers =
  let mds = show . md5 . pk
      pk  = L.pack . (map (fromIntegral . fromEnum))
  in mds ("") == "d41d8cd98f00b204e9800998ecf8427e" &&
     mds ("a") == "0cc175b9c0f1b6a831c399e269772661" &&
     mds ("abc") == "900150983cd24fb0d6963f7d28e17f72" &&
     mds ("message digest") == "f96b697d7cb7938d525a2f31aaf161d0" &&
     mds ("abcdefghijklmnopqrstuvwxyz") == "c3fcd3d76192e4007dfb496cca67e13b" &&
     mds ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") ==
       "d174ab98d277d9f5a5611c2c9f419d9f" &&
     mds ("12345678901234567890123456789012345678901234567890123456789012345678901234567890") == "57edf4a22be3c955ac49da2e2107b67a"

tests = [ T prop_PartsEqWhole "PartsEqWhole"
        , T prop_ShowLen "ShowLen"
        , T prop_BinaryLen "BinaryLen"
        , T prop_GetPut "GetPut"
        , T prop_ShowElem "ShowElem"
        , T prop_KnownAnswers "KnownAnswers"]

data Test = forall a. Testable a => T a String
runTest (T a s) = do
    putStr ("prop_" ++ s ++ ": ")
    quickCheck a

runTests = mapM_ runTest tests