palindromes-0.2.2.2: tests/Main.hs
-----------------------------------------------------------------------------
-- |
-- Module : tests.Main
-- Copyright : (c) 2007 - 2011 Johan Jeuring
-- License : BSD3
--
-- Maintainer : johan@jeuring.net
-- Stability : experimental
-- Portability : portable
--
-----------------------------------------------------------------------------
module Main where
import Data.Array
import Data.Char
import Test.QuickCheck
import Test.HUnit
import Data.Algorithms.Palindromes.Palindromes
propPalindromesAroundCentres :: Property
propPalindromesAroundCentres =
forAll (arbitrary:: Gen [Int]) $
\l -> let a = array (0,length l - 1) (zip [0..] l)
in palindromesAroundCentres a == longestPalindromesQ a
longestPalindromesQ :: Eq a => Array Int a -> [Int]
longestPalindromesQ a =
let (afirst,alast) = bounds a
positions = [0 .. 2*(alast-afirst+1)]
in map (lengthPalindromeAround a) positions
lengthPalindromeAround :: Eq a => Array Int a
-> Int
-> Int
lengthPalindromeAround a position
| even position =
extendPalindromeAround (afirst+pos-1) (afirst+pos)
| odd position =
extendPalindromeAround (afirst+pos-1) (afirst+pos+1)
where pos = div position 2
(afirst,alast) = bounds a
extendPalindromeAround start end =
if start < 0
|| end > alast-afirst
|| a!start /= a!end
then end-start-1
else extendPalindromeAround (start-1) (end+1)
propTextPalindrome :: Property
propTextPalindrome =
forAll (arbitrary:: Gen [Char]) $
\l -> let ltp = longestTextPalindrome l
ltp' = map toLower (filter isLetter (unescape ltp))
in ltp' == reverse ltp'
unescape :: String -> String
unescape [] = []
unescape cs = case readLitChar cs of
(c,rest):xs -> c:unescape rest
[] -> []
testTextPalindrome1, testTextPalindrome2, testTextPalindrome3, testTextPalindrome4,
testTextPalindrome5, testTextPalindrome6, testTextPalindrome7, testTextPalindrome8,
testTextPalindrome9, testTextPalindrome10, testTextPalindrome11 :: Test
testWordPalindrome1, testWordPalindrome2, testWordPalindrome3, testWordPalindrome4,
testWordPalindrome5, testWordPalindrome6 :: Test
testTextPalindrome1 =
TestCase (assertEqual
"textPalindrome1"
"\"a,ba.\""
(longestTextPalindrome "abcdea,ba.")
)
testTextPalindrome2 =
TestCase (assertEqual
"textPalindrome2"
"\"a,ba\""
(longestTextPalindrome "abcdea,ba")
)
testTextPalindrome3 =
TestCase (assertEqual
"textPalindrome3"
"\".a,ba\""
(longestTextPalindrome "abcde.a,ba")
)
testTextPalindrome4 =
TestCase (assertEqual
"textPalindrome4"
"\".a,ba\""
(longestTextPalindrome "abcde.a,baf")
)
testTextPalindrome5 =
TestCase (assertEqual
"textPalindrome5"
"\".ab,a\""
(longestTextPalindrome ".ab,acdef")
)
testTextPalindrome6 =
TestCase (assertEqual
"textPalindrome6"
"\"ab,a\""
(longestTextPalindrome "ab,acdef")
)
testTextPalindrome7 =
TestCase (assertEqual
"textPalindrome7"
"\"ab,a.\""
(longestTextPalindrome "ab,a.cdef")
)
testTextPalindrome8 =
TestCase (assertEqual
"textPalindrome8"
"\".ab,a.\""
(longestTextPalindrome "g.ab,a.cdef")
)
testTextPalindrome9 =
TestCase (assertEqual
"textPalindrome9"
""
(longestTextPalindrome "")
)
testTextPalindrome10 =
TestCase (do string <- readFile "examples/palindromes/Damnitimmad.txt"
assertEqual
"textPalindrome10"
(concatMap (\c -> case c of
'\n' -> "\\n"
'\"' -> "\\\""
d -> [d]
)
string
)
(init . tail $ longestTextPalindrome string)
)
testTextPalindrome11 =
TestCase (do string <- readFile "examples/palindromes/pal17.txt"
assertEqual
"textPalindrome11"
("\"" ++
concatMap (\c -> case c of
'\n' -> "\\n"
'\"' -> "\\\""
d -> [d]
)
string ++
"\"")
(longestTextPalindrome string)
)
testWordPalindrome1 =
TestCase (assertEqual
"wordPalindrome"
"\" is non si, \""
(longestWordPalindrome "what is non si, not?")
)
testWordPalindrome2 =
TestCase (assertEqual
"wordPalindrome"
"\" is non si\""
(longestWordPalindrome "what is non si")
)
testWordPalindrome3 =
TestCase (assertEqual
"wordPalindrome"
"\"is non si, \""
(longestWordPalindrome "is non si, not?")
)
testWordPalindrome4 =
TestCase (assertEqual
"wordPalindrome"
""
(longestWordPalindrome "aaaaba")
)
testWordPalindrome5 =
TestCase (assertEqual
"wordPalindrome"
"\" a\""
(longestWordPalindrome "aaaab a")
)
testWordPalindrome6 =
TestCase (assertEqual
"wordPalindrome"
"\" waaw \""
(longestWordPalindrome "w waaw wo waw")
)
tests :: Test
tests = TestList [TestLabel "testTextPalindrome1" testTextPalindrome1
,TestLabel "testTextPalindrome2" testTextPalindrome2
,TestLabel "testTextPalindrome3" testTextPalindrome3
,TestLabel "testTextPalindrome4" testTextPalindrome4
,TestLabel "testTextPalindrome5" testTextPalindrome5
,TestLabel "testTextPalindrome6" testTextPalindrome6
,TestLabel "testTextPalindrome7" testTextPalindrome7
,TestLabel "testTextPalindrome8" testTextPalindrome8
,TestLabel "testTextPalindrome9" testTextPalindrome9
,TestLabel "testTextPalindrome10" testTextPalindrome10
,TestLabel "testTextPalindrome11" testTextPalindrome11
,TestLabel "testWordPalindrome1" testWordPalindrome1
,TestLabel "testWordPalindrome2" testWordPalindrome2
,TestLabel "testWordPalindrome3" testWordPalindrome3
,TestLabel "testWordPalindrome4" testWordPalindrome4
,TestLabel "testWordPalindrome5" testWordPalindrome5
,TestLabel "testWordPalindrome6" testWordPalindrome6
]
main :: IO Counts
main = do
quickCheck propPalindromesAroundCentres
quickCheck propTextPalindrome
runTestTT tests
{-
Code for benchmarking. Needs to go in a separate file.
To compare my solution and Rampion's lazy solution:
[bench "lengthLongestPalindromes" (nf (palindromesAroundCentres (==) . listArrayl0) input)
,bench "Rampion's solution" (nf maximalPalindromeLengths input)
]
import Criterion.Main
import Data.Algorithms.Palindromes.Palindromes
import PalindromeRampion
import System.IO
main :: IO ()
main =
do fn <- openFile "../../../TestSources/Bibles/engelskingjames.txt" ReadMode
hSetEncoding fn latin1
input <- hGetContents fn
defaultMain
[bench "lengthLongestPalindrome-Eq" (nf lengthLongestPalindrome input)]
-}