@@ -23,77 +23,130 @@ namespace UnitTest.Datetime
2323
2424open Cedar.Spec.Ext.Datetime
2525
26- theorem test1 : toString ((Duration.parse "1ms" ).get!) = "1" := by native_decide
27- theorem test2 : toString ((Duration.parse "1s" ).get!) = "1000" := by native_decide
28- theorem test3 : toString ((Duration.parse "1m" ).get!) = "60000" := by native_decide
29- theorem test4 : toString ((Duration.parse "1h" ).get!) = "360000" := by native_decide
30- theorem test5 : toString ((Duration.parse "1d" ).get!) = "86400000" := by native_decide
31- theorem test6 : toString ((Duration.parse "1d2h3m4s5ms" ).get!) = "87304005" := by native_decide
32- theorem test7 : toString ((Duration.parse "2d12h" ).get!) = "177120000" := by native_decide
33- theorem test8 : toString ((Duration.parse "3m30s" ).get!) = "210000" := by native_decide
34- theorem test9 : toString ((Duration.parse "1h30m45s" ).get!) = "2205000" := by native_decide
35- theorem test10 : toString ((Duration.parse "2d5h20m" ).get!) = "175800000" := by native_decide
36- theorem test11 : toString ((Duration.parse "-1d12h" ).get!) = "-90720000" := by native_decide
37- theorem test12 : toString ((Duration.parse "-3h45m" ).get!) = "-3780000" := by native_decide
38- theorem test13 : toString ((Duration.parse "1d1ms" ).get!) = "86400001" := by native_decide
39- theorem test14 : toString ((Duration.parse "59m59s999ms" ).get!) = "3599999" := by native_decide
40- theorem test15 : toString ((Duration.parse "23h59m59s999ms" ).get!) = "11879999" := by native_decide
41- theorem test16 : toString ((Duration.parse "0d0h0m0s0ms" ).get!) = "0" := by native_decide
42-
43- private def testValid (str : String) (rep : Int) : TestCase IO :=
26+ private def testValidDatetime (str : String) (rep : Int) : TestCase IO :=
27+ test str ⟨λ _ => checkEq (parse str) (datetime? rep)⟩
28+
29+ def testsForValidDatetimeStrings :=
30+ suite "Datetime.parse for valid strings"
31+ [
32+ testValidDatetime "2022-10-10" 1665360000000 ,
33+ testValidDatetime "1969-12-31" (-86400000 : Int),
34+ testValidDatetime "1969-12-31T23:59:59Z" (-1000 : Int),
35+ -- Commented out tests following this comment are impacted by a bug we
36+ -- encountered in Lean. Enable them when the bug has been fixed. More
37+ -- details in https://github.com/cedar-policy/cedar-spec/issues/525
38+ -- testValidDatetime "1969-12-31T23:59:59.001Z" (-999 : Int),
39+ -- testValidDatetime "1969-12-31T23:59:59.999Z" (-1 : Int),
40+ testValidDatetime "2024-10-15" 1728950400000 ,
41+ testValidDatetime "2024-10-15T11:38:02Z" 1728992282000 ,
42+ testValidDatetime "2024-10-15T11:38:02.101Z" 1728992282101 ,
43+ testValidDatetime "2024-10-15T11:38:02.101-1134" 1729033922101 ,
44+ testValidDatetime "2024-10-15T11:38:02.101+1134" 1728950642101 ,
45+ testValidDatetime "2024-10-15T11:38:02+1134" 1728950642000 ,
46+ testValidDatetime "2024-10-15T11:38:02-1134" 1729033922000 ,
47+ ]
48+
49+ private def testInvalidDatetime (str : String) (msg : String) : TestCase IO :=
50+ test s! "{ str} [{ msg} ]" ⟨λ _ => checkEq (parse str) .none⟩
51+
52+ def testsForInvalidDatetimeStrings :=
53+ suite "Datetime.parse for invalid strings"
54+ [
55+ testInvalidDatetime "" "empty string" ,
56+ testInvalidDatetime "a" "string is letter" ,
57+ testInvalidDatetime "-" "string is character" ,
58+ testInvalidDatetime "-1" "string is integer" ,
59+ testInvalidDatetime "11-12-13" "two digits for year" ,
60+ testInvalidDatetime "1111-1x-20" "invalid month" ,
61+ testInvalidDatetime "2024-10-15Z" "Zulu code invalid for date" ,
62+ testInvalidDatetime "2024-10-15T11:38:02ZZ" "double Zulu code" ,
63+ testInvalidDatetime "2024-01-01T" "separator not needed" ,
64+ testInvalidDatetime "2024-01-01Ta" "unexpected character 'a'" ,
65+ testInvalidDatetime "2024-01-01T01:" "only hours" ,
66+ testInvalidDatetime "2024-01-01T01:02" "no seconds" ,
67+ testInvalidDatetime "2024-01-01T01:02:0b" "unexpected character 'b'" ,
68+ testInvalidDatetime "2024-01-01T01::02:03" "double colon" ,
69+ testInvalidDatetime "2024-01-01T01::02::03" "double colons" ,
70+ testInvalidDatetime "2024-01-01T31:02:03Z" "invalid hour range" ,
71+ testInvalidDatetime "2024-01-01T01:60:03Z" "invalid minute range" ,
72+ testInvalidDatetime "2016-12-31T23:59:60Z" "leap second" ,
73+ testInvalidDatetime "2016-12-31T23:59:61Z" "invalid second range" ,
74+ testInvalidDatetime "2024-01-01T00:00:00" "timezone not specified" ,
75+ testInvalidDatetime "2024-01-01T00:00:00T" "separator is not timezone" ,
76+ testInvalidDatetime "2024-01-01T00:00:00ZZ" "double Zulu code" ,
77+ testInvalidDatetime "2024-01-01T00:00:00x001Z" "typo in milliseconds separator" ,
78+ testInvalidDatetime "2024-01-01T00:00:00.001ZZ" "double Zulu code w/ millis" ,
79+ testInvalidDatetime "2016-12-31T23:59:60.000Z" "leap second (millis/UTC)" ,
80+ testInvalidDatetime "2016-12-31T23:59:60.000+0200" "leap second (millis/offset)" ,
81+ testInvalidDatetime "2024-01-01T00:00:00➕0000" "sign `+` is an emoji" ,
82+ testInvalidDatetime "2024-01-01T00:00:00➖0000" "sign `-` is an emoji" ,
83+ testInvalidDatetime "2024-01-01T00:00:00.0001Z" "fraction of seconds is 4 digits" ,
84+ testInvalidDatetime "2024-01-01T00:00:00.001➖0000" "sign `+` is an emoji" ,
85+ testInvalidDatetime "2024-01-01T00:00:00.001➕0000" "sign `-` is an emoji" ,
86+ testInvalidDatetime "2024-01-01T00:00:00.001+00000" "offset is 5 digits" ,
87+ testInvalidDatetime "2024-01-01T00:00:00.001-00000" "offset is 5 digits" ,
88+ testInvalidDatetime "2016-12-31T00:00:00+2400" "invalid offset range" ,
89+ testInvalidDatetime "2016-12-31T00:00:00+9999" "invalid offset range" ,
90+ ]
91+
92+ theorem testDuration16 : toString ((Duration.parse "0d0h0m0s0ms" ).get!) = "0" := by native_decide
93+
94+ private def testValidDuration (str : String) (rep : Int) : TestCase IO :=
4495 test str ⟨λ _ => checkEq (Duration.parse str) (duration? rep)⟩
4596
4697def testsForValidDurationStrings :=
4798 suite "Duration.parse for valid strings"
4899 [
49- testValid "0ms" 0 ,
50- testValid "0d0s" 0 ,
51- testValid "1ms" 1 ,
52- testValid "1s" 1000 ,
53- testValid "1m" 60000 ,
54- testValid "1h" 360000 ,
55- testValid "1d" 86400000 ,
56- testValid "12s340ms" 12340 ,
57- testValid "1s234ms" 1234 ,
58- testValid "-1s" (-1000 ),
59- testValid "-4s200ms" (-4200 ),
60- testValid "-9s876ms" (-9876 ),
61- testValid "106751d23h47m16s854ms" 9223297516854 ,
62- testValid "-106751d23h47m16s854ms" (-9223297516854 ),
63- testValid "1d2h3m4s5ms" 87304005 ,
64- testValid "2d12h" 177120000 ,
65- testValid "3m30s" 210000 ,
66- testValid "1h30m45s" 2205000 ,
67- testValid "2d5h20m" 175800000 ,
68- testValid "-1d12h" (-90720000 ),
69- testValid "-3h45m" (-3780000 ),
70- testValid "1d1ms" 86400001 ,
71- testValid "59m59s999ms" 3599999 ,
72- testValid "23h59m59s999ms" 11879999
100+ testValidDuration "0ms" 0 ,
101+ testValidDuration "0d0s" 0 ,
102+ testValidDuration "1ms" 1 ,
103+ testValidDuration "1s" 1000 ,
104+ testValidDuration "1m" 60000 ,
105+ testValidDuration "1h" 360000 ,
106+ testValidDuration "1d" 86400000 ,
107+ testValidDuration "12s340ms" 12340 ,
108+ testValidDuration "1s234ms" 1234 ,
109+ testValidDuration "-1s" (-1000 ),
110+ testValidDuration "-4s200ms" (-4200 ),
111+ testValidDuration "-9s876ms" (-9876 ),
112+ testValidDuration "106751d23h47m16s854ms" 9223297516854 ,
113+ testValidDuration "-106751d23h47m16s854ms" (-9223297516854 ),
114+ testValidDuration "1d2h3m4s5ms" 87304005 ,
115+ testValidDuration "2d12h" 177120000 ,
116+ testValidDuration "3m30s" 210000 ,
117+ testValidDuration "1h30m45s" 2205000 ,
118+ testValidDuration "2d5h20m" 175800000 ,
119+ testValidDuration "-1d12h" (-90720000 ),
120+ testValidDuration "-3h45m" (-3780000 ),
121+ testValidDuration "1d1ms" 86400001 ,
122+ testValidDuration "59m59s999ms" 3599999 ,
123+ testValidDuration "23h59m59s999ms" 11879999 ,
124+ testValidDuration "0d0h0m0s0ms" 0
73125 ]
74126
75- private def testInvalid (str : String) (msg : String) : TestCase IO :=
127+ private def testInvalidDuration (str : String) (msg : String) : TestCase IO :=
76128 test s! "{ str} [{ msg} ]" ⟨λ _ => checkEq (Duration.parse str) .none⟩
77129
78130def testsForInvalidDurationStrings :=
79131 suite "Duration.parse for invalid strings"
80132 [
81- testInvalid "" "empty string" ,
82- testInvalid "d" "unit but no amount" ,
83- testInvalid "1d-1s" "invalid use of -" ,
84- testInvalid "1d2h3m4s5ms6" "trailing amount" ,
85- testInvalid "1x2m3s" "invalid unit" ,
86- testInvalid "1.23s" "amounts must be integral" ,
87- testInvalid "1s1d" "invalid order" ,
88- testInvalid "1s1s" "repeated units" ,
89- testInvalid "1d2h3m4s5ms " "trailing space" ,
90- testInvalid " 1d2h3m4s5ms" "leading space" ,
91- testInvalid "1d9223372036854775807ms" "overflow" ,
92- testInvalid "1d92233720368547758071ms" "overflow ms" ,
93- testInvalid "9223372036854776s1ms" "overflow s"
133+ testInvalidDuration "" "empty string" ,
134+ testInvalidDuration "d" "unit but no amount" ,
135+ testInvalidDuration "1d-1s" "invalid use of -" ,
136+ testInvalidDuration "1d2h3m4s5ms6" "trailing amount" ,
137+ testInvalidDuration "1x2m3s" "invalid unit" ,
138+ testInvalidDuration "1.23s" "amounts must be integral" ,
139+ testInvalidDuration "1s1d" "invalid order" ,
140+ testInvalidDuration "1s1s" "repeated units" ,
141+ testInvalidDuration "1d2h3m4s5ms " "trailing space" ,
142+ testInvalidDuration " 1d2h3m4s5ms" "leading space" ,
143+ testInvalidDuration "1d9223372036854775807ms" "overflow" ,
144+ testInvalidDuration "1d92233720368547758071ms" "overflow ms" ,
145+ testInvalidDuration "9223372036854776s1ms" "overflow s"
94146 ]
95147
96- def tests := [testsForValidDurationStrings, testsForInvalidDurationStrings]
148+ def tests := [testsForValidDatetimeStrings, testsForInvalidDatetimeStrings,
149+ testsForValidDurationStrings, testsForInvalidDurationStrings]
97150
98151-- Uncomment for interactive debugging
99152-- #eval TestSuite.runAll tests
0 commit comments