RpcClient: subscribe and wait_for #6

Closed
opened 2026-04-11 10:55:38 +00:00 by charles · 0 comments
Owner

User story

As a test author, I want to subscribe to specific event types and block until a matching one arrives, so that I can assert on async server behaviour without polling loops.

Acceptance criteria

subscribe

  • subscribe(events: &[&str]) -> Result<(), TestError> sends a JSON-RPC request:
    {"method":"subscribe","params":{"events":["event.a","event.b"]}}
    
    and awaits success.
  • Semantics: replace, not additive. Each call overwrites the previous filter on the server. Documented in the doc comment and exercised by a self-test. (Resolves spec review §2.)
  • Empty slice means "all events" — sends {"events":[]}.
  • On connect, the client is in "no subscription" state — the user must call subscribe explicitly to receive any events.

wait_for

  • Signature: wait_for(method: &str, predicate: F, timeout: Duration) -> Result<Value, TestError> where F: Fn(&Value) -> bool + Send + Sync.
  • First scans the notification buffer for any already-received notification whose method matches and where predicate(&params) is true. Matching notifications are removed from the buffer so they aren't re-matched by a later call.
  • If nothing matches in the buffer, subscribes to the broadcast channel and waits for new notifications until either a match is found or the timeout elapses.
  • On match, returns the notification's params field as Value.
  • On timeout returns TestError::Timeout { event: method.into(), duration }.
  • Concurrent wait_for calls from different tasks are safe: a notification matched by waiter A is not delivered to waiter B (first matching waiter wins).

Out of scope

  • wait_for_any, collect_events, call_and_wait — separate issue.

References

  • Spec §2.3, §2.4, §3.2; spec review §2
## User story As a **test author**, I want to subscribe to specific event types and block until a matching one arrives, so that I can assert on async server behaviour without polling loops. ## Acceptance criteria ### subscribe - [ ] `subscribe(events: &[&str]) -> Result<(), TestError>` sends a JSON-RPC request: ```json {"method":"subscribe","params":{"events":["event.a","event.b"]}} ``` and awaits success. - [ ] **Semantics: replace, not additive.** Each call overwrites the previous filter on the server. Documented in the doc comment and exercised by a self-test. *(Resolves spec review §2.)* - [ ] Empty slice means "all events" — sends `{"events":[]}`. - [ ] On connect, the client is in "no subscription" state — the user must call `subscribe` explicitly to receive any events. ### wait_for - [ ] Signature: `wait_for(method: &str, predicate: F, timeout: Duration) -> Result<Value, TestError>` where `F: Fn(&Value) -> bool + Send + Sync`. - [ ] First scans the notification buffer for any already-received notification whose `method` matches and where `predicate(&params)` is true. Matching notifications are **removed from the buffer** so they aren't re-matched by a later call. - [ ] If nothing matches in the buffer, subscribes to the broadcast channel and waits for new notifications until either a match is found or the timeout elapses. - [ ] On match, returns the notification's `params` field as `Value`. - [ ] On timeout returns `TestError::Timeout { event: method.into(), duration }`. - [ ] Concurrent `wait_for` calls from different tasks are safe: a notification matched by waiter A is not delivered to waiter B (first matching waiter wins). ## Out of scope - `wait_for_any`, `collect_events`, `call_and_wait` — separate issue. ## References - Spec §2.3, §2.4, §3.2; spec review §2
charles added this to the v0.1.0 milestone 2026-04-11 10:55:38 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/ws-rpc-test#6
No description provided.