{-# OPTIONS_GHC -fno-warn-type-defaults #-} import Data.Foldable (for_) import Test.Hspec (Spec, describe, it, shouldBe) import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) import Clock (fromHourMin, toString) main :: IO () main = hspecWith defaultConfig {configFastFail = True} specs specs :: Spec specs = do -- Track-specific tests. describe "track-specific tests" $ do it "fromInteger should work in minutes" $ toString 3 `shouldBe` "00:03" it "constructor and fromInteger should be compatible" $ 60 `shouldBe` fromHourMin 1 0 it "negate works" $ negate (fromHourMin 23 55) `shouldBe` 5 describe "standard tests" $ do describe "create" $ for_ createCases createTest describe "add" $ for_ addCases addTest describe "equal" $ for_ equalCases equalTest where createTest (l, h, m, e) = it l assertion where assertion = toString (fromHourMin h m) `shouldBe` e addTest (l, h, m, m', e) = it l assertion where assertion = toString (fromHourMin h m + m') `shouldBe` e equalTest (l, (h1, m1), (h2, m2), e) = it l assertion where assertion = fromHourMin h1 m1 == fromHourMin h2 m2 `shouldBe` e createCases = [ ("on the hour" , 8, 0, "08:00") , ("past the hour" , 11, 9, "11:09") , ("midnight is zero hours" , 24, 0, "00:00") , ("hour rolls over" , 25, 0, "01:00") , ("hour rolls over continuously" , 100, 0, "04:00") , ("sixty minutes is next hour" , 1, 60, "02:00") , ("minutes roll over" , 0, 160, "02:40") , ("minutes roll over continuously" , 0, 1723, "04:43") , ("hour and minutes roll over" , 25, 160, "03:40") , ("hour and minutes roll over continuously" , 201, 3001, "11:01") , ("hour and minutes roll over to exactly midnight" , 72, 8640, "00:00") , ("negative hour" , -1, 15, "23:15") , ("negative hour rolls over" , -25, 0, "23:00") , ("negative hour rolls over continuously" , -91, 0, "05:00") , ("negative minutes" , 1, -40, "00:20") , ("negative minutes roll over" , 1, -160, "22:20") , ("negative minutes roll over continuously" , 1, -4820, "16:40") , ("negative hour and minutes both roll over" , -25, -160, "20:20") , ("negative hour and minutes both roll over continuously", -121, -5810, "22:10") ] addCases = [ ("add minutes" , 10, 0, 3, "10:03") , ("add no minutes" , 6, 41, 0, "06:41") , ("add to next hour" , 0, 45, 40, "01:25") , ("add more than one hour" , 10, 0, 61, "11:01") , ("add more than two hours with carry" , 0, 45, 160, "03:25") , ("add across midnight" , 23, 59, 2, "00:01") , ("add more than one day (1500 min = 25 hrs)" , 5, 32, 1500, "06:32") , ("add more than two days" , 1, 1, 3500, "11:21") , ("subtract minutes" , 10, 3, -3, "10:00") , ("subtract to previous hour" , 10, 3, -30, "09:33") , ("subtract more than an hour" , 10, 3, -70, "08:53") , ("subtract across midnight" , 0, 3, -4, "23:59") , ("subtract more than two hours" , 0, 0, -160, "21:20") , ("subtract more than two hours with borrow" , 6, 15, -160, "03:35") , ("subtract more than one day (1500 min = 25 hrs)", 5, 32, -1500, "04:32") , ("subtract more than two days" , 2, 20, -3000, "00:20") ] equalCases = [ ("clocks with same time" , (15, 37), ( 15, 37), True ) , ("clocks a minute apart" , (15, 36), ( 15, 37), False) , ("clocks an hour apart" , (14, 37), ( 15, 37), False) , ("clocks with hour overflow" , (10, 37), ( 34, 37), True ) , ("clocks with hour overflow by several days" , ( 3, 11), ( 99, 11), True ) , ("clocks with negative hour" , (22, 40), ( -2, 40), True ) , ("clocks with negative hour that wraps" , (17, 3), (-31, 3), True ) , ("clocks with negative hour that wraps multiple times" , (13, 49), (-83, 49), True ) , ("clocks with minute overflow" , ( 0, 1), ( 0, 1441), True ) , ("clocks with minute overflow by several days" , ( 2, 2), ( 2, 4322), True ) , ("clocks with negative minute" , ( 2, 40), ( 3, -20), True ) , ("clocks with negative minute that wraps" , ( 4, 10), ( 5, -1490), True ) , ("clocks with negative minute that wraps multiple times", ( 6, 15), ( 6, -4305), True ) , ("clocks with negative hours and minutes" , ( 7, 32), (-12, -268), True ) , ("clocks with negative hours and minutes that wrap" , (18, 7), (-54, -11513), True ) ]