packages feed

hunt-searchengine-0.3.0.1: test/Hunt/AnalyzerTests.hs

{-# LANGUAGE OverloadedStrings #-}

module Hunt.AnalyzerTests
(analyzerTests)
where
{-- Tests for Normalizers Analyzers Formatters #-}

import           Hunt.TestHelper

import qualified Data.Text                              as T

import           Test.Framework
import           Test.Framework.Providers.HUnit
import           Test.Framework.Providers.QuickCheck2
import           Test.HUnit                           hiding (Test)
import           Test.QuickCheck

import qualified Hunt.Index.Schema.Analyze            as A
import qualified Hunt.Index.Schema.Normalize.Date     as ND
import qualified Hunt.Index.Schema.Normalize.Position as NP
import qualified Hunt.Index.Schema.Normalize.Int      as NI

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

analyzerTests :: [Test]
analyzerTests =
  [-- Analyzer tests
    testCase "scanTextRE: text1 "             test_scan_text1
  , testCase "scanTextRE: date inv"           test_scan_date1
  , testCase "scanTextRE: date val"           test_scan_date2
  , testCase "scanTextRE: date val multiple"  test_scan_date3
  , testCase "scanTextRE: date val + inval"   test_scan_date4
  , testCase "scanTextRE: date val short   "  test_scan_date5
  , testCase "scanTextRE: date val shorter"   test_scan_date6

  -- Normalizer data - isAnyDate
  , testProperty "Normalizer: date YYYYMMDD"            prop_isAnyDate
  , testProperty "Normalizer: date 2013-01-01T21:12:12" prop_isAnyDate2
  , testProperty "Normalizer: date 2013"                prop_isAnyDate3

  -- Normalizer position
  , testProperty "Normalizer: pos double"       prop_isPosition_d
  , testProperty "Normalizer: pos text"         prop_isPosition_t
  , testCase     "Normalizer: norm pos int1"    test_norm_pos
  , testCase     "Normalizer: norm pos int2"    test_norm_pos2
  , testCase     "Normalizer: norm pos dbl1"    test_norm_pos4
  , testCase     "Normalizer: norm pos dbl2"    test_norm_pos5
  , testProperty "Normalizer: norm denorm dbl"  prop_norm_pos3

  -- Normalizer int
  , testProperty "Normalizer: isInt Int"         prop_isInt_int
  , testProperty "Normalizer: isInt Integer"     prop_isInt_integer
  , testProperty "Normalizer: isInt text"        prop_isInt_text
  , testProperty "Normalizer: isInt double"      prop_isInt_double
  , testCase     "Normalizer: isInt overflow"    test_isInt_overflow
  , testCase     "Normalizer: isInt nooverflow"  test_isInt_overflow2
  , testCase     "Normalizer: isInt maxBound1"   test_isInt_upper1
  , testCase     "Normalizer: isInt maxBound2"   test_isInt_upper2
  , testCase     "Normalizer: isInt minBound1"   test_isInt_lower1
  , testCase     "Normalizer: isInt minBound2"   test_isInt_lower2

  , testProperty "Normalizer: normInt int"      prop_normInt_int
  , testProperty "Normalizer: normInt integer"  prop_normInt_integer
  , testCase     "Normalizer: isInt 1"          test_normInt1
  , testCase     "Normalizer: isInt -1"         test_normInt2
  , testCase     "Normalizer: isInt maxBound"   test_normInt3
  , testCase     "Normalizer: isInt minBound"   test_normInt4
  ]

-- ----------------------------------------------------------------------------
-- normalizer position tests

prop_isInt_int :: Gen Bool
prop_isInt_int = do
  val <- arbitrary :: Gen Int
  return . NI.isInt . T.pack . show $ val

prop_isInt_integer :: Gen Bool
prop_isInt_integer = do
  val <- arbitrary :: Gen Integer
  return . NI.isInt . T.pack .show $ val

prop_isInt_text :: Gen Bool
prop_isInt_text = do
  val <- niceText1
  return . not . NI.isInt $ val

prop_isInt_double :: Gen Bool
prop_isInt_double = do
  val <- arbitrary :: Gen Double
  return . not . NI.isInt . T.pack . show $ val

test_isInt_overflow :: Assertion
test_isInt_overflow = assertEqual "" False (NI.isInt  "10000000000000000000000000000000000000")

test_isInt_overflow2 :: Assertion
test_isInt_overflow2 = assertEqual "" True (NI.isInt  "6443264")

test_isInt_upper1 :: Assertion
test_isInt_upper1 = assertEqual "" True (NI.isInt  "9223372036854775807")

test_isInt_upper2 :: Assertion
test_isInt_upper2 = assertEqual "" False (NI.isInt  "9223372036854775808")

test_isInt_lower1 :: Assertion
test_isInt_lower1 = assertEqual "" True (NI.isInt  "-9223372036854775808")

test_isInt_lower2 :: Assertion
test_isInt_lower2 = assertEqual "" False (NI.isInt  "-9223372036854775809")

prop_normInt_int :: Gen Bool
prop_normInt_int = do
  val <- arbitrary :: Gen Int
  return $ 21 == T.length (NI.normalizeToText . T.pack . show $ val)

prop_normInt_integer :: Gen Bool
prop_normInt_integer = do
  val <- arbitrary :: Gen Integer
  return $ 21 == T.length (NI.normalizeToText . T.pack . show $ val)

test_normInt1 :: Assertion
test_normInt1 = assertEqual "" "100000000000000000001" (NI.normalizeToText "1")

test_normInt2 :: Assertion
test_normInt2 = assertEqual "" "000000000000000000001" (NI.normalizeToText "-1")

test_normInt3 :: Assertion
test_normInt3 = assertEqual "" "109223372036854775807" (NI.normalizeToText "9223372036854775807")

test_normInt4 :: Assertion
test_normInt4 = assertEqual "" "009223372036854775808" (NI.normalizeToText "-9223372036854775808")


-- ----------------------------------------------------------------------------
-- normalizer position tests

genPos :: Gen String
genPos = do
  lat  <- choose (-89,89)  :: Gen Int
  long <- choose (-179,179) :: Gen Int
  return $ concat [ show lat, ".0000001-", show long, ".0000002" ]

prop_isPosition_d :: Gen Bool
prop_isPosition_d = do
  pos  <- genPos
  return . NP.isPosition $ T.pack pos

prop_isPosition_t :: Gen Bool
prop_isPosition_t = do
  long <- niceText1
  lat  <- niceText1
  return $ False == NP.isPosition (T.concat [ long, "-", lat ])

test_norm_pos :: Assertion
test_norm_pos = assertEqual "" "1100000000000000110000111100000011000011001111001100000000000000" (NP.normalize "1-1")

test_norm_pos2 :: Assertion
test_norm_pos2 = assertEqual "" "0000000000000000110000111100000011000011001111001100000000000000" (NP.normalize "-1.00--1.000")

test_norm_pos4 :: Assertion
test_norm_pos4 = assertEqual "" "1100000000000000110000111100000011000011001111001100000000000000" (NP.normalize "1.000000-1.000000")

test_norm_pos5 :: Assertion
test_norm_pos5 = let pos = "-25.0000001-1.0000002" in assertEqual "" pos . NP.denormalize . NP.normalize $ pos

prop_norm_pos3 :: Gen Property
prop_norm_pos3 = do
  p <- genPos
  let pos  = T.pack p
  let pos' = NP.denormalize . NP.normalize $ pos
  return $ counterexample (p ++ " != " ++ T.unpack pos') $ pos == pos'

-- ----------------------------------------------------------------------------
-- normalizer date tests

-- | test with date formatted like "2013-01-01"
-- | XXX everything fails?!?!
prop_isAnyDate :: Gen Bool
prop_isAnyDate = dateYYYYMMDD >>= return . ND.isAnyDate . T.unpack

prop_isAnyDate2 :: Gen Bool
prop_isAnyDate2 = return . ND.isAnyDate $ "2013-01-01T21:12:12"

prop_isAnyDate3 :: Gen Bool
prop_isAnyDate3 = return . ND.isAnyDate $ "2013"

-- ----------------------------------------------------------------------------
-- normalizer tests - validation
{-- depricated
-- | every random text should be a valid text
prop_validate_text :: Gen Bool
prop_validate_text = niceText1 >>= return . (N.typeValidator S.CText)

-- | every integer numbers should be valid numbers
prop_validate_int :: Gen Bool
prop_validate_int = do
  int <- arbitrary :: Gen Integer
  return $ N.typeValidator S.CInt (T.pack . show $ int)

-- | random text should not be considered a valid number
prop_validate_int2 :: Gen Bool
prop_validate_int2 = niceText1 >>= \t -> return $ False == N.typeValidator S.CInt ("a" `T.append` t)

-- | date formated "yyyy-mm-dd" should be valid
prop_validate_date :: Gen Bool
prop_validate_date = dateYYYYMMDD >>= return . (N.typeValidator S.CDate)

-- | random text should not be considered a valid date
prop_validate_date2 :: Gen Bool
prop_validate_date2 = niceText1 >>= \d -> return $ False == N.typeValidator S.CDate d
--}
-- ----------------------------------------------------------------------------
-- scan tests

-- | test general text regex
test_scan_text1 :: Assertion
test_scan_text1 = assert $ length scan == 3
  where
  scan = A.scanTextRE "[^ \t\n\r]*" "w1 w2 w3"

-- | test date regex with invalid date given
test_scan_date1 :: Assertion
test_scan_date1 = assert $ length scan == 0
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "w1 w2 w3"

-- | test date regex with valid date given
test_scan_date2 :: Assertion
test_scan_date2 = assert $ length scan == 1
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "2013-01-01"

-- | test date regex with multiple dates given
test_scan_date3 :: Assertion
test_scan_date3 = assert $ length scan == 2
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "2013-01-01 2012-12-31"

-- | test date regex with date containing string
test_scan_date4 :: Assertion
test_scan_date4 = assert $ (length scan == 2) && (scan !! 1 == "2013-01-01")
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "2013-01-01 asd 2013-01-01"

-- | test date regex with invalid date given
test_scan_date5 :: Assertion
test_scan_date5 = assert $ length scan == 0
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "2013-01"

-- | test date regex with invalid date given
test_scan_date6 :: Assertion
test_scan_date6 = assert $ length scan == 0
  where
  scan = A.scanTextRE "[0-9]{4}-((0[1-9])|(1[0-2]))-((0[1-9])|([12][0-9])|(3[01]))" "2013"