moonbitstack/moonasgi/client does not have a README file

    PushPromise

    pub(all) struct PushPromise {
    path : String
    headers : Array[(String, String)]
    } derive(Eq)

    A server-side push promise captured by the TestClient: the pushed path and the request headers the server would send for it (http.response.push).

    PushPromise::equal

    fn PushPromise::equal(PushPromise, PushPromise) -> Bool

    PushPromise::header

    fn PushPromise::header(self : PushPromise, name : String) -> String?

    First push-request header matching name.

    PushPromise::not_equal

    fn PushPromise::not_equal(x : PushPromise, y : PushPromise) -> Bool

    TestClient

    pub(all) struct TestClient {
    app : (
    Request
    ) -> Array[
    Event
    ]
    root_path : String
    base_headers : Array[(String, String)]
    client : (String, Int)?
    server : (String, Int?)?
    extensions :
    Extensions

    }

    An in-process application driver — the ASGI TestClient — built on the synchronous @http.run_http_app core, so it needs no socket and runs on every backend. It builds a synthetic http scope, feeds the request body in as HttpRequest events, runs the application, and reassembles the outbound stream into a TestResponse. app is the event-emitting application; the new / from_stream constructors adapt a @http.Handler / @http.StreamHandler.

    TestClient::delete

    fn TestClient::delete(self : TestClient, path : String, headers? : Array[(String, String)]) -> TestResponse

    DELETE path.

    TestClient::from_app

    fn TestClient::from_app(app : (
    Request
    ) -> Array[
    Event
    ], root_path? : String, base_headers? : Array[(String, String)], client? : (String, Int)?, server? : (String, Int?)?, extensions? :
    Extensions
    ) -> TestClient

    Build a TestClient from a raw event-emitting application (the shape @http.run_http_app drives). Defaults mirror a typical test harness: empty root_path, no base headers, a ("testclient", 50000) client peer, a ("testserver", 80) server, and no advertised extensions.

    TestClient::from_stream

    fn TestClient::from_stream(handler : (
    Request
    ) ->
    StreamingResponse
    , root_path? : String, base_headers? : Array[(String, String)], client? : (String, Int)?, server? : (String, Int?)?, extensions? :
    Extensions
    ) -> TestClient

    Build a TestClient from a streaming @http.StreamHandler (multi-chunk body, optional trailers).

    TestClient::get

    fn TestClient::get(self : TestClient, path : String, headers? : Array[(String, String)]) -> TestResponse

    GET path.

    TestClient::head

    fn TestClient::head(self : TestClient, path : String, headers? : Array[(String, String)]) -> TestResponse

    HEAD path.

    TestClient::new

    fn TestClient::new(handler : (
    Request
    ) ->
    Response
    , root_path? : String, base_headers? : Array[(String, String)], client? : (String, Int)?, server? : (String, Int?)?, extensions? :
    Extensions
    ) -> TestClient

    Build a TestClient from a unary @http.Handler.

    TestClient::patch

    fn TestClient::patch(self : TestClient, path : String, body? : Bytes, headers? : Array[(String, String)]) -> TestResponse

    PATCH path with body.

    TestClient::post

    fn TestClient::post(self : TestClient, path : String, body? : Bytes, headers? : Array[(String, String)]) -> TestResponse

    POST path with body.

    TestClient::put

    fn TestClient::put(self : TestClient, path : String, body? : Bytes, headers? : Array[(String, String)]) -> TestResponse

    PUT path with body.

    TestClient::request

    fn TestClient::request(self : TestClient, http_method~ : String, path~ : String, headers? : Array[(String, String)], body? : Bytes, http_version? : String, chunks? : Array[Bytes]) -> TestResponse

    Drive one request through the application and capture the response. Splits path into path + query string, merges the client's base_headers before the per-request headers, builds an http scope (carrying the client's root_path / peers / advertised extensions), feeds the body in, runs the app, and reassembles the outbound stream. Pass chunks to stream the request body as several HttpRequest events.

    TestClient::websocket

    fn TestClient::websocket(self : TestClient, path~ : String, handler~ :
    WebSocketHandler
    , send? : Array[
    WsMessage
    ], headers? : Array[(String, String)], subprotocols? : Array[String], disconnect? : Int?) -> WsTestSession

    Drive a @ws.WebSocketHandler through a full connection in-process and capture the result. Opens a WebSocketConnect, feeds each send message in as a WebSocketReceive, then (unless disconnect is None) a WebSocketDisconnect with the given close code, runs the handler through the synchronous @ws.ws_run core, and reassembles the server's outbound frames into a WsTestSession. No socket — testable on every backend, the WebSocket counterpart of request.

    TestClient::websocket_app

    fn TestClient::websocket_app(self : TestClient, path~ : String, app~ : (
    WebSocketScope
    , Array[
    Event
    ]) -> Array[
    Event
    ], send? : Array[
    WsMessage
    ], headers? : Array[(String, String)], subprotocols? : Array[String], disconnect? : Int?) -> WsTestSession

    Drive a general (@spec.WebSocketScope, Array[@spec.Event]) -> Array[@spec.Event] application through a full connection in-process. Like websocket, but for an app that consumes the whole inbound stream directly (the @ws.ws_run_app escape hatch) rather than the connect/receive/disconnect fold.

    TestResponse

    pub(all) struct TestResponse {
    status : Int
    headers : Array[(String, String)]
    body : Bytes
    trailers : Array[(String, String)]
    pushes : Array[PushPromise]
    pathsend : String?
    zerocopysend : ZeroCopySend?
    debug : Array[Json]
    early_hints : Array[Array[String]]
    } derive(Eq)

    The materialised result of driving an application in-process: the response status and headers, the body reassembled from every HttpResponseBody chunk, the trailing headers gathered from HttpResponseTrailers, any push promises, the pathsend path if the app used the path-send extension, the last zerocopysend handoff, every debug info payload, and the early_hints (each a 103 message's Link values). The captured, sans-transport analog of what a real client would observe.

    TestResponse::equal

    TestResponse::header

    fn TestResponse::header(self : TestResponse, name : String) -> String?

    First response header matching name (ASGI lowercased-name convention).

    TestResponse::json

    fn TestResponse::json(self : TestResponse) -> Json raise

    The response body parsed as JSON. Raises @json.ParseError if the body is not valid JSON, mirroring a real client's .json().

    TestResponse::not_equal

    fn TestResponse::not_equal(x : TestResponse, y : TestResponse) -> Bool

    TestResponse::text

    fn TestResponse::text(self : TestResponse) -> String

    The response body decoded as UTF-8 (lossy: invalid sequences become the replacement character), for asserting on text responses.

    TestResponse::trailer

    fn TestResponse::trailer(self : TestResponse, name : String) -> String?

    First trailing header matching name.

    WsTestSession

    pub(all) struct WsTestSession {
    accepted : Bool
    subprotocol : String?
    accept_headers : Array[(String, String)]
    messages : Array[
    WsMessage
    ]
    closed : Bool
    close_code : Int?
    close_reason : String?
    denial : TestResponse?
    } derive(Eq)

    The materialised result of driving a WebSocket connection in-process: whether the handshake was accepted, the negotiated subprotocol and accept_headers, every server→client message (messages), whether the server closed and with what close_code / close_reason, and — when the handshake was denied with the websocket.http.response extension — the captured HTTP denial response. The WebSocket analog of TestResponse.

    WsTestSession::equal

    WsTestSession::header

    fn WsTestSession::header(self : WsTestSession, name : String) -> String?

    First accept-response header matching name.

    WsTestSession::not_equal

    fn WsTestSession::not_equal(x : WsTestSession, y : WsTestSession) -> Bool

    WsTestSession::texts

    fn WsTestSession::texts(self : WsTestSession) -> Array[String]

    The server→client messages that were text frames, decoded to their strings (binary frames are skipped). The ergonomic assertion target for an echo/chat exchange.

    ZeroCopySend

    pub(all) struct ZeroCopySend {
    fd : Int
    offset : Int?
    count : Int?
    } derive(Eq)

    A http.response.zerocopysend message captured by the TestClient: the open file descriptor the app handed off, and the optional byte offset / count. The sans-transport analog of the server performing the zero-copy send.

    ZeroCopySend::equal

    ZeroCopySend::not_equal

    fn ZeroCopySend::not_equal(x : ZeroCopySend, y : ZeroCopySend) -> Bool

    reassemble

    Fold an outbound event stream into a TestResponse: HttpResponseStart sets status/headers, every HttpResponseBody appends to the body, every HttpResponseTrailers appends to the trailers, each HttpResponsePush records a promise, HttpResponsePathSend records the served path, and every HttpResponseEarlyHint records one 103 message's Link values. Other events (websocket, lifespan) are ignored — the http response is what a client observes. 把一串事件拼回一个响应,一致性套件与测试客户端共用。

    Source Files