Skip to content

Commit d1f811f

Browse files
committed
Documentation
1 parent 73d56ea commit d1f811f

File tree

2 files changed

+365
-17
lines changed

2 files changed

+365
-17
lines changed

src/wisp/simulate.gleam

Lines changed: 191 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,25 @@ pub const default_browser_headers: List(#(String, String)) = [
270270
]
271271

272272
/// Create a websocket upgrade request with proper headers.
273-
/// This creates a request that simulates a WebSocket upgrade handshake.
273+
///
274+
/// This creates a request that simulates a WebSocket upgrade handshake by
275+
/// setting the necessary headers: `connection`, `upgrade`, `sec-websocket-key`,
276+
/// and `sec-websocket-version`.
277+
///
278+
/// ## Example
279+
///
280+
/// ```gleam
281+
/// let request = simulate.websocket_request(http.Get, "/chat")
282+
/// let response = handle_request(request)
283+
///
284+
/// case response.body {
285+
/// wisp.WebSocket(upgrade) -> {
286+
/// let handler = wisp.upgrade_to_websocket(upgrade)
287+
/// // Test the websocket handler
288+
/// }
289+
/// _ -> panic as "Expected WebSocket upgrade"
290+
/// }
291+
/// ```
274292
///
275293
pub fn websocket_request(method: http.Method, path: String) -> Request {
276294
request(method, path)
@@ -280,9 +298,24 @@ pub fn websocket_request(method: http.Method, path: String) -> Request {
280298
|> header("sec-websocket-version", "13")
281299
}
282300

283-
/// A websocket mock that captures sent messages for testing.
284-
/// This allows you to verify what messages your websocket handler sends
285-
/// in response to incoming messages.
301+
/// A websocket mock for testing websocket handlers.
302+
///
303+
/// This opaque type represents a test websocket connection that captures all
304+
/// messages sent by the handler. It maintains the handler's state and tracks
305+
/// all text and binary messages sent through the connection.
306+
///
307+
/// You cannot construct this type directly - use `create_websocket` to create
308+
/// a test websocket from a websocket handler.
309+
///
310+
/// ## Functions
311+
///
312+
/// - `create_websocket` - Create a new test websocket
313+
/// - `send_websocket_text` - Send a text message to the handler
314+
/// - `send_websocket_binary` - Send a binary message to the handler
315+
/// - `websocket_sent_text_messages` - Get all text messages sent by the handler
316+
/// - `websocket_sent_binary_messages` - Get all binary messages sent by the handler
317+
/// - `reset_websocket` - Reset to initial state
318+
/// - `close_websocket` - Close the connection
286319
///
287320
pub opaque type WebSocket {
288321
WebSocket(
@@ -316,8 +349,39 @@ type WebSocketMessage {
316349
IsClosed(reply_with: process.Subject(Bool))
317350
}
318351

319-
/// Create a new websocket mock that captures all sent messages.
320-
/// Returns both the websocket and the websocket connection.
352+
/// Create a new websocket mock for testing.
353+
///
354+
/// This function creates a test websocket that captures all messages sent by the
355+
/// handler, allowing you to verify the handler's behavior without needing a real
356+
/// WebSocket connection. The mock automatically tracks text and binary messages
357+
/// sent through the connection.
358+
///
359+
/// ## Example
360+
///
361+
/// ```gleam
362+
/// let handler = websocket.new(
363+
/// on_init: fn(_conn) { 0 },
364+
/// on_message: fn(state, message, connection) {
365+
/// case message {
366+
/// websocket.Text(text) -> {
367+
/// websocket.send_text(connection, "Echo: " <> text)
368+
/// websocket.Continue(state + 1)
369+
/// }
370+
/// _ -> websocket.Continue(state)
371+
/// }
372+
/// },
373+
/// on_close: fn(_state) { Nil },
374+
/// )
375+
///
376+
/// let assert Ok(ws) = simulate.create_websocket(handler)
377+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello")
378+
/// let assert ["Echo: Hello"] = simulate.websocket_sent_text_messages(ws)
379+
/// ```
380+
///
381+
/// ## Returns
382+
///
383+
/// - `Ok(WebSocket)` - A test websocket that can be used with other simulate functions
384+
/// - `Error(actor.StartError)` - If the underlying actor fails to start
321385
///
322386
pub fn create_websocket(
323387
handler websocket: websocket.WebSocket,
@@ -421,21 +485,67 @@ fn handle_message(
421485
}
422486
}
423487

424-
/// Get all text messages that were sent through the mock connection.
425-
/// Messages are returned in the order they were sent.
488+
/// Get all text messages that have been sent by the websocket handler.
489+
///
490+
/// Messages are returned in the order they were sent. This is useful for
491+
/// verifying that your handler sends the expected messages in response to
492+
/// incoming messages.
493+
///
494+
/// ## Example
495+
///
496+
/// ```gleam
497+
/// let assert Ok(ws) = simulate.create_websocket(handler)
498+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello")
499+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "World")
500+
///
501+
/// let messages = simulate.websocket_sent_text_messages(ws)
502+
/// assert messages == ["Response 1", "Response 2"]
503+
/// ```
426504
///
427505
pub fn websocket_sent_text_messages(websocket: WebSocket) -> List(String) {
428506
process.call(websocket.subject, 1000, GetSentTextMessages)
429507
}
430508

431-
/// Get all binary messages that were sent through the mock connection.
432-
/// Messages are returned in the order they were sent.
509+
/// Get all binary messages that have been sent by the websocket handler.
510+
///
511+
/// Messages are returned in the order they were sent. This is useful for
512+
/// verifying that your handler sends the expected binary data in response to
513+
/// incoming messages.
514+
///
515+
/// ## Example
516+
///
517+
/// ```gleam
518+
/// let assert Ok(ws) = simulate.create_websocket(handler)
519+
/// let assert Ok(ws) = simulate.send_websocket_binary(ws, <<1, 2, 3>>)
520+
///
521+
/// let messages = simulate.websocket_sent_binary_messages(ws)
522+
/// assert messages == [<<1, 2, 3>>]
523+
/// ```
433524
///
434525
pub fn websocket_sent_binary_messages(websocket: WebSocket) -> List(BitArray) {
435526
process.call(websocket.subject, 1000, GetSentBinaryMessages)
436527
}
437528

438-
/// Reset the mock to its initial state, clearing all captured messages.
529+
/// Reset the websocket to its initial state, clearing all captured messages.
530+
///
531+
/// This calls the handler's `on_init` callback again and clears the list of
532+
/// sent messages. The websocket is also marked as not closed, allowing you to
533+
/// send messages again after a close.
534+
///
535+
/// ## Example
536+
///
537+
/// ```gleam
538+
/// let assert Ok(ws) = simulate.create_websocket(handler)
539+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello")
540+
/// let assert ["Response"] = simulate.websocket_sent_text_messages(ws)
541+
///
542+
/// // Reset to initial state
543+
/// let ws = simulate.reset_websocket(ws)
544+
/// let assert [] = simulate.websocket_sent_text_messages(ws)
545+
///
546+
/// // Can send messages again from a clean slate
547+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello again")
548+
/// ```
439549
///
440550
pub fn reset_websocket(websocket: WebSocket) -> WebSocket {
441551
let WebSocket(websocket: internal_websocket, connection:, state: _, subject:) =
@@ -446,8 +556,28 @@ pub fn reset_websocket(websocket: WebSocket) -> WebSocket {
446556
WebSocket(websocket: internal_websocket, connection:, state:, subject:)
447557
}
448558

449-
/// Simulate sending a text message to a websocket handler.
450-
/// Returns the updated state and any effects that occurred.
559+
/// Simulate sending a text message to the websocket handler.
560+
///
561+
/// This calls the handler's `on_message` callback with a `Text` message. The
562+
/// handler's state is updated based on the callback's response. Any messages
563+
/// sent by the handler can be retrieved using `websocket_sent_text_messages`
564+
/// or `websocket_sent_binary_messages`.
565+
///
566+
/// If the websocket has been closed, this function returns the websocket
567+
/// unchanged without calling the handler.
568+
///
569+
/// ## Example
570+
///
571+
/// ```gleam
572+
/// let assert Ok(ws) = simulate.create_websocket(handler)
573+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello")
574+
/// let assert ["Echo: Hello"] = simulate.websocket_sent_text_messages(ws)
575+
/// ```
576+
///
577+
/// ## Returns
578+
///
579+
/// - `Ok(WebSocket)` - The websocket with updated state
580+
/// - `Error(Nil)` - If the handler returns `Stop` or `StopWithError`
451581
///
452582
pub fn send_websocket_text(
453583
ws: WebSocket,
@@ -471,8 +601,28 @@ pub fn send_websocket_text(
471601
}
472602
}
473603

474-
/// Simulate sending a binary message to a websocket handler.
475-
/// Returns the updated state and any effects that occurred.
604+
/// Simulate sending a binary message to the websocket handler.
605+
///
606+
/// This calls the handler's `on_message` callback with a `Binary` message. The
607+
/// handler's state is updated based on the callback's response. Any messages
608+
/// sent by the handler can be retrieved using `websocket_sent_text_messages`
609+
/// or `websocket_sent_binary_messages`.
610+
///
611+
/// If the websocket has been closed, this function returns the websocket
612+
/// unchanged without calling the handler.
613+
///
614+
/// ## Example
615+
///
616+
/// ```gleam
617+
/// let assert Ok(ws) = simulate.create_websocket(handler)
618+
/// let assert Ok(ws) = simulate.send_websocket_binary(ws, <<1, 2, 3>>)
619+
/// let assert [<<1, 2, 3>>] = simulate.websocket_sent_binary_messages(ws)
620+
/// ```
621+
///
622+
/// ## Returns
623+
///
624+
/// - `Ok(WebSocket)` - The websocket with updated state
625+
/// - `Error(Nil)` - If the handler returns `Stop` or `StopWithError`
476626
///
477627
pub fn send_websocket_binary(
478628
ws: WebSocket,
@@ -496,8 +646,32 @@ pub fn send_websocket_binary(
496646
}
497647
}
498648

499-
/// Simulate closing a websocket connection.
500-
/// Returns the updated state representing the closed connection.
649+
/// Simulate closing the websocket connection.
650+
///
651+
/// This calls the handler's `on_close` callback with the current handler state.
652+
/// After closing, any subsequent calls to `send_websocket_text` or
653+
/// `send_websocket_binary` will be ignored without calling the handler.
654+
///
655+
/// Use `reset_websocket` to re-open the connection for further testing.
656+
///
657+
/// ## Example
658+
///
659+
/// ```gleam
660+
/// let assert Ok(ws) = simulate.create_websocket(handler)
661+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "Hello")
662+
///
663+
/// // Close the connection
664+
/// let assert Ok(Nil) = simulate.close_websocket(ws)
665+
///
666+
/// // Further messages are ignored
667+
/// let assert Ok(ws) = simulate.send_websocket_text(ws, "After close")
668+
/// let assert ["Response 1"] = simulate.websocket_sent_text_messages(ws)
669+
/// ```
670+
///
671+
/// ## Returns
672+
///
673+
/// - `Ok(Nil)` - If the connection was closed successfully
674+
/// - `Error(WebSocketError)` - If closing the connection failed
501675
///
502676
pub fn close_websocket(
503677
websocket: WebSocket,

0 commit comments

Comments
 (0)