time-compat-1.9.9: test/main/Test/Calendar/Duration.hs
module Test.Calendar.Duration
( testDuration,
)
where
import Data.Time.Calendar.Compat
import Data.Time.Calendar.Julian.Compat
import Test.Arbitrary ()
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck hiding (reason)
data AddDiff = MkAddDiff
{ adName :: String,
adAdd :: CalendarDiffDays -> Day -> Day,
adDifference :: Day -> Day -> CalendarDiffDays,
adFromYMD :: Integer -> Int -> Int -> Day
}
gregorianClip :: AddDiff
gregorianClip = MkAddDiff "gregorianClip" addGregorianDurationClip diffGregorianDurationClip fromGregorian
gregorianRollOver :: AddDiff
gregorianRollOver = MkAddDiff "gregorianRollOver" addGregorianDurationRollOver diffGregorianDurationRollOver fromGregorian
julianClip :: AddDiff
julianClip = MkAddDiff "julianClip" addJulianDurationClip diffJulianDurationClip fromJulian
julianRollOver :: AddDiff
julianRollOver = MkAddDiff "julianRollOver" addJulianDurationRollOver diffJulianDurationRollOver fromJulian
addDiffs :: [AddDiff]
addDiffs =
[ gregorianClip,
gregorianRollOver,
julianClip,
julianRollOver
]
testAddDiff :: AddDiff -> TestTree
testAddDiff MkAddDiff {..} = testProperty adName $ \day1 day2 ->
adAdd (adDifference day2 day1) day1 == day2
testAddDiffs :: TestTree
testAddDiffs =
testGroup
"add-diff"
$ fmap testAddDiff addDiffs
newtype Smallish = MkSmallish Integer deriving (Eq, Ord)
deriving newtype instance Show Smallish
instance Arbitrary Smallish where
arbitrary = do
b <- arbitrary
n <- if b then choose (0, 60) else return 30
return $ MkSmallish n
testPositiveDiff :: AddDiff -> TestTree
testPositiveDiff MkAddDiff {..} = testProperty adName $ \day1 (MkSmallish i) ->
let day2 = addDays i day1
r = adDifference day2 day1
in property $ cdMonths r >= 0 && cdDays r >= 0
testPositiveDiffs :: TestTree
testPositiveDiffs =
testGroup
"positive-diff"
$ fmap testPositiveDiff addDiffs
testSpecific :: AddDiff -> (Integer, Int, Int) -> (Integer, Int, Int) -> (Integer, Integer) -> TestTree
testSpecific MkAddDiff {..} (y2, m2, d2) (y1, m1, d1) (em, ed) =
let day1 = adFromYMD y1 m1 d1
day2 = adFromYMD y2 m2 d2
expected = CalendarDiffDays em ed
found = adDifference day2 day1
in testCase (adName ++ ": " ++ show day2 ++ " - " ++ show day1) $ do
assertEqual "add" day2 $ adAdd found day1
assertEqual "diff" expected found
testSpecificPair :: (Integer, Int, Int) -> (Integer, Int, Int) -> (Integer, Integer) -> (Integer, Integer) -> TestTree
testSpecificPair day2 day1 clipD rollD =
testGroup
(show day2 ++ " - " ++ show day1)
[ testSpecific gregorianClip day2 day1 clipD,
testSpecific gregorianRollOver day2 day1 rollD,
testSpecific julianClip day2 day1 clipD,
testSpecific julianRollOver day2 day1 rollD
]
testSpecifics :: TestTree
testSpecifics =
testGroup
"specific"
[ testSpecificPair (2017, 04, 07) (2017, 04, 07) (0, 0) (0, 0),
testSpecific gregorianClip (2017, 04, 07) (2017, 04, 01) (0, 6),
testSpecific gregorianClip (2017, 04, 01) (2017, 04, 07) (0, -6),
testSpecific gregorianClip (2017, 04, 07) (2017, 02, 01) (2, 6),
testSpecific gregorianClip (2017, 02, 01) (2017, 04, 07) (-2, -6),
testSpecificPair (2000, 03, 01) (2000, 01, 30) (1, 1) (1, 0),
testSpecificPair (2001, 03, 01) (2001, 01, 30) (1, 1) (0, 30),
testSpecificPair (2001, 03, 01) (2000, 01, 30) (13, 1) (12, 30),
testSpecificPair (2000, 03, 01) (2000, 01, 31) (1, 1) (0, 30),
testSpecificPair (2001, 03, 01) (2001, 01, 31) (1, 1) (0, 29),
testSpecificPair (2001, 03, 01) (2000, 01, 31) (13, 1) (12, 29),
testSpecificPair (2001, 10, 01) (2001, 08, 31) (1, 1) (1, 0)
]
testDuration :: TestTree
testDuration = testGroup "CalendarDiffDays" [testAddDiffs, testPositiveDiffs, testSpecifics]