----------------------------------------------------------------------------- -- -- Module : tests.Main -- Copyright : (c) 2007 - 2013 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 import Data.Algorithms.Palindromes.PalindromesUtils import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC longestTextPalindrome = Data.Algorithms.Palindromes.Palindromes.palindrome (Just Text) (Just Longest) (Just Linear) Nothing Nothing Nothing longestWordPalindrome = Data.Algorithms.Palindromes.Palindromes.palindrome (Just Word) (Just Longest) (Just Linear) Nothing Nothing Nothing propPalindromesAroundCentres :: Property propPalindromesAroundCentres = forAll (arbitrary:: Gen [Char]) $ \l -> let input = BC.pack l in palindromesAroundCentres (Just Text) (Just Linear) Nothing Nothing input == longestPalindromesQ input longestPalindromesQ :: B.ByteString -> [Int] longestPalindromesQ input = let (afirst,alast) = (0,B.length input - 1) positions = [0 .. 2*(alast-afirst+1)] in map (lengthPalindromeAround input) positions lengthPalindromeAround :: B.ByteString -> Int -> Int lengthPalindromeAround input 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) = (0,B.length input -1) extendPalindromeAround start end = if start < 0 || end > alast-afirst || B.index input start /= B.index input end then end-start-1 else extendPalindromeAround (start-1) (end+1) propTextPalindrome :: Property propTextPalindrome = forAll (arbitrary:: Gen [Char]) $ \l -> let ltp = longestTextPalindrome (BC.pack l) ltp' = map toLower (filter myIsLetterC (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 (BC.pack "abcdea,ba.")) ) testTextPalindrome2 = TestCase (assertEqual "textPalindrome2" "\"a,ba\"" (longestTextPalindrome (BC.pack "abcdea,ba")) ) testTextPalindrome3 = TestCase (assertEqual "textPalindrome3" "\".a,ba\"" (longestTextPalindrome (BC.pack "abcde.a,ba")) ) testTextPalindrome4 = TestCase (assertEqual "textPalindrome4" "\".a,ba\"" (longestTextPalindrome (BC.pack "abcde.a,baf")) ) testTextPalindrome5 = TestCase (assertEqual "textPalindrome5" "\".ab,a\"" (longestTextPalindrome (BC.pack ".ab,acdef")) ) testTextPalindrome6 = TestCase (assertEqual "textPalindrome6" "\"ab,a\"" (longestTextPalindrome (BC.pack "ab,acdef")) ) testTextPalindrome7 = TestCase (assertEqual "textPalindrome7" "\"ab,a.\"" (longestTextPalindrome (BC.pack "ab,a.cdef")) ) testTextPalindrome8 = TestCase (assertEqual "textPalindrome8" "\".ab,a.\"" (longestTextPalindrome (BC.pack "g.ab,a.cdef")) ) testTextPalindrome9 = TestCase (assertEqual "textPalindrome9" "" (longestTextPalindrome B.empty) ) testTextPalindrome10 = TestCase (do string <- B.readFile "/Users/johan/Documents/Palindromes/Software/staff.johanj.palindromes/trunk/examples/palindromes/Damnitimmad.txt" assertEqual "textPalindrome10" (concatMap (\c -> case c of '\n' -> "\\n" '\"' -> "\""--""\\\"" d -> [d] ) (show string) ) (longestTextPalindrome string) ) testTextPalindrome11 = TestCase (do string <- B.readFile "/Users/johan/Documents/Palindromes/Software/staff.johanj.palindromes/trunk/examples/palindromes/pal17.txt" assertEqual "textPalindrome11" (concatMap (\c -> case c of '\n' -> "\\n" '\"' -> "\"" d -> [d] ) (show string)) (longestTextPalindrome string) ) testWordPalindrome1 = TestCase (assertEqual "wordPalindrome" "\" is non si, \"" (longestWordPalindrome (BC.pack "what is non si, not?")) ) testWordPalindrome2 = TestCase (assertEqual "wordPalindrome" "\" is non si\"" (longestWordPalindrome (BC.pack "what is non si")) ) testWordPalindrome3 = TestCase (assertEqual "wordPalindrome" "\"is non si, \"" (longestWordPalindrome (BC.pack "is non si, not?")) ) testWordPalindrome4 = TestCase (assertEqual "wordPalindrome" "" (longestWordPalindrome (BC.pack "aaaaba")) ) testWordPalindrome5 = TestCase (assertEqual "wordPalindrome" "\" a\"" (longestWordPalindrome (BC.pack "aaaab a")) ) testWordPalindrome6 = TestCase (assertEqual "wordPalindrome" "\" waaw \"" (longestWordPalindrome (BC.pack "w waaw wo waw")) ) testWordPalindrome7 = TestCase (assertEqual "wordPalindrome" "\" waaw \"" (longestWordPalindrome (BC.pack "vwaawvxy v waaw v")) ) 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 ,TestLabel "testWordPalindrome7" testWordPalindrome7 ] main :: IO Counts main = do quickCheck propPalindromesAroundCentres quickCheck propTextPalindrome runTestTT tests {- 2nd property falsified by "m\159:t\231\202\r\STX-me\230\&9JS/\EM'5\164\171\148\&5A@\196\242\f\157jY\NULB,\134\179\ESCS`:\ff\203\b\130\&0\DC3Yni>L" "\GS[\242\tx\ENQ3\247\&3\130(\NUL?zX\215\DC3" "\213\SI6+\ESCU:1\165\254\228\SUB9\200\231\USM,3\227\&3\176\214X\203\SOH\130UI9\154\239