{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Default (Default)
import Data.Either (isRight)
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Text (Text)
import Test.Framework (defaultMain, testGroup)
import Test.Framework.Providers.HUnit (testCase)
import Test.HUnit (assertBool, assertEqual)
import qualified Data.PerfectHash.Construction as Construction
import Data.PerfectHash.Hashing (Hash)
import qualified Data.PerfectHash.Hashing as Hashing
import qualified Data.PerfectHash.Types.Nonces as Nonces
import qualified Exercise
testHashComputation
:: (Hashing.ToHashableChunks a, Show a)
=> a
-> Hash
-> IO ()
testHashComputation key val =
assertEqual error_message val computed_hash
where
error_message = unwords ["Incorrect hash computation of", show key]
computed_hash = Hashing.hash (Nonces.Nonce 0) key
mkInputs
:: Ord a
=> [a]
-> Map a Int
mkInputs inputs = Map.fromList $ zip inputs [1..]
wordIndexTuplesString :: Map String Int
wordIndexTuplesString = mkInputs [
"apple"
, "banana"
, "carrot"
]
wordIndexTuplesText :: Map Text Int
wordIndexTuplesText = mkInputs [
"alpha"
, "beta"
, "gamma"
]
intMapTuples :: Map Int Int
intMapTuples = mkInputs [
1000
, 5555
, 9876
]
testHashLookups
:: (Show a, Show b, Eq b, Default b, Hashing.ToHashableChunks a, Ord a)
=> Map a b
-> IO ()
testHashLookups word_index_tuples =
assertBool "Perfect hash lookups failed to match the input" $ isRight test_result_either
where
lookup_table = Construction.createMinimalPerfectHash word_index_tuples
test_result_either = Exercise.testPerfectLookups lookup_table word_index_tuples
tests = [
testGroup "Hash computation" [
testCase "compute-string-hash" $ testHashComputation ("blarg" :: String) $ Hashing.Hash 3322346319
, testCase "compute-int-hash" $ testHashComputation (70000 :: Int) $ Hashing.Hash 4169891409
]
, testGroup "Hash lookups" [
testCase "word-lookups-string" $ testHashLookups wordIndexTuplesString
, testCase "word-lookups-text" $ testHashLookups wordIndexTuplesText
, testCase "int-lookups" $ testHashLookups intMapTuples
]
, testGroup "Large scale round-tripping with random inputs" [
testCase "integers" $ assertBool "Lookups failed to match input" $
isRight $ Exercise.testPerfectLookups lookup_table intMapTuples
]
]
where
intMapTuples = Exercise.mkIntMapTuples 100000
lookup_table = Construction.createMinimalPerfectHash intMapTuples
main = defaultMain tests