
JsonTest.pudu
Pudu53 lines3.0 KB
1/** @Test.Client.Json.Suite — requests and responses whose bodies are JSON */2module PuduLangHttpClient.Client.JsonTest34import Std.Http as Http5import Std.Io as Io6import Std.Json as Json7import Std.Result as Result8import Std.Test as Test9import PuduLangHttpClient.Client as Client10import PuduLangHttpClient.Client.Json as JsonClient11import PuduLangHttpClient.Content as Content12import PuduLangHttpClient as HttpClient13import PuduLangHttpClient.Request as Request14import PuduLangHttpClient.Response as Response15import PuduLangHttpClient.Stub as Stub1617/** @Test.Client.Json.Todo — one item, written and read through derived implementations */18type Todo = { id: Int, title: Str, done: Bool } derives Json.Encode, Json.Decode192021fn echo(request: Request.Request) -> HttpClient.Outcome[Response.Response] {22 let body = match request.content {23 case Some(found) => Result.unwrapOr(Content.readText(&found), "")24 case None => "\{\"id\":1,\"title\":\"" + Http.methodName(&request.method) + " " + match Request.header(&request, "accept") { case Some(found) => found case None => "" } + "\",\"done\":false\}"25 }26 Ok(Response.answer(&request, 200).withContent(Content.text(body, "application/json")))27}282930fn main() -> Int {31 let stub = Stub.create()32 Stub.when(&stub, |request: Request.Request| request.uri.endsWith("/todos/1"), echo)33 Stub.respond(&stub, Http.Get, "/broken", 200, "not json")34 let client = Client.create(Stub.send(&stub)).withBaseAddress("http://api.test/")35 let todo = Todo{id: 2, title: "write docs", done: true}36 let checks = Test.suite("Client.Json", &[37 Test.equals("a get reads a derived value and asks for JSON", &JsonClient.getFromJson[Todo](&client, "todos/1"), &Ok(Todo{id: 1, title: "GET application/json", done: false})),38 Test.equals("a get reads a document", &Result.map(JsonClient.getJson(&client, "todos/1"), |value: Json.Json| Json.field(&value, "id")), &Ok(Some(Json.Number(1)))),39 Test.equals("a delete reads a derived value", &JsonClient.deleteFromJson[Todo](&client, "todos/1"), &Ok(Todo{id: 1, title: "DELETE application/json", done: false})),40 Test.equals("a post, put, and patch write a derived value", &[JsonClient.postAsJson(&client, "todos/1", &todo), JsonClient.putAsJson(&client, "todos/1", &todo), JsonClient.patchAsJson(&client, "todos/1", &todo)].map(|outcome: HttpClient.Outcome[Response.Response]| Result.andThen(outcome, |r: Response.Response| Response.readAs[Todo](&r))), &[Ok(todo), Ok(todo), Ok(todo)]),41 Test.equals("a missing resource is unsuccessful", &JsonClient.getFromJson[Todo](&client, "todos/2"), &Err(HttpClient.Unsuccessful(404, "Not Found"))),42 Test.that("a body that is not JSON is unreadable", match JsonClient.getJson(&client, "broken") {43 case Err(HttpClient.Unreadable(_)) => true44 case _ => false45 })46 ])47 let ran = Test.run(&checks)48 for failure in Test.failuresOf(&ran) {49 let _reported = Io.writeErrorLine(failure)50 }51 Test.report(&ran)52}53