Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ log = "0.4"

[dev-dependencies]
rstest = "0.18.2"
wireframe_testing = { path = "wireframe_testing" }

[lints.clippy]
pedantic = "warn"
7 changes: 4 additions & 3 deletions tests/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ use wireframe::{
message::Message,
serializer::BincodeSerializer,
};

mod util;
use util::{run_app_with_frame, run_app_with_frames};
use wireframe_testing::{
drive_with_frame as run_app_with_frame,
drive_with_frames as run_app_with_frames,
};

#[derive(bincode::Encode, bincode::BorrowDecode, PartialEq, Debug)]
struct TestEnvelope {
Expand Down
120 changes: 0 additions & 120 deletions tests/util.rs

This file was deleted.

16 changes: 16 additions & 0 deletions wireframe_testing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "wireframe_testing"
version = "0.1.0"
edition = "2024"

[dependencies]
tokio = { version = "1", features = ["macros", "rt"] }
wireframe = { path = ".." }
bincode = "2"
bytes = "1"

[dev-dependencies]
rstest = "0.18"

[lib]
path = "src/lib.rs"
139 changes: 139 additions & 0 deletions wireframe_testing/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use bincode::Encode;
use bytes::BytesMut;
use tokio::io::{self, AsyncReadExt, AsyncWriteExt, DuplexStream, duplex};
use wireframe::{
app::{Packet, WireframeApp},
frame::FrameProcessor,
serializer::Serializer,
};

const DEFAULT_CAPACITY: usize = 4096;

/// Feed a single frame into `app` using an in-memory duplex stream.
pub async fn drive_with_frame<S, C, E>(
app: WireframeApp<S, C, E>,
frame: Vec<u8>,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync + 'static,
C: Send + 'static,
E: Packet,
{
drive_with_frame_with_capacity(app, frame, DEFAULT_CAPACITY).await
}

/// Drive `app` with multiple frames, returning all bytes written by the app.
pub async fn drive_with_frames<S, C, E>(
app: WireframeApp<S, C, E>,
frames: Vec<Vec<u8>>,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync + 'static,
C: Send + 'static,
E: Packet,
{
drive_with_frames_with_capacity(app, frames, DEFAULT_CAPACITY).await
}

/// Feed `app` a single frame with a custom duplex buffer capacity.
pub async fn drive_with_frame_with_capacity<S, C, E>(
app: WireframeApp<S, C, E>,
frame: Vec<u8>,
capacity: usize,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync + 'static,
C: Send + 'static,
E: Packet,
{
drive_with_frames_with_capacity(app, vec![frame], capacity).await
}

/// Drive `app` with multiple frames using a duplex buffer of `capacity` bytes.
pub async fn drive_with_frames_with_capacity<S, C, E>(
app: WireframeApp<S, C, E>,
frames: Vec<Vec<u8>>,
capacity: usize,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync + 'static,
C: Send + 'static,
E: Packet,
{
let (mut client, server) = duplex(capacity);
let server_task = tokio::spawn(async move {
app.handle_connection(server).await;
});

send_frames(&mut client, &frames).await?;
client.shutdown().await?;

let mut buf = Vec::new();
client.read_to_end(&mut buf).await?;

server_task.await.expect("app task panicked");
Ok(buf)
}

/// Borrow `app` mutably and feed it a single frame.
pub async fn drive_with_frame_mut<S, C, E>(
app: &mut WireframeApp<S, C, E>,
frame: Vec<u8>,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync,
C: Send,
E: Packet,
{
drive_with_frames_mut(app, vec![frame]).await
}

/// Borrow `app` mutably and feed it multiple frames.
pub async fn drive_with_frames_mut<S, C, E>(
app: &mut WireframeApp<S, C, E>,
frames: Vec<Vec<u8>>,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync,
C: Send,
E: Packet,
{
let (mut client, server) = duplex(DEFAULT_CAPACITY);

send_frames(&mut client, &frames).await?;
client.shutdown().await?;

app.handle_connection(server).await;

let mut buf = Vec::new();
client.read_to_end(&mut buf).await?;

Ok(buf)
}

/// Encode `msg` using `bincode` and drive the app with the resulting frame.
pub async fn drive_with_bincode<S, C, E, M>(
app: WireframeApp<S, C, E>,
msg: M,
) -> io::Result<Vec<u8>>
where
S: Serializer + Send + Sync + 'static,
C: Send + 'static,
E: Packet,
M: Encode,
{
let bytes = bincode::encode_to_vec(msg, bincode::config::standard())
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
let mut framed = BytesMut::with_capacity(4 + bytes.len());
wireframe::frame::LengthPrefixedProcessor::default()
.encode(&bytes, &mut framed)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
drive_with_frame(app, framed.to_vec()).await
}

async fn send_frames(stream: &mut DuplexStream, frames: &[Vec<u8>]) -> io::Result<()> {
for frame in frames {
stream.write_all(frame).await?;
}
Ok(())
}
11 changes: 11 additions & 0 deletions wireframe_testing/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pub mod helpers;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (review_instructions): Module 'wireframe_testing' is missing a containing item comment (//!).

Please add a module-level doc comment at the top of this file using //! to describe the purpose of the module.

Review instructions:

Path patterns: **/*.rs

Instructions:
All modules MUST have a containing item comment (//!)


pub use helpers::{
drive_with_bincode,
drive_with_frame,
drive_with_frame_mut,
drive_with_frame_with_capacity,
drive_with_frames,
drive_with_frames_mut,
drive_with_frames_with_capacity,
};
Loading