(.require [library [lux (.except) [abstract [monad (.only do)] [\\specification ["[0]S" equivalence] ["[0]S" mix] ["[0]S" functor (.only Injection)]]] [control ["|" pipe] ["[0]" try (.use "[1]#[0]" functor)] ["[0]" exception]] [data ["[0]" product] [collection ["[0]" list (.use "[1]#[0]" functor mix)] ["[0]" set]]] [math ["[0]" random (.only Random) (.use "[1]#[0]" functor)] [number ["n" nat] ["i" int]]] [world [time ["[0]" instant (.only Instant) (.use "[1]#[0]" order)] ["[0]" duration]]] [test ["_" property (.only Test)]]]] [\\library ["[0]" /]]) (def .public (event it) (All (_ of) (-> (Random of) (Random (/.Event of)))) (do random.monad [when random.instant what it] (in [/.#when when /.#what what]))) (def .public (random size it) (All (_ of) (-> Nat (Random of) (Random (/.Series of)))) (|> it (random.list size) (random#each (|>> (list#mix (function (_ what [when events]) [(instant.before duration.milli_second when) (list.partial [/.#when when /.#what what] events)]) [instant.latest (list)]) product.right)) (random.one (|>> /.series try.maybe)))) (def (injection when) (-> Instant (Injection /.Series)) (|>> [/.#when when /.#what] list /.series try.trusted)) (def .public test Test (<| (_.covering /._) (do [! random.monad] [before (..event random.nat) after (random.only (|>> (the /.#when) (instant#= (the /.#when before)) not) (..event random.nat)) .let [[before after] (if (instant#< (the /.#when after) (the /.#when before)) [before after] [after before])] expected_instant random.instant expected_size (of ! each (n.% 10) random.nat) events (is (Random (List (/.Event Int))) (|> random.int (random.set i.hash expected_size) (of ! each (|>> set.list (list.sorted i.<) (list#each (function (_ it) [/.#when (instant.of_millis it) /.#what it]))))))]) (all _.and (<| (_.for [/.Event /.#what /.#when]) (`` (all _.and (,, (with_template [ ] [(_.coverage [] (|> (do try.monad [it (/.series (list before after)) actual ( it)] (in (same? actual))) (try.else false)))] [/.earliest before] [/.latest after] )) ))) (<| (_.for [/.Series]) (`` (all _.and (_.for [/.equivalence] (equivalenceS.spec (/.equivalence n.equivalence) (..random expected_size random.nat))) (_.for [/.mix] (mixS.spec (..injection expected_instant) /.equivalence /.mix)) (_.for [/.functor] (functorS.spec (..injection expected_instant) /.equivalence /.functor)) (_.coverage [/.series /.size] (|> (do try.monad [it (/.series events)] (in (/.size it))) (try#each (n.= expected_size)) (try.else false))) (_.coverage [/.empty] (and (,, (with_template [ ] [(|> (do try.monad [it (/.series (list))] ( it)) (|.when {try.#Failure error} (exception.match? /.empty error) _ false))] [/.earliest before] [/.latest after] )))) (,, (with_template [ ] [(_.coverage [] (|> (/.series (list )) (|.when {try.#Failure error} (exception.match? error) _ false)))] [/.disordered after before] [/.duplicated before before] )) ))) )))