ISO 8601: more tests (#40)
[packages/time.git] / test / main / Test / Format / ISO8601.hs
1 {-# OPTIONS -fno-warn-orphans #-}
2 module Test.Format.ISO8601(testISO8601) where
3
4 import Data.Ratio
5 import Data.Time
6 import Data.Time.Format.ISO8601
7 import Test.QuickCheck.Property
8 import Test.Tasty
9 import Test.Tasty.HUnit
10 import Test.Tasty.QuickCheck hiding (reason)
11 import Test.TestUtil
12 import Test.Arbitrary()
13
14
15 deriving instance Eq ZonedTime
16
17 readShowProperty :: (Eq a,Show a) => Format a -> a -> Property
18 readShowProperty fmt val = case formatShowM fmt val of
19 Nothing -> property Discard
20 Just str -> let
21 found = formatParseM fmt str
22 expected = Just val
23 in property $ if expected == found then succeeded else
24 failed {reason = show str ++ ": expected " ++ (show expected) ++ ", found " ++ (show found)}
25
26 readBoth :: NameTest t => (FormatExtension -> t) -> [TestTree]
27 readBoth fmts =
28 [
29 nameTest "extended" $ fmts ExtendedFormat,
30 nameTest "basic" $ fmts BasicFormat
31 ]
32
33 readShowProperties :: (Eq a,Show a,Arbitrary a) => (FormatExtension -> Format a) -> [TestTree]
34 readShowProperties fmts = readBoth $ \fe -> readShowProperty $ fmts fe
35
36 newtype Durational t = MkDurational t
37
38 instance Show t => Show (Durational t) where
39 show (MkDurational t) = show t
40
41 instance Arbitrary (Durational CalendarDiffDays) where
42 arbitrary = do
43 mm <- choose (-10000,10000)
44 dd <- choose (-40,40)
45 return $ MkDurational $ CalendarDiffDays mm dd
46
47 instance Arbitrary (Durational CalendarDiffTime) where
48 arbitrary = let
49 limit = 40 * 86400
50 picofactor = 10 ^ (12 :: Int)
51 in do
52 mm <- choose (-10000,10000)
53 ss <- choose (negate limit * picofactor, limit * picofactor)
54 return $ MkDurational $ CalendarDiffTime mm $ fromRational $ ss % picofactor
55
56 testReadShowFormat :: TestTree
57 testReadShowFormat = nameTest "read-show format"
58 [
59 nameTest "calendarFormat" $ readShowProperties $ calendarFormat,
60 nameTest "yearMonthFormat" $ readShowProperty $ yearMonthFormat,
61 nameTest "yearFormat" $ readShowProperty $ yearFormat,
62 nameTest "centuryFormat" $ readShowProperty $ centuryFormat,
63 nameTest "expandedCalendarFormat" $ readShowProperties $ expandedCalendarFormat 6,
64 nameTest "expandedYearMonthFormat" $ readShowProperty $ expandedYearMonthFormat 6,
65 nameTest "expandedYearFormat" $ readShowProperty $ expandedYearFormat 6,
66 nameTest "expandedCenturyFormat" $ readShowProperty $ expandedCenturyFormat 4,
67 nameTest "ordinalDateFormat" $ readShowProperties $ ordinalDateFormat,
68 nameTest "expandedOrdinalDateFormat" $ readShowProperties $ expandedOrdinalDateFormat 6,
69 nameTest "weekDateFormat" $ readShowProperties $ weekDateFormat,
70 nameTest "yearWeekFormat" $ readShowProperties $ yearWeekFormat,
71 nameTest "expandedWeekDateFormat" $ readShowProperties $ expandedWeekDateFormat 6,
72 nameTest "expandedYearWeekFormat" $ readShowProperties $ expandedYearWeekFormat 6,
73 nameTest "timeOfDayFormat" $ readShowProperties $ timeOfDayFormat,
74 nameTest "hourMinuteFormat" $ readShowProperties $ hourMinuteFormat,
75 nameTest "hourFormat" $ readShowProperty $ hourFormat,
76 nameTest "withTimeDesignator" $ readShowProperties $ \fe -> withTimeDesignator $ timeOfDayFormat fe,
77 nameTest "withUTCDesignator" $ readShowProperties $ \fe -> withUTCDesignator $ timeOfDayFormat fe,
78 nameTest "timeOffsetFormat" $ readShowProperties $ timeOffsetFormat,
79 nameTest "timeOfDayAndOffsetFormat" $ readShowProperties $ timeOfDayAndOffsetFormat,
80 nameTest "localTimeFormat" $ readShowProperties $ \fe -> localTimeFormat (calendarFormat fe) (timeOfDayFormat fe),
81 nameTest "zonedTimeFormat" $ readShowProperties $ \fe -> zonedTimeFormat (calendarFormat fe) (timeOfDayFormat fe) fe,
82 nameTest "utcTimeFormat" $ readShowProperties $ \fe -> utcTimeFormat (calendarFormat fe) (timeOfDayFormat fe),
83 nameTest "dayAndTimeFormat" $ readShowProperties $ \fe -> dayAndTimeFormat (calendarFormat fe) (timeOfDayFormat fe),
84 nameTest "timeAndOffsetFormat" $ readShowProperties $ \fe -> timeAndOffsetFormat (timeOfDayFormat fe) fe,
85 nameTest "durationDaysFormat" $ readShowProperty $ durationDaysFormat,
86 nameTest "durationTimeFormat" $ readShowProperty $ durationTimeFormat,
87 nameTest "alternativeDurationDaysFormat" $ readBoth $ \fe (MkDurational t) -> readShowProperty (alternativeDurationDaysFormat fe) t,
88 nameTest "alternativeDurationTimeFormat" $ readBoth $ \fe (MkDurational t) -> readShowProperty (alternativeDurationTimeFormat fe) t,
89 nameTest "intervalFormat" $ readShowProperties $ \fe -> intervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat,
90 nameTest "recurringIntervalFormat" $ readShowProperties $ \fe -> recurringIntervalFormat (localTimeFormat (calendarFormat fe) (timeOfDayFormat fe)) durationTimeFormat
91 ]
92
93 testShowFormat :: String -> Format t -> String -> t -> TestTree
94 testShowFormat name fmt str t = nameTest (name ++ ": " ++ str) $
95 assertEqual "" (Just str) $ formatShowM fmt t
96
97 testShowFormats :: TestTree
98 testShowFormats = nameTest "show format"
99 [
100 testShowFormat "durationDaysFormat" durationDaysFormat "P0D" $ CalendarDiffDays 0 0,
101 testShowFormat "durationDaysFormat" durationDaysFormat "P4Y" $ CalendarDiffDays 48 0,
102 testShowFormat "durationDaysFormat" durationDaysFormat "P7M" $ CalendarDiffDays 7 0,
103 testShowFormat "durationDaysFormat" durationDaysFormat "P5D" $ CalendarDiffDays 0 5,
104 testShowFormat "durationDaysFormat" durationDaysFormat "P2Y3M81D" $ CalendarDiffDays 27 81,
105 testShowFormat "durationTimeFormat" durationTimeFormat "P0D" $ CalendarDiffTime 0 0,
106 testShowFormat "durationTimeFormat" durationTimeFormat "P4Y" $ CalendarDiffTime 48 0,
107 testShowFormat "durationTimeFormat" durationTimeFormat "P7M" $ CalendarDiffTime 7 0,
108 testShowFormat "durationTimeFormat" durationTimeFormat "P5D" $ CalendarDiffTime 0 $ 5 * nominalDay,
109 testShowFormat "durationTimeFormat" durationTimeFormat "P2Y3M81D" $ CalendarDiffTime 27 $ 81 * nominalDay,
110 testShowFormat "durationTimeFormat" durationTimeFormat "PT2H" $ CalendarDiffTime 0 $ 7200,
111 testShowFormat "durationTimeFormat" durationTimeFormat "PT3M" $ CalendarDiffTime 0 $ 180,
112 testShowFormat "durationTimeFormat" durationTimeFormat "PT12S" $ CalendarDiffTime 0 $ 12,
113 testShowFormat "durationTimeFormat" durationTimeFormat "PT1M18.77634S" $ CalendarDiffTime 0 $ 78.77634,
114 testShowFormat "durationTimeFormat" durationTimeFormat "PT2H1M18.77634S" $ CalendarDiffTime 0 $ 7278.77634,
115 testShowFormat "durationTimeFormat" durationTimeFormat "P5DT2H1M18.77634S" $ CalendarDiffTime 0 $ 5 * nominalDay + 7278.77634,
116 testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10M5DT2H1M18.77634S" $ CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634,
117 testShowFormat "durationTimeFormat" durationTimeFormat "P7Y10MT2H1M18.77634S" $ CalendarDiffTime 94 $ 7278.77634,
118 testShowFormat "durationTimeFormat" durationTimeFormat "P8YT2H1M18.77634S" $ CalendarDiffTime 96 $ 7278.77634,
119 testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0001-00-00" $ CalendarDiffDays 12 0,
120 testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0002-03-29" $ CalendarDiffDays 27 29,
121 testShowFormat "alternativeDurationDaysFormat" (alternativeDurationDaysFormat ExtendedFormat) "P0561-08-29" $ CalendarDiffDays (561 * 12 + 8) 29,
122 testShowFormat "alternativeDurationTimeFormat" (alternativeDurationTimeFormat ExtendedFormat) "P0000-00-01T00:00:00" $ CalendarDiffTime 0 86400,
123 testShowFormat "alternativeDurationTimeFormat" (alternativeDurationTimeFormat ExtendedFormat) "P0007-10-05T02:01:18.77634" $ CalendarDiffTime 94 $ 5 * nominalDay + 7278.77634,
124 testShowFormat "alternativeDurationTimeFormat" (alternativeDurationTimeFormat ExtendedFormat) "P4271-10-05T02:01:18.77634" $ CalendarDiffTime (12 * 4271 + 10) $ 5 * nominalDay + 7278.77634,
125 testShowFormat "centuryFormat" centuryFormat "02" 2,
126 testShowFormat "centuryFormat" centuryFormat "21" 21,
127 testShowFormat "intervalFormat etc."
128 (intervalFormat (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat)) durationTimeFormat)
129 "2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
130 (LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56),CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34),
131 testShowFormat "recurringIntervalFormat etc."
132 (recurringIntervalFormat (localTimeFormat (calendarFormat ExtendedFormat) (timeOfDayFormat ExtendedFormat)) durationTimeFormat)
133 "R74/2015-06-13T21:13:56/P1Y2M7DT5H33M2.34S"
134 (74,LocalTime (fromGregorian 2015 6 13) (TimeOfDay 21 13 56),CalendarDiffTime 14 $ 7 * nominalDay + 5 * 3600 + 33 * 60 + 2.34),
135 testShowFormat "recurringIntervalFormat etc."
136 (recurringIntervalFormat (calendarFormat ExtendedFormat) durationDaysFormat)
137 "R74/2015-06-13/P1Y2M7D"
138 (74,fromGregorian 2015 6 13,CalendarDiffDays 14 7),
139 testShowFormat "timeOffsetFormat"
140 iso8601Format
141 "-06:30"
142 (minutesToTimeZone (-390)),
143 testShowFormat "timeOffsetFormat"
144 iso8601Format
145 "+00:00"
146 (minutesToTimeZone 0),
147 testShowFormat "timeOffsetFormat"
148 (timeOffsetFormat BasicFormat)
149 "+0000"
150 (minutesToTimeZone 0),
151 testShowFormat "timeOffsetFormat"
152 iso8601Format
153 "+00:10"
154 (minutesToTimeZone 10),
155 testShowFormat "timeOffsetFormat"
156 iso8601Format
157 "-00:10"
158 (minutesToTimeZone (-10)),
159 testShowFormat "timeOffsetFormat"
160 iso8601Format
161 "+01:35"
162 (minutesToTimeZone 95),
163 testShowFormat "timeOffsetFormat"
164 iso8601Format
165 "-01:35"
166 (minutesToTimeZone (-95)),
167 testShowFormat "timeOffsetFormat"
168 (timeOffsetFormat BasicFormat)
169 "+0135"
170 (minutesToTimeZone 95),
171 testShowFormat "timeOffsetFormat"
172 (timeOffsetFormat BasicFormat)
173 "-0135"
174 (minutesToTimeZone (-95)),
175 testShowFormat "timeOffsetFormat"
176 (timeOffsetFormat BasicFormat)
177 "-1100"
178 (minutesToTimeZone $ negate $ 11 * 60),
179 testShowFormat "timeOffsetFormat"
180 (timeOffsetFormat BasicFormat)
181 "+1015"
182 (minutesToTimeZone $ 615),
183 testShowFormat "zonedTimeFormat"
184 iso8601Format
185 "2024-07-06T08:45:56.553-06:30"
186 (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone (-390))),
187 testShowFormat "zonedTimeFormat"
188 iso8601Format
189 "2024-07-06T08:45:56.553+06:30"
190 (ZonedTime (LocalTime (fromGregorian 2024 07 06) (TimeOfDay 8 45 56.553)) (minutesToTimeZone 390)),
191 testShowFormat "utcTimeFormat"
192 iso8601Format
193 "2024-07-06T08:45:56.553Z"
194 (UTCTime (fromGregorian 2024 07 06) (timeOfDayToTime $ TimeOfDay 8 45 56.553)),
195 testShowFormat "utcTimeFormat"
196 iso8601Format
197 "2028-12-31T23:59:60.9Z"
198 (UTCTime (fromGregorian 2028 12 31) (timeOfDayToTime $ TimeOfDay 23 59 60.9)),
199 testShowFormat "weekDateFormat"
200 (weekDateFormat ExtendedFormat)
201 "1994-W52-7"
202 (fromGregorian 1995 1 1),
203 testShowFormat "weekDateFormat"
204 (weekDateFormat ExtendedFormat)
205 "1995-W01-1"
206 (fromGregorian 1995 1 2),
207 testShowFormat "weekDateFormat"
208 (weekDateFormat ExtendedFormat)
209 "1996-W52-7"
210 (fromGregorian 1996 12 29),
211 testShowFormat "weekDateFormat"
212 (weekDateFormat ExtendedFormat)
213 "1997-W01-2"
214 (fromGregorian 1996 12 31),
215 testShowFormat "weekDateFormat"
216 (weekDateFormat ExtendedFormat)
217 "1997-W01-3"
218 (fromGregorian 1997 1 1),
219 testShowFormat "weekDateFormat"
220 (weekDateFormat ExtendedFormat)
221 "1974-W32-6"
222 (fromGregorian 1974 8 10),
223 testShowFormat "weekDateFormat"
224 (weekDateFormat BasicFormat)
225 "1974W326"
226 (fromGregorian 1974 8 10),
227 testShowFormat "weekDateFormat"
228 (weekDateFormat ExtendedFormat)
229 "1995-W05-6"
230 (fromGregorian 1995 2 4),
231 testShowFormat "weekDateFormat"
232 (weekDateFormat BasicFormat)
233 "1995W056"
234 (fromGregorian 1995 2 4),
235 testShowFormat "weekDateFormat"
236 (expandedWeekDateFormat 6 ExtendedFormat)
237 "+001995-W05-6"
238 (fromGregorian 1995 2 4),
239 testShowFormat "weekDateFormat"
240 (expandedWeekDateFormat 6 BasicFormat)
241 "+001995W056"
242 (fromGregorian 1995 2 4),
243 testShowFormat "ordinalDateFormat"
244 (ordinalDateFormat ExtendedFormat)
245 "1846-235"
246 (fromGregorian 1846 8 23),
247 testShowFormat "ordinalDateFormat"
248 (ordinalDateFormat BasicFormat)
249 "1844236"
250 (fromGregorian 1844 8 23),
251 testShowFormat "ordinalDateFormat"
252 (expandedOrdinalDateFormat 5 ExtendedFormat)
253 "+01846-235"
254 (fromGregorian 1846 8 23),
255 testShowFormat "hourMinuteFormat"
256 (hourMinuteFormat ExtendedFormat)
257 "13:17.25"
258 (TimeOfDay 13 17 15),
259 testShowFormat "hourMinuteFormat"
260 (hourMinuteFormat ExtendedFormat)
261 "01:12.4"
262 (TimeOfDay 1 12 24),
263 testShowFormat "hourMinuteFormat"
264 (hourMinuteFormat BasicFormat)
265 "1317.25"
266 (TimeOfDay 13 17 15),
267 testShowFormat "hourMinuteFormat"
268 (hourMinuteFormat BasicFormat)
269 "0112.4"
270 (TimeOfDay 1 12 24),
271 testShowFormat "hourFormat"
272 hourFormat
273 "22"
274 (TimeOfDay 22 0 0),
275 testShowFormat "hourFormat"
276 hourFormat
277 "06"
278 (TimeOfDay 6 0 0),
279 testShowFormat "hourFormat"
280 hourFormat
281 "18.9475"
282 (TimeOfDay 18 56 51)
283 ]
284
285 testISO8601 :: TestTree
286 testISO8601 = nameTest "ISO8601"
287 [
288 testShowFormats,
289 testReadShowFormat
290 ]