Translate HTTP and network tests

This commit is contained in:
2026-08-08 18:30:51 +02:00
parent de6e611ef0
commit 6d4d9adaf4
13 changed files with 1793 additions and 1051 deletions

View File

@@ -4,7 +4,10 @@
//! surfaces. Their behavior is implemented only when the owning API slice is
//! ported.
use std::collections::BTreeMap;
use std::future::Future;
use std::marker::PhantomData;
use std::pin::Pin;
use std::sync::{
Arc,
atomic::{AtomicBool, Ordering},
@@ -91,7 +94,7 @@ impl CancellationToken {
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
#[derive(Debug, Default, Eq, Hash, PartialEq)]
pub struct Subscription;
pub type EventHandler<T> = Arc<dyn Fn(T) + Send + Sync>;
@@ -143,17 +146,65 @@ pub struct TimeProvider;
pub struct MediaTypeHeaderValue(pub String);
pub struct HttpMessageHandler;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct HttpRequest {
pub method: String,
pub uri: Uri,
pub headers: BTreeMap<String, String>,
pub content_type: Option<String>,
pub body: Vec<u8>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct HttpResponse {
pub status_code: u16,
pub headers: BTreeMap<String, String>,
pub content_type: Option<String>,
pub body: Vec<u8>,
}
impl HttpResponse {
#[must_use]
pub const fn is_success_status_code(&self) -> bool {
self.status_code >= 200 && self.status_code < 300
}
}
pub type HttpResponseFuture = Pin<Box<dyn Future<Output = HttpResponse> + Send>>;
type HttpHandler = dyn Fn(HttpRequest, CancellationToken) -> HttpResponseFuture + Send + Sync;
#[derive(Clone)]
pub struct HttpMessageHandler(Arc<HttpHandler>);
impl HttpMessageHandler {
pub fn new<F, Fut>(handler: F) -> Self
where
F: Fn(HttpRequest, CancellationToken) -> Fut + Send + Sync + 'static,
Fut: Future<Output = HttpResponse> + Send + 'static,
{
Self(Arc::new(move |request, cancellation_token| {
Box::pin(handler(request, cancellation_token))
}))
}
#[must_use]
pub fn send(
&self,
request: HttpRequest,
cancellation_token: CancellationToken,
) -> HttpResponseFuture {
(self.0)(request, cancellation_token)
}
}
pub struct HttpClient;
pub struct HttpResponse;
pub struct HttpMethod(pub String);
pub struct AuthenticationHeaderValue(pub String);
pub trait IProgress<T> {}
pub trait IProgress<T>: Send + Sync {}
pub struct IEnumerator;
@@ -200,3 +251,55 @@ pub struct UnicodeCategory(pub i32);
pub struct TextEncoding;
pub struct SocketException;
#[cfg(test)]
mod tests {
use super::{CancellationToken, HttpMessageHandler, HttpRequest, HttpResponse, Uri};
use std::collections::BTreeMap;
use std::future::Future;
use std::task::{Context, Poll, Waker};
#[test]
fn http_handler_preserves_request_and_response_data() {
let handler = HttpMessageHandler::new(|request, _cancellation_token| async move {
HttpResponse {
status_code: 201,
headers: request.headers,
content_type: request.content_type,
body: request.body,
}
});
let mut response = handler.send(
HttpRequest {
method: "PUT".into(),
uri: Uri("http://example.test/".into()),
headers: BTreeMap::from([("Location".into(), "slcaps://fixture".into())]),
content_type: Some("application/llsd+xml".into()),
body: b"test".to_vec(),
},
CancellationToken::default(),
);
let mut context = Context::from_waker(Waker::noop());
let response = match Future::poll(response.as_mut(), &mut context) {
Poll::Ready(response) => response,
Poll::Pending => panic!("immediate handler unexpectedly remained pending"),
};
assert!(response.is_success_status_code());
assert_eq!(response.headers["Location"], "slcaps://fixture");
assert_eq!(
response.content_type.as_deref(),
Some("application/llsd+xml")
);
assert_eq!(response.body, b"test");
assert!(
!HttpResponse {
status_code: 399,
headers: BTreeMap::new(),
content_type: None,
body: Vec::new(),
}
.is_success_status_code()
);
}
}

View File

@@ -53,6 +53,8 @@ pub enum Error {
Argument,
/// An index or destination buffer boundary was exceeded.
IndexOutOfRange,
/// An operation observed a requested cancellation.
Cancelled,
}
impl Error {
@@ -61,7 +63,7 @@ impl Error {
pub const fn csharp_member(self) -> Option<&'static str> {
match self {
Self::NotImplemented(error) => Some(error.csharp_member()),
Self::ArgumentNull | Self::Argument | Self::IndexOutOfRange => None,
Self::ArgumentNull | Self::Argument | Self::IndexOutOfRange | Self::Cancelled => None,
}
}
}
@@ -79,6 +81,7 @@ impl fmt::Display for Error {
Self::ArgumentNull => formatter.write_str("required argument was null"),
Self::Argument => formatter.write_str("argument was invalid"),
Self::IndexOutOfRange => formatter.write_str("index was out of range"),
Self::Cancelled => formatter.write_str("operation was cancelled"),
}
}
}

View File

@@ -11377,19 +11377,11 @@ impl GridClient {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GridClient.Parcels")
}
/// C# member: `P:LibreMetaverse.GridClient.Self`.
pub fn self_(&self) -> libremetaverse::AgentManager {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GridClient.Self")
}
/// Setter for C# member: `P:LibreMetaverse.GridClient.Self`.
pub fn set_self_(&mut self, value: libremetaverse::AgentManager) {
pub fn self_(&mut self) -> &mut libremetaverse::AgentManager {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GridClient.Self")
}
/// C# member: `P:LibreMetaverse.GridClient.Settings`.
pub fn settings(&self) -> libremetaverse::Settings {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GridClient.Settings")
}
/// Setter for C# member: `P:LibreMetaverse.GridClient.Settings`.
pub fn set_settings(&mut self, value: libremetaverse::Settings) {
pub fn settings(&mut self) -> &mut libremetaverse::Settings {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.GridClient.Settings")
}
/// C# member: `P:LibreMetaverse.GridClient.Sound`.
@@ -25747,7 +25739,7 @@ impl Settings {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Settings.TexturePipeline")
}
/// C# member: `P:LibreMetaverse.Settings.Timing`.
pub fn timing(&self) -> libremetaverse::TimingSettings {
pub fn timing(&mut self) -> &mut libremetaverse::TimingSettings {
libremetaverse_types::unimplemented_api!("P:LibreMetaverse.Settings.Timing")
}
/// C# member: `P:LibreMetaverse.Settings.UploadCost`.