(.require [library [lux (.except) ["_" test (.only Test)] [abstract [monad (.only do)]] [control ["[0]" io] ["[0]" try (.only Try)] ["[0]" exception (.only exception:)]] [data ["[0]" text (.use "[1]#[0]" equivalence) ["%" \\format (.only format)]]] [math ["[0]" random]]]] [\\library ["[0]" /]] [\\specification ["$[0]" /]]) (exception: dead) (def mock (/.Mock [Bit Text]) (implementation (def (on_read [dead? content]) (do try.monad [char (try.of_maybe (text.char 0 content)) [_ content] (try.of_maybe (text.split_at 1 content))] (if dead? (exception.except ..dead []) (in [[dead? content] char])))) (def (on_read_line [dead? content]) (do try.monad [[line content] (try.of_maybe (text.split_by text.new_line content))] (if dead? (exception.except ..dead []) (in [[dead? content] line])))) (def (on_write message [dead? content]) (if dead? (exception.except ..dead []) {try.#Success [dead? (format content message)]})) (def (on_close [dead? content]) (if dead? (exception.except ..dead []) {try.#Success [true content]})))) (def .public test Test (<| (_.covering /._) (all _.and (_.for [/.async /.mock /.Mock] ($/.spec (io.io (/.async (/.mock ..mock [false ""]))))) (do random.monad [expected (random.alphabetic 10) .let [console (/.mock ..mock [false ""])]] (_.coverage [/.write_line] (io.run! (do io.monad [?_ (/.write_line expected console) ?actual (at console read_line [])] (in (<| (try.else false) (do try.monad [_ ?_ actual ?actual] (in (text#= expected actual))))))))) )))