(.require [library [lux (.except) [abstract [monad (.only do)] [\\specification ["$[0]" equivalence]]] [control ["[0]" try (.use "[1]#[0]" functor)] ["[0]" exception]] [data ["[0]" text ["<[1]>" \\parser]]] [math ["[0]" random (.only Random)] [number ["n" nat] ["i" int]]] [world [time ["[0]" date (.use "[1]#[0]" equivalence)] ["[0]" year]]] [test ["_" property (.only Test)]]]] [\\program ["[0]" /]]) (def .public random (Random /.Date) (random.one (function (_ raw) (try.maybe (do try.monad [year (|> raw date.year year.value i.abs (i.% +9,000) (i.+ +1,000) year.year) raw (date.date year (date.month raw) (date.day_of_month raw))] (/.date raw)))) random.date)) (def .public test Test (<| (_.covering /._) (_.for [/.Date]) (do random.monad [expected ..random candidate random.date] (all _.and (_.for [/.equivalence] ($equivalence.spec /.equivalence ..random)) (_.coverage [/.format /.parser] (|> expected /.format (.result /.parser) (try#each (of /.equivalence = expected)) (try.else false))) (_.coverage [/.value /.date] (|> expected /.value /.date (try#each (of /.equivalence = expected)) (try.else false))) (_.coverage [/.year_is_out_of_range] (when (/.date candidate) {try.#Success date} (same? candidate (/.value date)) {try.#Failure error} (exception.match? /.year_is_out_of_range error))) (_.coverage [/.epoch] (date#= date.epoch (/.value /.epoch))) ))))