time-1.8: test/main/Test/Calendar/Valid.hs
module Test.Calendar.Valid(testValid) where
import Data.Time
import Data.Time.Calendar.OrdinalDate
import Data.Time.Calendar.WeekDate
import Data.Time.Calendar.Julian
import Test.Tasty
import Test.Tasty.QuickCheck hiding (reason)
import Test.QuickCheck.Property
validResult :: (Eq c,Show c,Eq t,Show t) =>
(s -> c) -> Bool -> (t -> c) -> (c -> t) -> (c -> Maybe t) -> s -> Result
validResult sc valid toComponents fromComponents fromComponentsValid s = let
c = sc s
mt = fromComponentsValid c
t' = fromComponents c
c' = toComponents t'
in if valid then
case mt of
Nothing -> rejected
Just t -> if t' /= t
then failed {reason = "'fromValid' gives " ++ show t ++ ", but 'from' gives " ++ show t'}
else if c' /= c
then failed {reason = "found valid, but converts " ++ show c ++ " -> " ++ show t' ++ " -> " ++ show c'}
else succeeded
else case mt of
Nothing -> if c' /= c
then succeeded
else failed {reason = show c ++ " found invalid, but converts with " ++ show t'}
Just _ -> rejected
validTest :: (Arbitrary s,Show s,Eq c,Show c,Eq t,Show t) =>
String -> (s -> c) -> (t -> c) -> (c -> t) -> (c -> Maybe t) -> TestTree
validTest name sc toComponents fromComponents fromComponentsValid = testGroup name
[
testProperty "valid" $ property $ validResult sc True toComponents fromComponents fromComponentsValid,
testProperty "invalid" $ property $ validResult sc False toComponents fromComponents fromComponentsValid
]
toSundayStartWeek :: Day -> (Integer,Int,Int)
toSundayStartWeek day = let
(y,_) = toOrdinalDate day
(w,d) = sundayStartWeek day
in (y,w,d)
toMondayStartWeek :: Day -> (Integer,Int,Int)
toMondayStartWeek day = let
(y,_) = toOrdinalDate day
(w,d) = mondayStartWeek day
in (y,w,d)
newtype Year = MkYear Integer deriving (Eq,Show)
instance Arbitrary Year where
arbitrary = fmap MkYear $ choose (-1000,3000)
newtype YearMonth = MkYearMonth Int deriving (Eq,Show)
instance Arbitrary YearMonth where
arbitrary = fmap MkYearMonth $ choose (-5,17)
newtype MonthDay = MkMonthDay Int deriving (Eq,Show)
instance Arbitrary MonthDay where
arbitrary = fmap MkMonthDay $ choose (-5,35)
newtype YearDay = MkYearDay Int deriving (Eq,Show)
instance Arbitrary YearDay where
arbitrary = fmap MkYearDay $ choose (-20,400)
newtype YearWeek = MkYearWeek Int deriving (Eq,Show)
instance Arbitrary YearWeek where
arbitrary = fmap MkYearWeek $ choose (-5,60)
newtype WeekDay = MkWeekDay Int deriving (Eq,Show)
instance Arbitrary WeekDay where
arbitrary = fmap MkWeekDay $ choose (-5,15)
fromYMD :: (Year,YearMonth,MonthDay) -> (Integer,Int,Int)
fromYMD (MkYear y,MkYearMonth ym,MkMonthDay md) = (y,ym,md)
fromYD :: (Year,YearDay) -> (Integer,Int)
fromYD (MkYear y,MkYearDay yd) = (y,yd)
fromYWD :: (Year,YearWeek,WeekDay) -> (Integer,Int,Int)
fromYWD (MkYear y,MkYearWeek yw,MkWeekDay wd) = (y,yw,wd)
testValid :: TestTree
testValid = testGroup "testValid"
[
validTest "Gregorian" fromYMD toGregorian (\(y,m,d) -> fromGregorian y m d) (\(y,m,d) -> fromGregorianValid y m d),
validTest "OrdinalDate" fromYD toOrdinalDate (\(y,d) -> fromOrdinalDate y d) (\(y,d) -> fromOrdinalDateValid y d),
validTest "WeekDate" fromYWD toWeekDate (\(y,w,d) -> fromWeekDate y w d) (\(y,w,d) -> fromWeekDateValid y w d),
validTest "SundayStartWeek" fromYWD toSundayStartWeek (\(y,w,d) -> fromSundayStartWeek y w d) (\(y,w,d) -> fromSundayStartWeekValid y w d),
validTest "MondayStartWeek" fromYWD toMondayStartWeek (\(y,w,d) -> fromMondayStartWeek y w d) (\(y,w,d) -> fromMondayStartWeekValid y w d),
validTest "Julian" fromYMD toJulian (\(y,m,d) -> fromJulian y m d) (\(y,m,d) -> fromJulianValid y m d)
]