packages feed

perfect-hash-generator-1.0.0: test/Main.hs

{-# 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