mirror of https://github.com/rwf2/Rocket.git
Fix or ignore remaining doc tests in 'core'.
This adds an unstable "async_test" function for use in tests, to ensure they stay working while refactoring other APIs.
This commit is contained in:
parent
aee7f35095
commit
b780f9d8e0
|
@ -133,20 +133,22 @@ impl Data {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io;
|
||||
/// use futures::io::AllowStdIo;
|
||||
/// use rocket::Data;
|
||||
///
|
||||
/// fn handler(mut data: Data) -> io::Result<String> {
|
||||
/// async fn handler(mut data: Data) -> io::Result<String> {
|
||||
/// // write all of the data to stdout
|
||||
/// data.stream_to(&mut io::stdout())
|
||||
/// .map(|n| format!("Wrote {} bytes.", n))
|
||||
/// let written = data.stream_to(AllowStdIo::new(io::stdout())).await?;
|
||||
/// Ok(format!("Wrote {} bytes.", written))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn stream_to<'w, W: AsyncWrite + Unpin>(self, writer: &'w mut W) -> impl Future<Output = io::Result<u64>> + 'w {
|
||||
pub fn stream_to<'w, W: AsyncWrite + Unpin + 'w>(self, mut writer: W) -> impl Future<Output = io::Result<u64>> + 'w {
|
||||
Box::pin(async move {
|
||||
let stream = self.open();
|
||||
stream.copy_into(writer).await
|
||||
stream.copy_into(&mut writer).await
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -159,19 +161,20 @@ impl Data {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io;
|
||||
/// use rocket::Data;
|
||||
///
|
||||
/// fn handler(mut data: Data) -> io::Result<String> {
|
||||
/// data.stream_to_file("/static/file")
|
||||
/// .map(|n| format!("Wrote {} bytes to /static/file", n))
|
||||
/// async fn handler(mut data: Data) -> io::Result<String> {
|
||||
/// let written = data.stream_to_file("/static/file").await?;
|
||||
/// Ok(format!("Wrote {} bytes to /static/file", written))
|
||||
/// }
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn stream_to_file<P: AsRef<Path> + Send + 'static>(self, path: P) -> impl Future<Output = io::Result<u64>> {
|
||||
Box::pin(async move {
|
||||
let mut file = tokio::fs::File::create(path).compat().await?.compat();
|
||||
self.stream_to(&mut file).await
|
||||
let file = tokio::fs::File::create(path).compat().await?.compat();
|
||||
self.stream_to(file).await
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -149,3 +149,13 @@ pub fn ignite() -> Rocket {
|
|||
pub fn custom(config: config::Config) -> Rocket {
|
||||
Rocket::custom(config)
|
||||
}
|
||||
|
||||
// TODO.async: More thoughtful plan for async tests
|
||||
/// WARNING: This is unstable! Do not use this method outside of Rocket!
|
||||
#[doc(hidden)]
|
||||
pub fn async_test(fut: impl std::future::Future<Output = ()> + Send + 'static) {
|
||||
use futures::future::{FutureExt, TryFutureExt};
|
||||
|
||||
let mut runtime = tokio::runtime::Runtime::new().expect("create tokio runtime");
|
||||
runtime.block_on(fut.boxed().unit_error().compat()).expect("unit_error future returned Err");
|
||||
}
|
||||
|
|
|
@ -18,16 +18,20 @@ use yansi::Paint;
|
|||
///
|
||||
/// ```rust
|
||||
/// # #![feature(proc_macro_hygiene)]
|
||||
/// use std::io::{self, Read};
|
||||
/// use std::io;
|
||||
///
|
||||
/// use futures::io::AsyncReadExt;
|
||||
///
|
||||
/// # use rocket::post;
|
||||
/// use rocket::Data;
|
||||
/// use rocket::response::Debug;
|
||||
///
|
||||
/// use rocket::AsyncReadExt as _;
|
||||
///
|
||||
/// #[post("/", format = "plain", data = "<data>")]
|
||||
/// fn post(data: Data) -> Result<String, Debug<io::Error>> {
|
||||
/// async fn post(data: Data) -> Result<String, Debug<io::Error>> {
|
||||
/// let mut name = String::with_capacity(32);
|
||||
/// data.open().take(32).read_to_string(&mut name)?;
|
||||
/// data.open().take(32).read_to_string(&mut name).await?;
|
||||
/// Ok(name)
|
||||
/// }
|
||||
/// ```
|
||||
|
|
|
@ -166,7 +166,7 @@ use crate::request::Request;
|
|||
/// use rocket::response::{self, Response, Responder};
|
||||
/// use rocket::http::ContentType;
|
||||
///
|
||||
/// impl Responder<'r> for Person {
|
||||
/// impl<'r> Responder<'r> for Person {
|
||||
/// fn respond_to(self, _: &'r Request) -> response::ResultFuture<'r> {
|
||||
/// Box::pin(async move {
|
||||
/// Response::build()
|
||||
|
|
|
@ -268,11 +268,12 @@ impl<'r> ResponseBuilder<'r> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use rocket::Response;
|
||||
/// use rocket::http::hyper::header::Accept;
|
||||
/// use rocket::http::Header;
|
||||
/// use rocket::http::hyper::header::ACCEPT;
|
||||
///
|
||||
/// let response = Response::build()
|
||||
/// .header_adjoin(Accept::json())
|
||||
/// .header_adjoin(Accept::text())
|
||||
/// .header_adjoin(Header::new(ACCEPT.as_str(), "application/json"))
|
||||
/// .header_adjoin(Header::new(ACCEPT.as_str(), "text/plain"))
|
||||
/// .finalize();
|
||||
///
|
||||
/// assert_eq!(response.headers().get("Accept").count(), 2);
|
||||
|
@ -338,20 +339,23 @@ impl<'r> ResponseBuilder<'r> {
|
|||
self
|
||||
}
|
||||
|
||||
// TODO.async: un-ignore this test once Seek/AsyncSeek situation has been resolved.
|
||||
/// Sets the body of the `Response` to be the fixed-sized `body`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// ```rust,ignore
|
||||
/// # #![feature(async_await)]
|
||||
/// use rocket::Response;
|
||||
/// use std::fs::File;
|
||||
/// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
|
||||
/// use tokio::fs::File;
|
||||
/// # use std::io;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// # fn test() -> io::Result<()> {
|
||||
/// # async fn test() -> io::Result<()> {
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Response::build()
|
||||
/// .sized_body(File::open("body.txt")?)
|
||||
/// .sized_body(File::open("body.txt").compat().await?.compat())
|
||||
/// .finalize();
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
@ -369,15 +373,17 @@ impl<'r> ResponseBuilder<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use rocket::Response;
|
||||
/// use std::fs::File;
|
||||
/// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
|
||||
/// use tokio::fs::File;
|
||||
/// # use std::io;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// # fn test() -> io::Result<()> {
|
||||
/// # async fn test() -> io::Result<()> {
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Response::build()
|
||||
/// .streamed_body(File::open("body.txt")?)
|
||||
/// .streamed_body(File::open("body.txt").compat().await?.compat())
|
||||
/// .finalize();
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
@ -396,15 +402,17 @@ impl<'r> ResponseBuilder<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use rocket::Response;
|
||||
/// use std::fs::File;
|
||||
/// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
|
||||
/// use tokio::fs::File;
|
||||
/// # use std::io;
|
||||
///
|
||||
/// # #[allow(dead_code)]
|
||||
/// # fn test() -> io::Result<()> {
|
||||
/// # async fn test() -> io::Result<()> {
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Response::build()
|
||||
/// .chunked_body(File::open("body.txt")?, 8096)
|
||||
/// .chunked_body(File::open("body.txt").compat().await?.compat(), 8096)
|
||||
/// .finalize();
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
|
@ -814,15 +822,16 @@ impl<'r> Response<'r> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use rocket::Response;
|
||||
/// use rocket::http::hyper::header::Accept;
|
||||
/// use rocket::http::Header;
|
||||
/// use rocket::http::hyper::header::ACCEPT;
|
||||
///
|
||||
/// let mut response = Response::new();
|
||||
/// response.adjoin_header(Accept::json());
|
||||
/// response.adjoin_header(Accept::text());
|
||||
/// response.adjoin_header(Header::new(ACCEPT.as_str(), "application/json"));
|
||||
/// response.adjoin_header(Header::new(ACCEPT.as_str(), "text/plain"));
|
||||
///
|
||||
/// let mut accept_headers = response.headers().iter();
|
||||
/// assert_eq!(accept_headers.next(), Some(Accept::json().into()));
|
||||
/// assert_eq!(accept_headers.next(), Some(Accept::text().into()));
|
||||
/// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "application/json")));
|
||||
/// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "text/plain")));
|
||||
/// assert_eq!(accept_headers.next(), None);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
|
@ -887,14 +896,17 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::Response;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// assert!(response.body().is_none());
|
||||
///
|
||||
/// response.set_sized_body(Cursor::new("Hello, world!"));
|
||||
/// assert_eq!(response.body_string(), Some("Hello, world!".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("Hello, world!".to_string()));
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn body(&mut self) -> Option<Body<&mut (dyn AsyncRead + Unpin + Send)>> {
|
||||
|
@ -916,15 +928,18 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::Response;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// assert!(response.body().is_none());
|
||||
///
|
||||
/// response.set_sized_body(Cursor::new("Hello, world!"));
|
||||
/// assert_eq!(response.body_string(), Some("Hello, world!".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("Hello, world!".to_string()));
|
||||
/// assert!(response.body().is_none());
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn body_string(&mut self) -> impl Future<Output = Option<String>> + 'r {
|
||||
|
@ -944,15 +959,18 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::Response;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// assert!(response.body().is_none());
|
||||
///
|
||||
/// response.set_sized_body(Cursor::new("hi!"));
|
||||
/// assert_eq!(response.body_bytes(), Some(vec![0x68, 0x69, 0x21]));
|
||||
/// assert_eq!(response.body_bytes().await, Some(vec![0x68, 0x69, 0x21]));
|
||||
/// assert!(response.body().is_none());
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn body_bytes(&mut self) -> impl Future<Output = Option<Vec<u8>>> + 'r {
|
||||
|
@ -971,9 +989,11 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::Response;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// assert!(response.body().is_none());
|
||||
///
|
||||
|
@ -981,9 +1001,13 @@ impl<'r> Response<'r> {
|
|||
/// assert!(response.body().is_some());
|
||||
///
|
||||
/// let body = response.take_body();
|
||||
/// let body_string = body.and_then(|b| b.into_string());
|
||||
/// let body_string = match body {
|
||||
/// Some(b) => b.into_string().await,
|
||||
/// None => None,
|
||||
/// };
|
||||
/// assert_eq!(body_string, Some("Hello, world!".to_string()));
|
||||
/// assert!(response.body().is_none());
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn take_body(&mut self) -> Option<Body<Pin<Box<dyn AsyncRead + Send + 'r>>>> {
|
||||
|
@ -1015,12 +1039,15 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::Response;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// response.set_sized_body(Cursor::new("Hello, world!"));
|
||||
/// assert_eq!(response.body_string(), Some("Hello, world!".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("Hello, world!".to_string()));
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn set_sized_body<B>(&mut self, mut body: B)
|
||||
|
@ -1041,12 +1068,17 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{AsyncRead, repeat};
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::repeat;
|
||||
/// use futures::io::AsyncReadExt;
|
||||
/// use rocket::Response;
|
||||
/// use rocket::AsyncReadExt as _;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// response.set_streamed_body(repeat(97).take(5));
|
||||
/// assert_eq!(response.body_string(), Some("aaaaa".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("aaaaa".to_string()));
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_streamed_body<B>(&mut self, body: B) where B: AsyncRead + Send + 'r {
|
||||
|
@ -1059,12 +1091,17 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::io::{AsyncRead, repeat};
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::repeat;
|
||||
/// use futures::io::AsyncReadExt;
|
||||
/// use rocket::Response;
|
||||
/// use rocket::AsyncReadExt as _;
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let mut response = Response::new();
|
||||
/// response.set_chunked_body(repeat(97).take(5), 10);
|
||||
/// assert_eq!(response.body_string(), Some("aaaaa".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("aaaaa".to_string()));
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_chunked_body<B>(&mut self, body: B, chunk_size: u64)
|
||||
|
@ -1079,15 +1116,18 @@ impl<'r> Response<'r> {
|
|||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(async_await)]
|
||||
/// use std::io::Cursor;
|
||||
/// use rocket::response::{Response, Body};
|
||||
///
|
||||
/// # rocket::async_test(async {
|
||||
/// let body = Body::Sized(Cursor::new("Hello!"), 6);
|
||||
///
|
||||
/// let mut response = Response::new();
|
||||
/// response.set_raw_body(body);
|
||||
///
|
||||
/// assert_eq!(response.body_string(), Some("Hello!".to_string()));
|
||||
/// assert_eq!(response.body_string().await, Some("Hello!".to_string()));
|
||||
/// # })
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_raw_body<T>(&mut self, body: Body<T>)
|
||||
|
|
|
@ -50,13 +50,15 @@ impl<'r, R> Created<R> {
|
|||
/// status::Created::new("http://myservice.com/resource.json")
|
||||
/// }
|
||||
///
|
||||
/// # rocket::async_test(async move {
|
||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||
/// # let client = Client::new(rocket).unwrap();
|
||||
/// let mut response = client.get("/").dispatch();
|
||||
/// let mut response = client.get("/").dispatch().await;
|
||||
///
|
||||
/// let loc = response.headers().get_one("Location");
|
||||
/// assert_eq!(loc, Some("http://myservice.com/resource.json"));
|
||||
/// assert!(response.body().is_none());
|
||||
/// });
|
||||
/// ```
|
||||
pub fn new<L: Into<Cow<'static, str>>>(location: L) -> Self {
|
||||
Created(location.into(), None, None)
|
||||
|
@ -80,11 +82,12 @@ impl<'r, R> Created<R> {
|
|||
/// .body("{ 'resource': 'Hello, world!' }")
|
||||
/// }
|
||||
///
|
||||
/// # rocket::async_test(async move {
|
||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||
/// # let client = Client::new(rocket).unwrap();
|
||||
/// let mut response = client.get("/").dispatch();
|
||||
/// let mut response = client.get("/").dispatch().await;
|
||||
///
|
||||
/// let body = response.body_string();
|
||||
/// let body = response.body_string().await;
|
||||
/// assert_eq!(body.unwrap(), "{ 'resource': 'Hello, world!' }");
|
||||
///
|
||||
/// let loc = response.headers().get_one("Location");
|
||||
|
@ -92,6 +95,7 @@ impl<'r, R> Created<R> {
|
|||
///
|
||||
/// let etag = response.headers().get_one("ETag");
|
||||
/// assert_eq!(etag, None);
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn body(mut self, responder: R) -> Self
|
||||
where R: Responder<'r>
|
||||
|
@ -116,11 +120,12 @@ impl<'r, R> Created<R> {
|
|||
/// .tagged_body("{ 'resource': 'Hello, world!' }")
|
||||
/// }
|
||||
///
|
||||
/// # rocket::async_test(async move {
|
||||
/// # let rocket = rocket::ignite().mount("/", routes![create]);
|
||||
/// # let client = Client::new(rocket).unwrap();
|
||||
/// let mut response = client.get("/").dispatch();
|
||||
/// let mut response = client.get("/").dispatch().await;
|
||||
///
|
||||
/// let body = response.body_string();
|
||||
/// let body = response.body_string().await;
|
||||
/// assert_eq!(body.unwrap(), "{ 'resource': 'Hello, world!' }");
|
||||
///
|
||||
/// let loc = response.headers().get_one("Location");
|
||||
|
@ -128,6 +133,7 @@ impl<'r, R> Created<R> {
|
|||
///
|
||||
/// let etag = response.headers().get_one("ETag");
|
||||
/// assert_eq!(etag, Some(r#""13046220615156895040""#));
|
||||
/// # });
|
||||
/// ```
|
||||
pub fn tagged_body(mut self, responder: R) -> Self
|
||||
where R: Responder<'r> + Hash
|
||||
|
|
|
@ -24,10 +24,11 @@ impl<T: AsyncRead> Stream<T> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::io;
|
||||
/// use futures::io::AllowStdIo;
|
||||
/// use rocket::response::Stream;
|
||||
///
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Stream::chunked(io::stdin(), 10);
|
||||
/// let response = Stream::chunked(AllowStdIo::new(io::stdin()), 10);
|
||||
/// ```
|
||||
pub fn chunked(reader: T, chunk_size: u64) -> Stream<T> {
|
||||
Stream(reader, chunk_size)
|
||||
|
@ -49,10 +50,11 @@ impl<T: AsyncRead + Debug> Debug for Stream<T> {
|
|||
///
|
||||
/// ```rust
|
||||
/// use std::io;
|
||||
/// use futures::io::AllowStdIo;
|
||||
/// use rocket::response::Stream;
|
||||
///
|
||||
/// # #[allow(unused_variables)]
|
||||
/// let response = Stream::from(io::stdin());
|
||||
/// let response = Stream::from(AllowStdIo::new(io::stdin()));
|
||||
/// ```
|
||||
impl<T: AsyncRead> From<T> for Stream<T> {
|
||||
fn from(reader: T) -> Self {
|
||||
|
|
|
@ -106,16 +106,12 @@ elif [ "$1" = "--core" ]; then
|
|||
pushd "${CORE_LIB_ROOT}" > /dev/null 2>&1
|
||||
|
||||
echo ":: Building and testing core [no features]..."
|
||||
# TODO.async: --lib because doc tests are not complete
|
||||
CARGO_INCREMENTAL=0 cargo test --no-default-features --lib
|
||||
# CARGO_INCREMENTAL=0 cargo test --no-default-features
|
||||
CARGO_INCREMENTAL=0 cargo test --no-default-features
|
||||
|
||||
for feature in "${FEATURES[@]}"; do
|
||||
echo ":: Building and testing core [${feature}]..."
|
||||
|
||||
# TODO.async: --lib because doc tests are not complete
|
||||
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}" --lib
|
||||
# CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
|
||||
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
|
||||
done
|
||||
|
||||
popd > /dev/null 2>&1
|
||||
|
|
Loading…
Reference in New Issue