{-# LANGUAGE FlexibleContexts #-} import Data.Typeable import Test.QuickCheck import Test.Framework (Test,testGroup,defaultMain) import Test.Framework.Providers.QuickCheck2 (testProperty) import Data.Histogram import Data.Histogram.Bin.MaybeBin import QC.Instances () ---------------------------------------------------------------- -- ---------------------------------------------------------------- tests :: [Test] tests = [ testGroup "Bins" [ testsBin (T :: T BinI) , testsBin (T :: T BinInt) , testsBin (T :: T (BinF Float)) , testsBin (T :: T (BinF Float)) , testsBin (T :: T BinD) , testsBin (T :: T (BinEnum Char)) , testsBin (T :: T LogBinD) , testsBin (T :: T (MaybeBin BinI)) , testsBin (T :: T (Bin2D BinI BinI)) ] , testGroup "fromIndex . toIndex == is" [ testProperty "BinI" $ prop_FromTo (T :: T BinI) , testProperty "BinEnum" $ prop_FromTo (T :: T (BinEnum Char)) , testProperty "Bin2D" $ prop_FromTo (T :: T (Bin2D BinI BinI)) ] , testGroup "Sliceable bins" [ testSliceBin (T :: T BinI) , testSliceBin (T :: T BinInt) , testSliceBin (T :: T (BinF Float)) , testSliceBin (T :: T (BinF Float)) , testSliceBin (T :: T BinD) , testSliceBin (T :: T (BinEnum Char)) , testSliceBin (T :: T LogBinD) ] , testGroup "Histogram" [ testProperty "read . show" (isIdentity (readHistogram . show) :: Histogram BinI Int -> Bool) ] ] testsBin :: ( Read a, Show a, Show (BinValue a), Eq a, Typeable a , Bin a , Arbitrary a, Arbitrary (BinValue a) ) => T a -> Test testsBin t = testGroup ("Bin test for " ++ show (typeOfT t)) [ testProperty "read . show = id" $ prop_ReadShow t , testProperty "toIndex . fromIndex = id" $ prop_ToFrom t , testProperty "inRange" $ prop_InRange t ] testSliceBin :: ( Show b, Typeable b, SliceableBin b, Arbitrary b ) => T b -> Test testSliceBin t = testGroup ("Slice tests for" ++ show (typeOfT t)) [ testProperty "N of bins" $ prop_sliceBin t ] ---------------------------------------------------------------- -- Bin tests ---------------------------------------------------------------- -- > read . show == id prop_ReadShow :: (Read a, Show a, Eq a) => T a -> a -> Bool prop_ReadShow _ = isIdentity (read . show) -- > toIndex . fromIndex == id prop_ToFrom :: Bin bin => T bin -> Int -> bin -> Property prop_ToFrom _ i bin = i >= 0 && i < nBins bin ==> isIdentity (toIndex bin . fromIndex bin) i -- > fromIndex . toIndex == id -- Hold only for integral bins prop_FromTo :: (Bin bin, Eq (BinValue bin)) => T bin -> BinValue bin -> bin -> Property prop_FromTo _ x bin = inRange bin x ==> isIdentity (fromIndex bin . toIndex bin) x -- > inRange b x == indexInRange b x prop_InRange :: (Bin bin) => T bin -> bin -> BinValue bin -> Bool prop_InRange _ b x = inRange b x == indexInRange (toIndex b x) where indexInRange i = i >= 0 && i < nBins b -- Sliced bin have correct number of bins prop_sliceBin :: (SliceableBin b) => T b -> b -> Gen Bool prop_sliceBin _ bin = do let n = nBins bin i <- choose (0, n-1) j <- choose (i, n-1) return $ nBins (sliceBin i j bin) == (j - i + 1) ---------------------------------------------------------------- -- Helpers ---------------------------------------------------------------- isIdentity :: Eq a => (a -> a) -> a -> Bool isIdentity f x = x == f x data T a = T paramOfT :: T a -> a paramOfT _ = undefined typeOfT :: Typeable a => T a -> TypeRep typeOfT = typeOf . paramOfT ---------------------------------------------------------------- -- Main ---------------------------------------------------------------- main :: IO () main = defaultMain tests