packages feed

compact-word-vectors-0.1: test/Tests/Blob.hs

-- | Tests for blobs

{-# LANGUAGE CPP,BangPatterns #-}
module Tests.Blob where

--------------------------------------------------------------------------------

import Data.Word
import Data.List as L

import Data.Primitive.ByteArray

import Data.Vector.Compact.Blob

import Test.Tasty
import Test.Tasty.HUnit

--------------------------------------------------------------------------------

all_tests = tests_blobs

tests_blobs = testGroup "unit tests for Blobs"
  [ testCase "toList . fromList == id"    $ forall_ w64_lists   prop_from_to_list
  , testCase "fromList . toList == id"    $ forall_ blobs       prop_to_from_blob
  , testCase "toList vs. peekWord"        $ forall_ blobs       prop_tolist_vs_peek
  , testCase "blobHead vs. list head"     $ forall_ w64_lists   prop_head_of_list
  , testCase "eqBlob vs. naive"           $ forall_ blob_pairs  prop_eq_vs_naive
  , testCase "fromBA . toBA == id"        $ forall_ blobs       prop_to_from_bytearray
  , testCase "toBA . fromBA == pad"       $ forall_ byte_lists  prop_from_to_bytearray
  ]

forall_ :: [a] -> (a -> Bool) -> Assertion
forall_ xs cond = assertBool "failed" (and (map cond xs))

--------------------------------------------------------------------------------
-- * inputs

w64_lists_of_length :: Int -> [[Word64]]
w64_lists_of_length ni =
  [ [ i | i<-[1..n]  ]
  , [ i | i<-[1001+n,1000+n .. 1001] ]
  , [ i | i<-[2^32-1-n .. 2^32-1   ] ]
  , [ i | i<-[2^32-1   .. 2^32+n-2 ] ]
  , [ i | i<-[2^64-1-n .. 2^64-1   ] ]
  ]
  where
    n = fromIntegral ni :: Word64

w64_lists = concatMap w64_lists_of_length [1..33]  :: [[Word64]]
blobs     = map blobFromWordList w64_lists            :: [Blob]

blob_pairs = [ (b1,b2)| b1<-blobs, b2<-blobs ] :: [(Blob,Blob)]

byte_lists = [ map fromIntegral [1..n] | n<-[1..(512::Int)] ] :: [[Word8]]

--------------------------------------------------------------------------------

eqBlob_naive b1 b2 = blobToWordList b1 == blobToWordList b2

baToList :: ByteArray -> [Word8]
baToList = foldrByteArray (:) [] 

pad :: [Word8] -> [Word8]
pad xs = xs ++ replicate (len8-len) 0 where
  len  = length xs
  len8 = 8 * (div (len+7) 8)

--------------------------------------------------------------------------------
-- * properties

prop_from_to_list list = blobToWordList (blobFromWordList list) == list
prop_to_from_blob blob = blobFromWordList (blobToWordList blob) == blob

prop_tolist_vs_peek blob = [ peekWord blob i | i<-[0..n-1] ] == blobToWordList blob where 
  n = blobSizeInWords blob

prop_head_of_list list = blobHead (blobFromWordList list) == L.head list

prop_eq_vs_naive (b1,b2) = eqBlob b1 b2 == eqBlob_naive b1 b2 

prop_to_from_bytearray blob = blobFromByteArray (blobToByteArray blob) == blob 

prop_from_to_bytearray list = baToList (blobToByteArray (blobFromByteArray ba)) == pad list where
  ba = byteArrayFromList list 

--------------------------------------------------------------------------------