
ResponseTest.pudu
Pudu39 lines2.8 KB
1/** @Test.Response.Suite — responses read, checked, and built for stubs */2module PuduLangHttpClient.ResponseTest34import Std.Io as Io5import Std.Json as Json6import Std.Result as Result7import Std.Test as Test8import PuduLangHttpClient.Content as Content9import PuduLangHttpClient as HttpClient10import PuduLangHttpClient.Request as Request11import PuduLangHttpClient.Response as Response1213/** @Test.Response.Price — a body read through a derived decoder */14type Price = { amount: Int } derives Json.Decode151617fn main() -> Int {18 let request = Request.get("http://a/")19 let ok = Response.answer(&request, 200).withHeader("Retry-After", "3").withHeader("content-language", "en").withJson(&Json.object(&[("amount", Json.Number(5))]))20 let missing = Response.answer(&request, 404)21 let checks = Test.suite("Response", &[22 Test.equals("an answer has the status and its reason", &(ok.status.code, missing.status.reason, ok.request.uri), &(200, "Not Found", "http://a/")),23 Test.that("only a 2xx is a success", Response.isSuccess(&ok) && !Response.isSuccess(&missing) && !Response.isSuccess(&Response.answer(&request, 199)) && !Response.isSuccess(&Response.answer(&request, 300))),24 Test.equals("a success passes and a failure names its status", &(Result.map(Response.ensureSuccess(ok), |r: Response.Response| r.status.code), Result.map(Response.ensureSuccess(missing), |r: Response.Response| r.status.code)), &(Ok(200), Err(HttpClient.Unsuccessful(404, "Not Found")))),25 Test.equals("a content header goes with the body and others with the response", &(ok.headers, ok.content.headers), &([("Retry-After", "3")], [("content-type", "application/json; charset=utf-8")])),26 Test.equals("headers are found among the response's own and then its body's", &(Response.header(&ok, "retry-after"), Response.header(&ok, "Content-Type"), Response.header(&ok, "none")), &(Some("3"), Some("application/json; charset=utf-8"), None)),27 Test.equals("every value of a header is listed", &Response.headerValues(&missing.withHeader("vary", "a").withHeader("Vary", "b"), "vary"), &["a", "b"]),28 Test.equals("the body reads as text, bytes, JSON, and a derived value", &(Response.text(&ok), Response.bytes(&ok).length(), Response.json(&ok), Response.readAs[Price](&ok)), &(Ok("\{\"amount\":5\}"), 12, Ok(Json.object(&[("amount", Json.Number(5))])), Ok(Price{amount: 5}))),29 Test.equals("retry-after is read in milliseconds", &(Response.retryAfter(&ok, 0), Response.retryAfter(&missing, 0)), &(Some(3000), None)),30 Test.equals("text replaces the body", &Response.text(&missing.withText("gone")), &Ok("gone")),31 Test.equals("content is set as given", &missing.withContent(Content.octets(&"x".toBytes())).content, &Content.octets(&"x".toBytes()))32 ])33 let ran = Test.run(&checks)34 for failure in Test.failuresOf(&ran) {35 let _reported = Io.writeErrorLine(failure)36 }37 Test.report(&ran)38}39