aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/world
diff options
context:
space:
mode:
authorEduardo Julian2022-07-06 17:11:35 -0400
committerEduardo Julian2022-07-06 17:11:35 -0400
commitf7880ce83ba82ada2d04a0c587448446e677d458 (patch)
tree0cdd43e40933906bae8c87681095284e4274d3c6 /stdlib/source/test/lux/world
parent5270f301eba5237feebc8eca14aee6b7a992a819 (diff)
Moved "lux/time" to "lux/world/time".
Diffstat (limited to 'stdlib/source/test/lux/world')
-rw-r--r--stdlib/source/test/lux/world/file.lux5
-rw-r--r--stdlib/source/test/lux/world/time.lux157
-rw-r--r--stdlib/source/test/lux/world/time/date.lux95
-rw-r--r--stdlib/source/test/lux/world/time/day.lux89
-rw-r--r--stdlib/source/test/lux/world/time/duration.lux100
-rw-r--r--stdlib/source/test/lux/world/time/instant.lux106
-rw-r--r--stdlib/source/test/lux/world/time/month.lux101
-rw-r--r--stdlib/source/test/lux/world/time/year.lux97
8 files changed, 748 insertions, 2 deletions
diff --git a/stdlib/source/test/lux/world/file.lux b/stdlib/source/test/lux/world/file.lux
index 5133e9c39..faebedb1f 100644
--- a/stdlib/source/test/lux/world/file.lux
+++ b/stdlib/source/test/lux/world/file.lux
@@ -22,8 +22,9 @@
[meta
[macro
["^" pattern]]]
- [time
- ["[0]" instant (.only Instant)]]]]
+ [world
+ [time
+ ["[0]" instant (.only Instant)]]]]]
["[0]" /
["[1][0]" watch]]
[\\library
diff --git a/stdlib/source/test/lux/world/time.lux b/stdlib/source/test/lux/world/time.lux
new file mode 100644
index 000000000..62c3ec43c
--- /dev/null
+++ b/stdlib/source/test/lux/world/time.lux
@@ -0,0 +1,157 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" pipe]
+ ["[0]" try (.use "[1]#[0]" functor)]
+ ["[0]" exception]]
+ [data
+ ["[0]" text (.only)
+ ["%" \\format (.only format)]
+ ["<[1]>" \\parser]]]
+ [math
+ ["[0]" random]
+ [number
+ ["n" nat]]]]]
+ ["[0]" /
+ ["[1][0]" date]
+ ["[1][0]" day]
+ ["[1][0]" duration]
+ ["[1][0]" instant]
+ ["[1][0]" month]
+ ["[1][0]" year]]
+ [\\library
+ ["[0]" / (.only)
+ ["[0]" duration]]])
+
+(def for_implementation
+ Test
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence random.time))
+ (_.for [/.order]
+ ($order.spec /.order random.time))
+ (_.for [/.enum]
+ ($enum.spec /.enum random.time))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec random.time))))
+
+(def for_clock
+ Test
+ (do [! random.monad]
+ [expected random.time]
+ (_.coverage [/.clock /.time]
+ (|> expected
+ /.clock
+ /.time
+ (try#each (at /.equivalence = expected))
+ (try.else false)))))
+
+(def for_ranges
+ Test
+ (do [! random.monad]
+ [valid_hour (at ! each (|>> (n.% /.hours) (n.max 10)) random.nat)
+ valid_minute (at ! each (|>> (n.% /.minutes) (n.max 10)) random.nat)
+ valid_second (at ! each (|>> (n.% /.seconds) (n.max 10)) random.nat)
+ valid_milli_second (at ! each (n.% /.milli_seconds) random.nat)
+
+ .let [invalid_hour (|> valid_hour (n.+ /.hours))
+ invalid_minute (|> valid_minute (n.+ /.minutes) (n.min 99))
+ invalid_second (|> valid_second (n.+ /.seconds) (n.min 99))]]
+ (`` (all _.and
+ (,, (with_template [<cap> <exception> <prefix> <suffix> <valid> <invalid>]
+ [(_.coverage [<cap> <exception>]
+ (let [valid!
+ (|> <valid>
+ %.nat
+ (text.prefix <prefix>)
+ (text.suffix <suffix>)
+ (at /.codec decoded)
+ (pipe.case
+ {try.#Success _} true
+ {try.#Failure error} false))
+
+ invalid!
+ (|> <invalid>
+ %.nat
+ (text.prefix <prefix>)
+ (text.suffix <suffix>)
+ (at /.codec decoded)
+ (pipe.case
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? <exception> error)))]
+ (and valid!
+ invalid!)))]
+
+ [/.hours /.invalid_hour "" ":00:00.000" valid_hour invalid_hour]
+ [/.minutes /.invalid_minute "00:" ":00.000" valid_minute invalid_minute]
+ [/.seconds /.invalid_second "00:00:" ".000" valid_second invalid_second]
+ ))
+ (_.coverage [/.milli_seconds]
+ (|> valid_milli_second
+ %.nat
+ (format "00:00:00.")
+ (at /.codec decoded)
+ (pipe.case
+ {try.#Success _} true
+ {try.#Failure error} false)))
+ ))))
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Time])
+ (do [! random.monad]
+ [.let [day (.nat (duration.millis duration.day))]
+ expected random.time
+
+ out_of_bounds (at ! each (|>> /.millis (n.+ day))
+ random.time)]
+ (`` (all _.and
+ ..for_implementation
+
+ (_.coverage [/.millis /.of_millis]
+ (|> expected
+ /.millis
+ /.of_millis
+ (try#each (at /.equivalence = expected))
+ (try.else false)))
+ (_.coverage [/.time_exceeds_a_day]
+ (case (/.of_millis out_of_bounds)
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? /.time_exceeds_a_day error)))
+ (_.coverage [/.midnight]
+ (|> /.midnight
+ /.millis
+ (n.= 0)))
+ (_.coverage [/.parser]
+ (|> expected
+ (at /.codec encoded)
+ (<text>.result /.parser)
+ (try#each (at /.equivalence = expected))
+ (try.else false)))
+ ..for_ranges
+ (_.for [/.Clock]
+ ..for_clock)
+
+ /date.test
+ /day.test
+ /duration.test
+ /instant.test
+ /month.test
+ /year.test
+ )))))
diff --git a/stdlib/source/test/lux/world/time/date.lux b/stdlib/source/test/lux/world/time/date.lux
new file mode 100644
index 000000000..c97fd626e
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/date.lux
@@ -0,0 +1,95 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" try (.use "[1]#[0]" functor)]
+ ["[0]" exception]]
+ [data
+ ["[0]" text
+ ["%" \\format (.only format)]
+ ["<[1]>" \\parser]]]
+ [math
+ ["[0]" random (.only Random)]
+ [number
+ ["n" nat]
+ ["i" int]]]]]
+ [\\library
+ ["[0]" /]])
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Date])
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence random.date))
+ (_.for [/.order]
+ ($order.spec /.order random.date))
+ (_.for [/.enum]
+ ($enum.spec /.enum random.date))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec random.date))
+
+ (do random.monad
+ [expected random.date]
+ (_.coverage [/.date /.year /.month /.day_of_month]
+ (|> (/.date (/.year expected)
+ (/.month expected)
+ (/.day_of_month expected))
+ (try#each (at /.equivalence = expected))
+ (try.else false))))
+ (do random.monad
+ [expected random.date]
+ (_.coverage [/.invalid_day]
+ (case (/.date (/.year expected)
+ (/.month expected)
+ (n.+ 31 (/.day_of_month expected)))
+ {try.#Failure error}
+ (exception.match? /.invalid_day error)
+
+ {try.#Success _}
+ false)))
+ (do random.monad
+ [expected random.date]
+ (_.coverage [/.days /.of_days]
+ (|> expected
+ /.days
+ /.of_days
+ (at /.equivalence = expected))))
+ (_.coverage [/.epoch]
+ (|> /.epoch
+ /.days
+ (i.= +0)))
+ (do random.monad
+ [expected random.date]
+ (_.coverage [/.parser]
+ (|> (at /.codec encoded expected)
+ (<text>.result /.parser)
+ (try#each (at /.equivalence = expected))
+ (try.else false))))
+ (do [! random.monad]
+ [year (at ! each (|>> (n.% 10,000) ++)
+ random.nat)
+ month (at ! each (|>> (n.% 10) (n.+ 13))
+ random.nat)
+ day (at ! each (|>> (n.% 10) (n.+ 10))
+ random.nat)
+ .let [input (format (%.nat year)
+ "-" (%.nat month)
+ "-" (%.nat day))]]
+ (_.coverage [/.invalid_month]
+ (case (<text>.result /.parser input)
+ {try.#Failure error}
+ (exception.match? /.invalid_month error)
+
+ {try.#Success _}
+ false)))
+ )))
diff --git a/stdlib/source/test/lux/world/time/day.lux b/stdlib/source/test/lux/world/time/day.lux
new file mode 100644
index 000000000..eecc8a0fb
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/day.lux
@@ -0,0 +1,89 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" hash]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" try (.use "[1]#[0]" functor)]
+ ["[0]" exception]
+ [function
+ ["[0]" predicate]]]
+ [data
+ [collection
+ ["[0]" list]
+ ["[0]" set]]]
+ [math
+ ["[0]" random (.only Random) (.use "[1]#[0]" monad)]
+ [number
+ ["n" nat]]]]]
+ [\\library
+ ["[0]" /]])
+
+(def .public random
+ (Random /.Day)
+ (random.either (random.either (random.either (random#in {/.#Sunday})
+ (random#in {/.#Monday}))
+ (random.either (random#in {/.#Tuesday})
+ (random#in {/.#Wednesday})))
+ (random.either (random.either (random#in {/.#Thursday})
+ (random#in {/.#Friday}))
+ (random#in {/.#Saturday}))))
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Day])
+ (do random.monad
+ [expected ..random
+ invalid (random.only (predicate.or (n.< (/.number {/.#Sunday}))
+ (n.> (/.number {/.#Saturday})))
+ random.nat)]
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence ..random))
+ (_.for [/.hash]
+ ($hash.spec /.hash ..random))
+ (_.for [/.order]
+ ($order.spec /.order ..random))
+ (_.for [/.enum]
+ ($enum.spec /.enum ..random))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec ..random))
+
+ (do random.monad
+ [not_a_day (random.upper_case 1)]
+ (_.coverage [/.not_a_day_of_the_week]
+ (case (at /.codec decoded not_a_day)
+ {try.#Failure error}
+ (exception.match? /.not_a_day_of_the_week error)
+
+ {try.#Success _}
+ false)))
+ (_.coverage [/.number /.by_number]
+ (|> expected
+ /.number
+ /.by_number
+ (try#each (at /.equivalence = expected))
+ (try.else false)))
+ (_.coverage [/.invalid_day]
+ (case (/.by_number invalid)
+ {try.#Failure error}
+ (exception.match? /.invalid_day error)
+
+ {try.#Success _}
+ false))
+ (_.coverage [/.week]
+ (let [all (list.size /.week)
+ uniques (set.size (set.of_list /.hash /.week))]
+ (and (n.= (/.number {/.#Saturday})
+ all)
+ (n.= all
+ uniques))))
+ ))))
diff --git a/stdlib/source/test/lux/world/time/duration.lux b/stdlib/source/test/lux/world/time/duration.lux
new file mode 100644
index 000000000..e73108548
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/duration.lux
@@ -0,0 +1,100 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" monoid]
+ ["$[0]" codec]]]
+ [data
+ ["[0]" bit (.use "[1]#[0]" equivalence)]]
+ [math
+ ["[0]" random (.only Random)]
+ [number
+ ["n" nat]
+ ["i" int]]]]]
+ [\\library
+ ["[0]" /]])
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Duration])
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence random.duration))
+ (_.for [/.order]
+ ($order.spec /.order random.duration))
+ (_.for [/.enum]
+ ($enum.spec /.enum random.duration))
+ (_.for [/.monoid]
+ ($monoid.spec /.equivalence /.monoid random.duration))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec random.duration))
+
+ (do random.monad
+ [duration random.duration]
+ (_.coverage [/.of_millis /.millis]
+ (|> duration /.millis /.of_millis (at /.equivalence = duration))))
+ (do random.monad
+ [.let [(open "#[0]") /.equivalence]
+ expected random.duration
+ parameter random.duration]
+ (all _.and
+ (_.coverage [/.composite /.difference]
+ (|> expected (/.composite parameter) (/.difference parameter) (#= expected)))
+ (_.coverage [/.empty]
+ (|> expected (/.composite /.empty) (#= expected)))
+ (_.coverage [/.inverse]
+ (and (|> expected /.inverse /.inverse (#= expected))
+ (|> expected (/.composite (/.inverse expected)) (#= /.empty))))
+ (_.coverage [/.positive? /.negative? /.neutral?]
+ (or (bit#= (/.positive? expected)
+ (/.negative? (/.inverse expected)))
+ (bit#= (/.neutral? expected)
+ (/.neutral? (/.inverse expected)))))
+ ))
+ (do random.monad
+ [.let [(open "#[0]") /.equivalence]
+ factor random.nat]
+ (_.coverage [/.up /.down]
+ (|> /.milli_second (/.up factor) (/.down factor) (#= /.milli_second))))
+ (do [! random.monad]
+ [.let [(open "#[0]") /.order
+ positive (|> random.duration
+ (random.only (|>> (#= /.empty) not))
+ (at ! each (function (_ duration)
+ (if (/.positive? duration)
+ duration
+ (/.inverse duration)))))]
+ sample positive
+ frame positive]
+ (`` (all _.and
+ (_.coverage [/.framed]
+ (let [sample' (/.framed frame sample)]
+ (and (#< frame sample')
+ (bit#= (#< frame sample)
+ (#= sample sample')))))
+ (_.coverage [/.ticks]
+ (i.= +1 (/.ticks sample sample)))
+ (_.coverage [/.milli_second]
+ (#= /.empty (at /.enum pred /.milli_second)))
+ (,, (with_template [<factor> <big> <small>]
+ [(_.coverage [<big>]
+ (|> <big> (/.ticks <small>) (i.= <factor>)))]
+
+ [+1,000 /.second /.milli_second]
+ [+60 /.minute /.second]
+ [+60 /.hour /.minute]
+ [+24 /.day /.hour]
+
+ [+7 /.week /.day]
+ [+365 /.normal_year /.day]
+ [+366 /.leap_year /.day]
+ ))
+ )))
+ )))
diff --git a/stdlib/source/test/lux/world/time/instant.lux b/stdlib/source/test/lux/world/time/instant.lux
new file mode 100644
index 000000000..56a4749ec
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/instant.lux
@@ -0,0 +1,106 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" function]
+ ["[0]" try]
+ ["[0]" io]]
+ [data
+ [collection
+ ["[0]" list (.use "[1]#[0]" mix)]]]
+ [math
+ ["[0]" random]]]]
+ [\\library
+ ["[0]" / (.only)
+ [//
+ ["[0]" duration (.only Duration)]
+ ["[0]" day (.only Day) (.use "[1]#[0]" enum)]]]])
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Instant])
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence random.instant))
+ (_.for [/.order]
+ ($order.spec /.order random.instant))
+ (_.for [/.enum]
+ ($enum.spec /.enum random.instant))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec random.instant))
+
+ (do random.monad
+ [.let [(open "#[0]") /.equivalence]
+ expected random.instant]
+ (all _.and
+ (_.coverage [/.millis /.of_millis]
+ (|> expected /.millis /.of_millis (#= expected)))
+ (_.coverage [/.relative /.absolute]
+ (|> expected /.relative /.absolute (#= expected)))
+ (_.coverage [/.date /.time /.of_date_time]
+ (#= expected
+ (/.of_date_time (/.date expected)
+ (/.time expected))))
+ ))
+ (do random.monad
+ [.let [(open "#[0]") /.equivalence
+ (open "duration#[0]") duration.equivalence]
+ from random.instant
+ to random.instant]
+ (all _.and
+ (_.coverage [/.span]
+ (|> from (/.span from) (duration#= duration.empty)))
+ (_.coverage [/.after]
+ (|> from (/.after (/.span from to)) (#= to)))
+ (_.coverage [/.epoch]
+ (duration#= (/.relative to)
+ (/.span /.epoch to)))
+ ))
+ (do random.monad
+ [instant random.instant
+ .let [d0 (/.day_of_week instant)]]
+ (_.coverage [/.day_of_week]
+ (let [apply (is (-> (-> Duration Duration) (-> Day Day) Nat Bit)
+ (function (_ polarity move steps)
+ (let [day_shift (list#mix (function.constant move)
+ d0
+ (list.repeated steps []))
+ instant_shift (|> instant
+ (/.after (polarity (duration.up steps duration.day)))
+ /.day_of_week)]
+ (day#= day_shift
+ instant_shift))))]
+ (and (apply function.identity day#succ 0)
+ (apply function.identity day#succ 1)
+ (apply function.identity day#succ 2)
+ (apply function.identity day#succ 3)
+ (apply function.identity day#succ 4)
+ (apply function.identity day#succ 5)
+ (apply function.identity day#succ 6)
+ (apply function.identity day#succ 7)
+
+ (apply duration.inverse day#pred 0)
+ (apply duration.inverse day#pred 1)
+ (apply duration.inverse day#pred 2)
+ (apply duration.inverse day#pred 3)
+ (apply duration.inverse day#pred 4)
+ (apply duration.inverse day#pred 5)
+ (apply duration.inverse day#pred 6)
+ (apply duration.inverse day#pred 7)))))
+ (_.coverage [/.now]
+ (case (try (io.run! /.now))
+ {try.#Success _}
+ true
+
+ {try.#Failure _}
+ false))
+ )))
diff --git a/stdlib/source/test/lux/world/time/month.lux b/stdlib/source/test/lux/world/time/month.lux
new file mode 100644
index 000000000..c87a956cd
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/month.lux
@@ -0,0 +1,101 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" hash]
+ ["$[0]" order]
+ ["$[0]" enum]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" try (.use "[1]#[0]" functor)]
+ ["[0]" exception]
+ [function
+ ["[0]" predicate]]]
+ [data
+ [collection
+ ["[0]" set]
+ ["[0]" list (.use "[1]#[0]" functor mix)]]]
+ [math
+ ["[0]" random (.only Random)]
+ [number
+ ["n" nat]]]]]
+ [\\library
+ ["[0]" / (.only)
+ [//
+ ["[0]" duration]]]])
+
+(def .public random
+ (Random /.Month)
+ (let [december (/.number {/.#December})]
+ (|> random.nat
+ (at random.monad each (|>> (n.% december) ++))
+ (random.one (|>> /.by_number try.maybe)))))
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Month])
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence ..random))
+ (_.for [/.hash]
+ ($hash.spec /.hash ..random))
+ (_.for [/.order]
+ ($order.spec /.order ..random))
+ (_.for [/.enum]
+ ($enum.spec /.enum ..random))
+ (_.for [/.codec]
+ ($codec.spec /.equivalence /.codec ..random))
+
+ (do random.monad
+ [expected ..random
+ invalid (random.only (predicate.or (n.< (/.number {/.#January}))
+ (n.> (/.number {/.#December})))
+ random.nat)]
+ (all _.and
+ (_.coverage [/.number /.by_number]
+ (|> expected
+ /.number
+ /.by_number
+ (try#each (at /.equivalence = expected))
+ (try.else false)))
+ (_.coverage [/.invalid_month]
+ (case (/.by_number invalid)
+ {try.#Failure error}
+ (exception.match? /.invalid_month error)
+
+ {try.#Success _}
+ false))
+ (_.coverage [/.year]
+ (let [all (list.size /.year)
+ uniques (set.size (set.of_list /.hash /.year))]
+ (and (n.= (/.number {/.#December})
+ all)
+ (n.= all
+ uniques))))
+ (_.coverage [/.days]
+ (let [expected (.nat (duration.ticks duration.day duration.normal_year))]
+ (|> /.year
+ (list#each /.days)
+ (list#mix n.+ 0)
+ (n.= expected))))
+ (_.coverage [/.leap_year_days]
+ (let [expected (.nat (duration.ticks duration.day duration.leap_year))]
+ (|> /.year
+ (list#each /.leap_year_days)
+ (list#mix n.+ 0)
+ (n.= expected))))
+ (do random.monad
+ [not_a_month (random.upper_case 1)]
+ (_.coverage [/.not_a_month_of_the_year]
+ (case (at /.codec decoded not_a_month)
+ {try.#Failure error}
+ (exception.match? /.not_a_month_of_the_year error)
+
+ {try.#Success _}
+ false)))
+ )))))
diff --git a/stdlib/source/test/lux/world/time/year.lux b/stdlib/source/test/lux/world/time/year.lux
new file mode 100644
index 000000000..0e0dee518
--- /dev/null
+++ b/stdlib/source/test/lux/world/time/year.lux
@@ -0,0 +1,97 @@
+(.require
+ [library
+ [lux (.except)
+ ["_" test (.only Test)]
+ [abstract
+ [monad (.only do)]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" order]
+ ["$[0]" codec]]]
+ [control
+ ["[0]" try]
+ ["[0]" exception]]
+ [data
+ ["[0]" bit (.use "[1]#[0]" equivalence)]
+ [text
+ ["%" \\format (.only format)]]]
+ [math
+ ["[0]" random (.only Random)]
+ [number
+ ["n" nat]
+ ["i" int]]]]]
+ [\\library
+ ["[0]" / (.only)
+ ["/[1]" // (.only)
+ ["[1][0]" duration]
+ ["[1][0]" instant]
+ ["[1][0]" date]]]])
+
+(def .public random
+ (Random /.Year)
+ (random.one (|>> /.year try.maybe) random.int))
+
+(def .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Year])
+ (all _.and
+ (_.for [/.equivalence]
+ ($equivalence.spec /.equivalence ..random))
+ (_.for [/.order]
+ ($order.spec /.order ..random))
+ (_.for [/.codec /.parser]
+ ($codec.spec /.equivalence /.codec ..random))
+
+ (do random.monad
+ [expected random.int]
+ (all _.and
+ (_.coverage [/.year]
+ (bit#= (i.= +0 expected)
+ (case (/.year expected)
+ {try.#Success _}
+ false
+
+ {try.#Failure _}
+ true)))
+ (_.coverage [/.value]
+ (case (/.year expected)
+ {try.#Success year}
+ (i.= expected (/.value year))
+
+ {try.#Failure _}
+ (i.= +0 expected)))
+ ))
+ (_.coverage [/.there_is_no_year_0]
+ (case (/.year +0)
+ {try.#Success _}
+ false
+
+ {try.#Failure error}
+ (exception.match? /.there_is_no_year_0 error)))
+ (_.coverage [/.days]
+ (n.= (.nat (//duration.ticks //duration.day //duration.normal_year))
+ /.days))
+ (_.coverage [/.epoch]
+ (at /.equivalence =
+ (//date.year (//instant.date //instant.epoch))
+ /.epoch))
+ (_.for [/.Period]
+ (_.coverage [/.leap /.century /.era]
+ (n.= /.leap (n./ /.century /.era))))
+ (let [leap (try.trusted (/.year (.int /.leap)))
+ century (try.trusted (/.year (.int /.century)))
+ era (try.trusted (/.year (.int /.era)))]
+ (all _.and
+ (_.coverage [/.leap?]
+ (and (/.leap? leap)
+ (not (/.leap? century))
+ (/.leap? era)))
+ (_.coverage [/.leaps]
+ (and (i.= +1 (/.leaps leap))
+ (i.= (.int (n./ /.leap /.century))
+ (/.leaps century))
+ (i.= (++ (i.* +4 (-- (/.leaps century))))
+ (/.leaps era))))
+ ))
+ )))