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:
Jeb Rosen 2019-08-14 09:30:59 -07:00 committed by Sergio Benitez
parent aee7f35095
commit b780f9d8e0
8 changed files with 116 additions and 55 deletions

View File

@ -133,20 +133,22 @@ impl Data {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io; /// use std::io;
/// use futures::io::AllowStdIo;
/// use rocket::Data; /// 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 /// // write all of the data to stdout
/// data.stream_to(&mut io::stdout()) /// let written = data.stream_to(AllowStdIo::new(io::stdout())).await?;
/// .map(|n| format!("Wrote {} bytes.", n)) /// Ok(format!("Wrote {} bytes.", written))
/// } /// }
/// ``` /// ```
#[inline(always)] #[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 { Box::pin(async move {
let stream = self.open(); let stream = self.open();
stream.copy_into(writer).await stream.copy_into(&mut writer).await
}) })
} }
@ -159,19 +161,20 @@ impl Data {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io; /// use std::io;
/// use rocket::Data; /// use rocket::Data;
/// ///
/// fn handler(mut data: Data) -> io::Result<String> { /// async fn handler(mut data: Data) -> io::Result<String> {
/// data.stream_to_file("/static/file") /// let written = data.stream_to_file("/static/file").await?;
/// .map(|n| format!("Wrote {} bytes to /static/file", n)) /// Ok(format!("Wrote {} bytes to /static/file", written))
/// } /// }
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn stream_to_file<P: AsRef<Path> + Send + 'static>(self, path: P) -> impl Future<Output = io::Result<u64>> { pub fn stream_to_file<P: AsRef<Path> + Send + 'static>(self, path: P) -> impl Future<Output = io::Result<u64>> {
Box::pin(async move { Box::pin(async move {
let mut file = tokio::fs::File::create(path).compat().await?.compat(); let file = tokio::fs::File::create(path).compat().await?.compat();
self.stream_to(&mut file).await self.stream_to(file).await
}) })
} }

View File

@ -149,3 +149,13 @@ pub fn ignite() -> Rocket {
pub fn custom(config: config::Config) -> Rocket { pub fn custom(config: config::Config) -> Rocket {
Rocket::custom(config) 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");
}

View File

@ -18,16 +18,20 @@ use yansi::Paint;
/// ///
/// ```rust /// ```rust
/// # #![feature(proc_macro_hygiene)] /// # #![feature(proc_macro_hygiene)]
/// use std::io::{self, Read}; /// use std::io;
///
/// use futures::io::AsyncReadExt;
/// ///
/// # use rocket::post; /// # use rocket::post;
/// use rocket::Data; /// use rocket::Data;
/// use rocket::response::Debug; /// use rocket::response::Debug;
/// ///
/// use rocket::AsyncReadExt as _;
///
/// #[post("/", format = "plain", data = "<data>")] /// #[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); /// 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) /// Ok(name)
/// } /// }
/// ``` /// ```

View File

@ -166,7 +166,7 @@ use crate::request::Request;
/// use rocket::response::{self, Response, Responder}; /// use rocket::response::{self, Response, Responder};
/// use rocket::http::ContentType; /// use rocket::http::ContentType;
/// ///
/// impl Responder<'r> for Person { /// impl<'r> Responder<'r> for Person {
/// fn respond_to(self, _: &'r Request) -> response::ResultFuture<'r> { /// fn respond_to(self, _: &'r Request) -> response::ResultFuture<'r> {
/// Box::pin(async move { /// Box::pin(async move {
/// Response::build() /// Response::build()

View File

@ -268,11 +268,12 @@ impl<'r> ResponseBuilder<'r> {
/// ///
/// ```rust /// ```rust
/// use rocket::Response; /// use rocket::Response;
/// use rocket::http::hyper::header::Accept; /// use rocket::http::Header;
/// use rocket::http::hyper::header::ACCEPT;
/// ///
/// let response = Response::build() /// let response = Response::build()
/// .header_adjoin(Accept::json()) /// .header_adjoin(Header::new(ACCEPT.as_str(), "application/json"))
/// .header_adjoin(Accept::text()) /// .header_adjoin(Header::new(ACCEPT.as_str(), "text/plain"))
/// .finalize(); /// .finalize();
/// ///
/// assert_eq!(response.headers().get("Accept").count(), 2); /// assert_eq!(response.headers().get("Accept").count(), 2);
@ -338,20 +339,23 @@ impl<'r> ResponseBuilder<'r> {
self 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`. /// Sets the body of the `Response` to be the fixed-sized `body`.
/// ///
/// # Example /// # Example
/// ///
/// ```rust /// ```rust,ignore
/// # #![feature(async_await)]
/// use rocket::Response; /// use rocket::Response;
/// use std::fs::File; /// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
/// use tokio::fs::File;
/// # use std::io; /// # use std::io;
/// ///
/// # #[allow(dead_code)] /// # #[allow(dead_code)]
/// # fn test() -> io::Result<()> { /// # async fn test() -> io::Result<()> {
/// # #[allow(unused_variables)] /// # #[allow(unused_variables)]
/// let response = Response::build() /// let response = Response::build()
/// .sized_body(File::open("body.txt")?) /// .sized_body(File::open("body.txt").compat().await?.compat())
/// .finalize(); /// .finalize();
/// # Ok(()) /// # Ok(())
/// # } /// # }
@ -369,15 +373,17 @@ impl<'r> ResponseBuilder<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use rocket::Response; /// use rocket::Response;
/// use std::fs::File; /// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
/// use tokio::fs::File;
/// # use std::io; /// # use std::io;
/// ///
/// # #[allow(dead_code)] /// # #[allow(dead_code)]
/// # fn test() -> io::Result<()> { /// # async fn test() -> io::Result<()> {
/// # #[allow(unused_variables)] /// # #[allow(unused_variables)]
/// let response = Response::build() /// let response = Response::build()
/// .streamed_body(File::open("body.txt")?) /// .streamed_body(File::open("body.txt").compat().await?.compat())
/// .finalize(); /// .finalize();
/// # Ok(()) /// # Ok(())
/// # } /// # }
@ -396,15 +402,17 @@ impl<'r> ResponseBuilder<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use rocket::Response; /// use rocket::Response;
/// use std::fs::File; /// use futures::compat::{AsyncRead01CompatExt, Future01CompatExt};
/// use tokio::fs::File;
/// # use std::io; /// # use std::io;
/// ///
/// # #[allow(dead_code)] /// # #[allow(dead_code)]
/// # fn test() -> io::Result<()> { /// # async fn test() -> io::Result<()> {
/// # #[allow(unused_variables)] /// # #[allow(unused_variables)]
/// let response = Response::build() /// let response = Response::build()
/// .chunked_body(File::open("body.txt")?, 8096) /// .chunked_body(File::open("body.txt").compat().await?.compat(), 8096)
/// .finalize(); /// .finalize();
/// # Ok(()) /// # Ok(())
/// # } /// # }
@ -814,15 +822,16 @@ impl<'r> Response<'r> {
/// ///
/// ```rust /// ```rust
/// use rocket::Response; /// use rocket::Response;
/// use rocket::http::hyper::header::Accept; /// use rocket::http::Header;
/// use rocket::http::hyper::header::ACCEPT;
/// ///
/// let mut response = Response::new(); /// let mut response = Response::new();
/// response.adjoin_header(Accept::json()); /// response.adjoin_header(Header::new(ACCEPT.as_str(), "application/json"));
/// response.adjoin_header(Accept::text()); /// response.adjoin_header(Header::new(ACCEPT.as_str(), "text/plain"));
/// ///
/// let mut accept_headers = response.headers().iter(); /// let mut accept_headers = response.headers().iter();
/// assert_eq!(accept_headers.next(), Some(Accept::json().into())); /// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "application/json")));
/// assert_eq!(accept_headers.next(), Some(Accept::text().into())); /// assert_eq!(accept_headers.next(), Some(Header::new(ACCEPT.as_str(), "text/plain")));
/// assert_eq!(accept_headers.next(), None); /// assert_eq!(accept_headers.next(), None);
/// ``` /// ```
#[inline(always)] #[inline(always)]
@ -887,14 +896,17 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::Response; /// use rocket::Response;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// ///
/// response.set_sized_body(Cursor::new("Hello, world!")); /// 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)] #[inline(always)]
pub fn body(&mut self) -> Option<Body<&mut (dyn AsyncRead + Unpin + Send)>> { pub fn body(&mut self) -> Option<Body<&mut (dyn AsyncRead + Unpin + Send)>> {
@ -916,15 +928,18 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::Response; /// use rocket::Response;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// ///
/// response.set_sized_body(Cursor::new("Hello, world!")); /// 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()); /// assert!(response.body().is_none());
/// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn body_string(&mut self) -> impl Future<Output = Option<String>> + 'r { pub fn body_string(&mut self) -> impl Future<Output = Option<String>> + 'r {
@ -944,15 +959,18 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::Response; /// use rocket::Response;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// ///
/// response.set_sized_body(Cursor::new("hi!")); /// 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()); /// assert!(response.body().is_none());
/// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn body_bytes(&mut self) -> impl Future<Output = Option<Vec<u8>>> + 'r { pub fn body_bytes(&mut self) -> impl Future<Output = Option<Vec<u8>>> + 'r {
@ -971,9 +989,11 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::Response; /// use rocket::Response;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// ///
@ -981,9 +1001,13 @@ impl<'r> Response<'r> {
/// assert!(response.body().is_some()); /// assert!(response.body().is_some());
/// ///
/// let body = response.take_body(); /// 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_eq!(body_string, Some("Hello, world!".to_string()));
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// # })
/// ``` /// ```
#[inline(always)] #[inline(always)]
pub fn take_body(&mut self) -> Option<Body<Pin<Box<dyn AsyncRead + Send + 'r>>>> { pub fn take_body(&mut self) -> Option<Body<Pin<Box<dyn AsyncRead + Send + 'r>>>> {
@ -1015,12 +1039,15 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::Response; /// use rocket::Response;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// response.set_sized_body(Cursor::new("Hello, world!")); /// 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] #[inline]
pub fn set_sized_body<B>(&mut self, mut body: B) pub fn set_sized_body<B>(&mut self, mut body: B)
@ -1041,12 +1068,17 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use std::io::{AsyncRead, repeat}; /// # #![feature(async_await)]
/// use std::io::repeat;
/// use futures::io::AsyncReadExt;
/// use rocket::Response; /// use rocket::Response;
/// use rocket::AsyncReadExt as _;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// response.set_streamed_body(repeat(97).take(5)); /// 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)] #[inline(always)]
pub fn set_streamed_body<B>(&mut self, body: B) where B: AsyncRead + Send + 'r { pub fn set_streamed_body<B>(&mut self, body: B) where B: AsyncRead + Send + 'r {
@ -1059,12 +1091,17 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use std::io::{AsyncRead, repeat}; /// # #![feature(async_await)]
/// use std::io::repeat;
/// use futures::io::AsyncReadExt;
/// use rocket::Response; /// use rocket::Response;
/// use rocket::AsyncReadExt as _;
/// ///
/// # rocket::async_test(async {
/// let mut response = Response::new(); /// let mut response = Response::new();
/// response.set_chunked_body(repeat(97).take(5), 10); /// 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)] #[inline(always)]
pub fn set_chunked_body<B>(&mut self, body: B, chunk_size: u64) pub fn set_chunked_body<B>(&mut self, body: B, chunk_size: u64)
@ -1079,15 +1116,18 @@ impl<'r> Response<'r> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// # #![feature(async_await)]
/// use std::io::Cursor; /// use std::io::Cursor;
/// use rocket::response::{Response, Body}; /// use rocket::response::{Response, Body};
/// ///
/// # rocket::async_test(async {
/// let body = Body::Sized(Cursor::new("Hello!"), 6); /// let body = Body::Sized(Cursor::new("Hello!"), 6);
/// ///
/// let mut response = Response::new(); /// let mut response = Response::new();
/// response.set_raw_body(body); /// 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)] #[inline(always)]
pub fn set_raw_body<T>(&mut self, body: Body<T>) pub fn set_raw_body<T>(&mut self, body: Body<T>)

View File

@ -50,13 +50,15 @@ impl<'r, R> Created<R> {
/// status::Created::new("http://myservice.com/resource.json") /// status::Created::new("http://myservice.com/resource.json")
/// } /// }
/// ///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]); /// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap(); /// # 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"); /// let loc = response.headers().get_one("Location");
/// assert_eq!(loc, Some("http://myservice.com/resource.json")); /// assert_eq!(loc, Some("http://myservice.com/resource.json"));
/// assert!(response.body().is_none()); /// assert!(response.body().is_none());
/// });
/// ``` /// ```
pub fn new<L: Into<Cow<'static, str>>>(location: L) -> Self { pub fn new<L: Into<Cow<'static, str>>>(location: L) -> Self {
Created(location.into(), None, None) Created(location.into(), None, None)
@ -80,11 +82,12 @@ impl<'r, R> Created<R> {
/// .body("{ 'resource': 'Hello, world!' }") /// .body("{ 'resource': 'Hello, world!' }")
/// } /// }
/// ///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]); /// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap(); /// # 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!' }"); /// assert_eq!(body.unwrap(), "{ 'resource': 'Hello, world!' }");
/// ///
/// let loc = response.headers().get_one("Location"); /// let loc = response.headers().get_one("Location");
@ -92,6 +95,7 @@ impl<'r, R> Created<R> {
/// ///
/// let etag = response.headers().get_one("ETag"); /// let etag = response.headers().get_one("ETag");
/// assert_eq!(etag, None); /// assert_eq!(etag, None);
/// # });
/// ``` /// ```
pub fn body(mut self, responder: R) -> Self pub fn body(mut self, responder: R) -> Self
where R: Responder<'r> where R: Responder<'r>
@ -116,11 +120,12 @@ impl<'r, R> Created<R> {
/// .tagged_body("{ 'resource': 'Hello, world!' }") /// .tagged_body("{ 'resource': 'Hello, world!' }")
/// } /// }
/// ///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]); /// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap(); /// # 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!' }"); /// assert_eq!(body.unwrap(), "{ 'resource': 'Hello, world!' }");
/// ///
/// let loc = response.headers().get_one("Location"); /// let loc = response.headers().get_one("Location");
@ -128,6 +133,7 @@ impl<'r, R> Created<R> {
/// ///
/// let etag = response.headers().get_one("ETag"); /// let etag = response.headers().get_one("ETag");
/// assert_eq!(etag, Some(r#""13046220615156895040""#)); /// assert_eq!(etag, Some(r#""13046220615156895040""#));
/// # });
/// ``` /// ```
pub fn tagged_body(mut self, responder: R) -> Self pub fn tagged_body(mut self, responder: R) -> Self
where R: Responder<'r> + Hash where R: Responder<'r> + Hash

View File

@ -24,10 +24,11 @@ impl<T: AsyncRead> Stream<T> {
/// ///
/// ```rust /// ```rust
/// use std::io; /// use std::io;
/// use futures::io::AllowStdIo;
/// use rocket::response::Stream; /// use rocket::response::Stream;
/// ///
/// # #[allow(unused_variables)] /// # #[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> { pub fn chunked(reader: T, chunk_size: u64) -> Stream<T> {
Stream(reader, chunk_size) Stream(reader, chunk_size)
@ -49,10 +50,11 @@ impl<T: AsyncRead + Debug> Debug for Stream<T> {
/// ///
/// ```rust /// ```rust
/// use std::io; /// use std::io;
/// use futures::io::AllowStdIo;
/// use rocket::response::Stream; /// use rocket::response::Stream;
/// ///
/// # #[allow(unused_variables)] /// # #[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> { impl<T: AsyncRead> From<T> for Stream<T> {
fn from(reader: T) -> Self { fn from(reader: T) -> Self {

View File

@ -106,16 +106,12 @@ elif [ "$1" = "--core" ]; then
pushd "${CORE_LIB_ROOT}" > /dev/null 2>&1 pushd "${CORE_LIB_ROOT}" > /dev/null 2>&1
echo ":: Building and testing core [no features]..." echo ":: Building and testing core [no features]..."
# TODO.async: --lib because doc tests are not complete CARGO_INCREMENTAL=0 cargo test --no-default-features
CARGO_INCREMENTAL=0 cargo test --no-default-features --lib
# CARGO_INCREMENTAL=0 cargo test --no-default-features
for feature in "${FEATURES[@]}"; do for feature in "${FEATURES[@]}"; do
echo ":: Building and testing core [${feature}]..." 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}"
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}" --lib
# CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
done done
popd > /dev/null 2>&1 popd > /dev/null 2>&1