creatur-2.0.10: test/ALife/Creatur/Genetics/CodeQC.hs
{-# LANGUAGE UnicodeSyntax #-}
module ALife.Creatur.Genetics.CodeQC
(
test
) where
import ALife.Creatur.Genetics.Code
import ALife.Creatur.Genetics.CodeInternal
import Data.Eq.Unicode ((≡))
import Data.Ord.Unicode ((≤))
import Data.List (nub)
import Test.Framework as TF (Test, testGroup)
import Test.Framework.Providers.QuickCheck2 (testProperty)
import Test.QuickCheck (Arbitrary, Gen, Property, arbitrary, property,
sized, vectorOf)
-- guaranteed not to have multiple values for the same code (but might have
-- multiple codes for the same value)
data TestCode = TestCode (Code Char Bool) deriving Show
sizedArbTestCode ∷ Int → Gen TestCode
sizedArbTestCode n = do
cs ← vectorOf n arbitrary
xs ← vectorOf n arbitrary
return $ TestCode $ Code n $ zip cs (nub xs)
instance Arbitrary TestCode where
arbitrary = sized sizedArbTestCode
prop_encoding_round_trippable ∷ TestCode → Char → Property
prop_encoding_round_trippable (TestCode g) c =
property $ maybe Nothing (decode g) (encode g c) ≡ c'
where c' = if c `elem` cs then Just c else Nothing
cs = map fst $ cTable g
-- guaranteed not to have multiple values for the same code, or multiple codes
-- for the same value
data TestCode2 = TestCode2 (Code Char Bool) deriving Show
sizedArbTestCode2 ∷ Int → Gen TestCode2
sizedArbTestCode2 n = do
cs ← vectorOf n arbitrary
xs ← vectorOf n arbitrary
return $ TestCode2 $ Code n $ zip (nub cs) (nub xs)
instance Arbitrary TestCode2 where
arbitrary = sized sizedArbTestCode2
prop_decoding_round_trippable ∷ TestCode2 → [Bool] → Property
prop_decoding_round_trippable (TestCode2 g) x =
property $ maybe Nothing (encode g) (decode g x) ≡ x'
where x' = if x `elem` xs then Just x else Nothing
xs = map snd $ cTable g
data TestParms = TestParms String deriving Show
sizedTestParms ∷ Int → Gen TestParms
sizedTestParms n = do
let n' = 2 + min 8 n -- keep number of values low to speed up tests
let values = take n' ['a' .. 'z']
return $ TestParms values
instance Arbitrary TestParms where
arbitrary = sized sizedTestParms
prop_gray_code_is_efficient ∷ TestParms → Property
prop_gray_code_is_efficient (TestParms values) =
property $ 2 ^ (nBits - 1) < nValues && nValues ≤ 2 ^ nBits
where g = mkGrayCode values
nValues = length values
nBits = (length . snd . head . cTable) g
test ∷ Test
test = testGroup "QuickCheck ALife.Creatur.Genetics.CodeQC"
[
testProperty "prop_encoding_round_trippable"
prop_encoding_round_trippable,
testProperty "prop_decoding_round_trippable"
prop_decoding_round_trippable,
testProperty "prop_gray_code_is_efficient"
prop_gray_code_is_efficient
]