(.using [library [lux "*" ["_" test {"+" Test}] [abstract [monad {"+" do}]] [control ["[0]" io {"+" IO}] ["[0]" maybe ("[1]#[0]" functor)] ["[0]" try ("[1]#[0]" monad)] ["[0]" exception] ["[0]" function]] [data ["[0]" binary ("[1]#[0]" equivalence)] ["[0]" text ("[1]#[0]" equivalence) ["%" format {"+" format}] [encoding ["[0]" utf8]]] [collection ["[0]" dictionary]]] [math ["[0]" random {"+" Random}]] [world [net {"+" URL} ["[0]" http "_" ["[1]" client] ["[1]/[0]" status] ["@[1]" /]]]]]] [\\program ["[0]" / ["/[1]" // "_" ["[1][0]" identity]]]]) (def: (url_body url) (-> URL (@http.Body IO)) (let [url (# utf8.codec encoded url)] (function (_ _) (io.io {try.#Success [(binary.size url) url]})))) (def: (good_http user password) (-> //identity.User //identity.Password (http.Client IO)) (implementation (def: (request method url headers input) (with_expansions [ [http/status.bad_request [@http.#headers (http.headers (list)) @http.#body (..url_body "")]]] (<| io.io {try.#Success} (if (|> headers (dictionary.value "User-Agent") (maybe#each (same? /.user_agent)) (maybe.else false)) (case [method input] [{@http.#Get} {.#None}] [http/status.ok [@http.#headers (http.headers (list)) @http.#body (..url_body url)]] [{@http.#Put} {.#Some input}] (if (|> headers (dictionary.value "Authorization") (maybe#each (text#= (//identity.basic_auth user password))) (maybe.else false)) [http/status.created [@http.#headers (http.headers (list)) @http.#body (..url_body url)]] ) _ ) )))))) (def: bad_http (http.Client IO) (implementation (def: (request method url headers input) (<| io.io {try.#Success} [http/status.bad_request [@http.#headers (http.headers (list)) @http.#body (..url_body "")]])))) (def: .public test Test (<| (_.covering /._) (do [! random.monad] [address (random.upper_case 10) uri (random.lower_case 10) user (random.lower_case 10) password (random.lower_case 10) content (# ! each (# utf8.codec encoded) (random.lower_case 10))] (all _.and (_.coverage [/.repository /.user_agent /.Address] (let [repo (/.repository (..good_http user password) {.#Some [//identity.#user user //identity.#password password]} address)] (and (|> (# repo download uri) io.run! (try#each (# utf8.codec decoded)) try#conjoint (try#each (text#= (format address uri))) (try.else false)) (|> (# repo upload uri content) io.run! (try#each (function.constant true)) (try.else false))))) (_.coverage [/.upload_failure] (let [repo (/.repository (..good_http user password) {.#None} address)] (case (io.run! (# repo upload uri content)) {try.#Failure error} (exception.match? /.upload_failure error) {try.#Success _} false))) (_.coverage [/.download_failure] (let [repo (/.repository ..bad_http {.#None} address)] (case (io.run! (# repo download uri)) {try.#Failure error} (exception.match? /.download_failure error) {try.#Success _} false))) ))))