Make 'Fairing::on_attach()' async.

This transitively requires that 'Rocket::inspect()', 'Client::new()',
and 'Client::untracked()' also become async.
This commit is contained in:
Jeb Rosen 2020-06-14 08:57:53 -07:00 committed by Sergio Benitez
parent dea940c7a8
commit b0238e5110
78 changed files with 394 additions and 316 deletions

View File

@ -93,8 +93,8 @@ pub fn database_attr(attr: TokenStream, input: TokenStream) -> Result<TokenStrea
pub fn fairing() -> impl ::rocket::fairing::Fairing {
use #databases::Poolable;
::rocket::fairing::AdHoc::on_attach(#fairing_name, |mut rocket| {
let pool = #databases::database_config(#name, rocket.inspect().config())
::rocket::fairing::AdHoc::on_attach(#fairing_name, |mut rocket| async {
let pool = #databases::database_config(#name, rocket.inspect().await.config())
.map(<#conn_type>::pool);
match pool {

View File

@ -548,9 +548,9 @@ pub enum ConfigError {
/// # .extra("databases", databases)
/// # .expect("custom config okay");
/// #
/// # rocket::custom(config).attach(AdHoc::on_attach("Testing", |mut rocket| {
/// # rocket::custom(config).attach(AdHoc::on_attach("Testing", |mut rocket| async {
/// # {
/// let manifest = rocket.inspect();
/// let manifest = rocket.inspect().await;
/// let config = database_config("my_db", manifest.config()).unwrap();
/// assert_eq!(config.url, "db/db.sqlite");
/// assert_eq!(config.pool_size, 25);

View File

@ -151,8 +151,8 @@ impl Fairing for TemplateFairing {
/// The user's callback, if any was supplied, is called to customize the
/// template engines. In debug mode, the `ContextManager::new` method
/// initializes a directory watcher for auto-reloading of templates.
fn on_attach(&self, mut rocket: Rocket) -> Result<Rocket, Rocket> {
let manifest = rocket.inspect();
async fn on_attach(&self, mut rocket: Rocket) -> Result<Rocket, Rocket> {
let manifest = rocket.inspect().await;
let config = manifest.config();
let mut template_root = config.root_relative(DEFAULT_TEMPLATE_DIR);
match config.get_str("template_dir") {

View File

@ -331,8 +331,9 @@ impl Template {
/// use rocket::local::Client;
///
/// fn main() {
/// # rocket::async_test(async {
/// let rocket = rocket::ignite().attach(Template::fairing());
/// let client = Client::new(rocket).expect("valid rocket");
/// let client = Client::new(rocket).await.expect("valid rocket");
///
/// // Create a `context`. Here, just an empty `HashMap`.
/// let mut context = HashMap::new();
@ -340,6 +341,7 @@ impl Template {
/// # context.insert("test", "test");
/// # #[allow(unused_variables)]
/// let template = Template::show(client.manifest(), "index", context);
/// # });
/// }
/// ```
#[inline]

View File

@ -22,8 +22,8 @@ mod rusqlite_integration_test {
#[database("test_db")]
struct SqliteDb(pub rusqlite::Connection);
#[test]
fn deref_mut_impl_present() {
#[rocket::async_test]
async fn deref_mut_impl_present() {
let mut test_db: BTreeMap<String, Value> = BTreeMap::new();
let mut test_db_opts: BTreeMap<String, Value> = BTreeMap::new();
test_db_opts.insert("url".into(), Value::String(":memory:".into()));
@ -34,7 +34,7 @@ mod rusqlite_integration_test {
.unwrap();
let mut rocket = rocket::custom(config).attach(SqliteDb::fairing());
let mut conn = SqliteDb::get_one(rocket.inspect()).expect("unable to get connection");
let mut conn = SqliteDb::get_one(rocket.inspect().await).expect("unable to get connection");
// Rusqlite's `transaction()` method takes `&mut self`; this tests the
// presence of a `DerefMut` trait on the generated connection type.
@ -43,8 +43,8 @@ mod rusqlite_integration_test {
tx.commit().expect("committed transaction");
}
#[test]
fn deref_impl_present() {
#[rocket::async_test]
async fn deref_impl_present() {
let mut test_db: BTreeMap<String, Value> = BTreeMap::new();
let mut test_db_opts: BTreeMap<String, Value> = BTreeMap::new();
test_db_opts.insert("url".into(), Value::String(":memory:".into()));
@ -55,7 +55,7 @@ mod rusqlite_integration_test {
.unwrap();
let mut rocket = rocket::custom(config).attach(SqliteDb::fairing());
let conn = SqliteDb::get_one(rocket.inspect()).expect("unable to get connection");
let conn = SqliteDb::get_one(rocket.inspect().await).expect("unable to get connection");
let _: i32 = conn.query_row("SELECT 1", &[] as &[&dyn ToSql], |row| row.get(0)).expect("get row");
}
}

View File

@ -34,7 +34,7 @@ mod helmet_tests {
macro_rules! dispatch {
($helmet:expr, $closure:expr) => {{
let rocket = rocket::ignite().mount("/", routes![hello]).attach($helmet);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let response = client.get("/").dispatch().await;
assert_eq!(response.status(), Status::Ok);
$closure(response)

View File

@ -73,7 +73,7 @@ mod static_tests {
#[rocket::async_test]
async fn test_static_no_index() {
let client = Client::new(rocket()).expect("valid rocket");
let client = Client::new(rocket()).await.expect("valid rocket");
assert_all(&client, "no_index", REGULAR_FILES, true).await;
assert_all(&client, "no_index", HIDDEN_FILES, false).await;
assert_all(&client, "no_index", INDEXED_DIRECTORIES, false).await;
@ -81,7 +81,7 @@ mod static_tests {
#[rocket::async_test]
async fn test_static_hidden() {
let client = Client::new(rocket()).expect("valid rocket");
let client = Client::new(rocket()).await.expect("valid rocket");
assert_all(&client, "dots", REGULAR_FILES, true).await;
assert_all(&client, "dots", HIDDEN_FILES, true).await;
assert_all(&client, "dots", INDEXED_DIRECTORIES, false).await;
@ -89,7 +89,7 @@ mod static_tests {
#[rocket::async_test]
async fn test_static_index() {
let client = Client::new(rocket()).expect("valid rocket");
let client = Client::new(rocket()).await.expect("valid rocket");
assert_all(&client, "index", REGULAR_FILES, true).await;
assert_all(&client, "index", HIDDEN_FILES, false).await;
assert_all(&client, "index", INDEXED_DIRECTORIES, true).await;
@ -101,7 +101,7 @@ mod static_tests {
#[rocket::async_test]
async fn test_static_all() {
let client = Client::new(rocket()).expect("valid rocket");
let client = Client::new(rocket()).await.expect("valid rocket");
assert_all(&client, "both", REGULAR_FILES, true).await;
assert_all(&client, "both", HIDDEN_FILES, true).await;
assert_all(&client, "both", INDEXED_DIRECTORIES, true).await;
@ -133,7 +133,7 @@ mod static_tests {
fn catch_two(a: &RawStr, b: &RawStr) -> String { format!("{}/{}", a, b) }
let rocket = rocket().mount("/default", routes![catch_one, catch_two]);
let client = Client::new(rocket).expect("valid rocket");
let client = Client::new(rocket).await.expect("valid rocket");
let mut response = client.get("/default/ireallydontexist").dispatch().await;
assert_eq!(response.status(), Status::Ok);

View File

@ -49,10 +49,10 @@ mod templates_tests {
const ESCAPED_EXPECTED: &'static str
= "\nh_start\ntitle: _test_\nh_end\n\n\n&lt;script &#x2F;&gt;\n\nfoot\n";
#[test]
fn test_tera_templates() {
#[rocket::async_test]
async fn test_tera_templates() {
let mut rocket = rocket();
let manifest = rocket.inspect();
let manifest = rocket.inspect().await;
let mut map = HashMap::new();
map.insert("title", "_test_");
map.insert("content", "<script />");
@ -68,7 +68,7 @@ mod templates_tests {
#[rocket::async_test]
async fn test_template_metadata_with_tera() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.get("/tera/txt_test").dispatch().await;
assert_eq!(response.status(), Status::Ok);
@ -94,10 +94,10 @@ mod templates_tests {
const EXPECTED: &'static str
= "Hello _test_!\n\n<main> &lt;script /&gt; hi </main>\nDone.\n\n";
#[test]
fn test_handlebars_templates() {
#[rocket::async_test]
async fn test_handlebars_templates() {
let mut rocket = rocket();
let manifest = rocket.inspect();
let manifest = rocket.inspect().await;
let mut map = HashMap::new();
map.insert("title", "_test_");
map.insert("content", "<script /> hi");
@ -109,7 +109,7 @@ mod templates_tests {
#[rocket::async_test]
async fn test_template_metadata_with_handlebars() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.get("/hbs/test").dispatch().await;
assert_eq!(response.status(), Status::Ok);
@ -146,7 +146,7 @@ mod templates_tests {
write_file(&reload_path, INITIAL_TEXT);
// set up the client. if we can't reload templates, then just quit
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let res = client.get("/is_reloading").dispatch().await;
if res.status() != Status::Ok {
return;

View File

@ -36,7 +36,7 @@ foo!("/hello/<name>", name);
#[rocket::async_test]
async fn test_reexpansion() {
let rocket = rocket::ignite().mount("/", routes![easy, hard, hi]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/easy/327").dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "easy id: 327");
@ -62,7 +62,7 @@ index!(i32);
#[rocket::async_test]
async fn test_index() {
let rocket = rocket::ignite().mount("/", routes![index]).manage(100i32);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "Thing: 100");

View File

@ -23,7 +23,7 @@ pub enum Foo<'r> {
#[rocket::async_test]
async fn responder_foo() {
let client = Client::new(rocket::ignite()).expect("valid rocket");
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();
@ -72,7 +72,7 @@ pub struct Bar<'r> {
#[rocket::async_test]
async fn responder_bar() {
let client = Client::new(rocket::ignite()).expect("valid rocket");
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();
@ -97,7 +97,7 @@ pub struct Baz {
#[rocket::async_test]
async fn responder_baz() {
let client = Client::new(rocket::ignite()).expect("valid rocket");
let client = Client::new(rocket::ignite()).await.expect("valid rocket");
let local_req = client.get("/");
let req = local_req.inner();

View File

@ -44,7 +44,7 @@ fn simple(simple: Simple) -> String { simple.0 }
#[rocket::async_test]
async fn test_data() {
let rocket = rocket::ignite().mount("/", routes![form, simple]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.post("/f")
.header(ContentType::Form)

View File

@ -39,7 +39,7 @@ async fn test_formats() {
.mount("/", routes![json, xml, json_long, msgpack_long, msgpack,
plain, binary, other]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.post("/").header(ContentType::JSON).dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "json");
@ -85,7 +85,7 @@ async fn test_custom_formats() {
let rocket = rocket::ignite()
.mount("/", routes![get_foo, post_foo, get_bar_baz, put_bar_baz]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let foo_a = Accept::new(&[MediaType::new("application", "foo").into()]);
let foo_ct = ContentType::new("application", "foo");

View File

@ -21,7 +21,7 @@ fn get3(_number: u64) -> &'static str { "3" }
#[rocket::async_test]
async fn test_ranking() {
let rocket = rocket::ignite().mount("/", routes![get0, get1, get2, get3]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/0").dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "0");
@ -41,12 +41,12 @@ async fn test_ranking() {
#[get("/<_n>")]
fn get0b(_n: u8) { }
#[test]
fn test_rank_collision() {
#[rocket::async_test]
async fn test_rank_collision() {
use rocket::error::LaunchErrorKind;
let rocket = rocket::ignite().mount("/", routes![get0, get0b]);
let client_result = Client::new(rocket);
let client_result = Client::new(rocket).await;
match client_result.as_ref().map_err(|e| e.kind()) {
Err(LaunchErrorKind::Collision(..)) => { /* o.k. */ },
Ok(_) => panic!("client succeeded unexpectedly"),

View File

@ -85,7 +85,7 @@ async fn test_full_route() {
.mount("/1", routes![post1])
.mount("/2", routes![post2]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let a = "A%20A";
let name = "Bob%20McDonald";

View File

@ -174,9 +174,9 @@
//!
//! fn main() {
//! rocket::ignite()
//! .attach(AdHoc::on_attach("Token Config", |mut rocket| {
//! .attach(AdHoc::on_attach("Token Config", |mut rocket| async {
//! println!("Adding token managed state from config...");
//! let token_val = rocket.inspect().config().get_int("token").unwrap_or(-1);
//! let token_val = rocket.inspect().await.config().get_int("token").unwrap_or(-1);
//! Ok(rocket.manage(Token(token_val)))
//! }))
//! # ;

View File

@ -1,6 +1,6 @@
use std::sync::Mutex;
use futures_util::future::BoxFuture;
use futures_util::future::{Future, BoxFuture};
use crate::{Manifest, Rocket, Request, Response, Data};
use crate::fairing::{Fairing, Kind, Info};
@ -46,7 +46,7 @@ pub struct AdHoc {
enum AdHocKind {
/// An ad-hoc **attach** fairing. Called when the fairing is attached.
Attach(Mutex<Option<Box<dyn FnOnce(Rocket) -> Result<Rocket, Rocket> + Send + 'static>>>),
Attach(Mutex<Option<Box<dyn FnOnce(Rocket) -> BoxFuture<'static, Result<Rocket, Rocket>> + Send + 'static>>>),
/// An ad-hoc **launch** fairing. Called just before Rocket launches.
Launch(Mutex<Option<Box<dyn FnOnce(&Manifest) + Send + 'static>>>),
/// An ad-hoc **request** fairing. Called when a request is received.
@ -66,12 +66,14 @@ impl AdHoc {
/// use rocket::fairing::AdHoc;
///
/// // The no-op attach fairing.
/// let fairing = AdHoc::on_attach("No-Op", |rocket| Ok(rocket));
/// let fairing = AdHoc::on_attach("No-Op", |rocket| async { Ok(rocket) });
/// ```
pub fn on_attach<F: Send + 'static>(name: &'static str, f: F) -> AdHoc
where F: FnOnce(Rocket) -> Result<Rocket, Rocket>
pub fn on_attach<F, Fut>(name: &'static str, f: F) -> AdHoc
where
F: FnOnce(Rocket) -> Fut + Send + 'static,
Fut: Future<Output=Result<Rocket, Rocket>> + Send + 'static,
{
AdHoc { name, kind: AdHocKind::Attach(Mutex::new(Some(Box::new(f)))) }
AdHoc { name, kind: AdHocKind::Attach(Mutex::new(Some(Box::new(|rocket| Box::pin(f(rocket)))))) }
}
/// Constructs an `AdHoc` launch fairing named `name`. The function `f` will
@ -153,11 +155,13 @@ impl Fairing for AdHoc {
Info { name: self.name, kind }
}
fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
async fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
if let AdHocKind::Attach(ref mutex) = self.kind {
let mut opt = mutex.lock().expect("AdHoc::Attach lock");
let f = opt.take().expect("internal error: `on_attach` one-call invariant broken");
f(rocket)
let f = mutex.lock()
.expect("AdHoc::Attach lock")
.take()
.expect("internal error: `on_attach` one-call invariant broken");
f(rocket).await
} else {
Ok(rocket)
}

View File

@ -20,12 +20,12 @@ impl Fairings {
Fairings::default()
}
pub fn attach(&mut self, fairing: Box<dyn Fairing>, mut rocket: Rocket) -> Rocket {
pub async fn attach(&mut self, fairing: Box<dyn Fairing>, mut rocket: Rocket) -> Rocket {
// Run the `on_attach` callback if this is an 'attach' fairing.
let kind = fairing.info().kind;
let name = fairing.info().name;
if kind.is(Kind::Attach) {
rocket = fairing.on_attach(rocket)
rocket = fairing.on_attach(rocket).await
.unwrap_or_else(|r| { self.attach_failures.push(name); r })
}

View File

@ -207,7 +207,7 @@ pub use self::info_kind::{Info, Kind};
/// # unimplemented!()
/// }
///
/// fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
/// async fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
/// /* ... */
/// # unimplemented!()
/// }
@ -415,7 +415,7 @@ pub trait Fairing: Send + Sync + 'static {
/// ## Default Implementation
///
/// The default implementation of this method simply returns `Ok(rocket)`.
fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> { Ok(rocket) }
async fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> { Ok(rocket) }
/// The launch callback.
///
@ -465,8 +465,8 @@ impl<T: Fairing> Fairing for std::sync::Arc<T> {
}
#[inline]
fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
(self as &T).on_attach(rocket)
async fn on_attach(&self, rocket: Rocket) -> Result<Rocket, Rocket> {
(self as &T).on_attach(rocket).await
}
#[inline]

View File

@ -55,13 +55,13 @@ use crate::error::LaunchError;
/// ```rust
/// use rocket::local::Client;
///
/// # let _ = async {
/// # rocket::async_test(async {
/// let rocket = rocket::ignite();
/// let client = Client::new(rocket).expect("valid rocket");
/// let client = Client::new(rocket).await.expect("valid rocket");
/// let response = client.post("/")
/// .body("Hello, world!")
/// .dispatch().await;
/// # };
/// # });
/// ```
///
/// [`new()`]: #method.new
@ -78,8 +78,8 @@ impl Client {
/// Constructs a new `Client`. If `tracked` is `true`, an empty `CookieJar`
/// is created for cookie tracking. Otherwise, the internal `CookieJar` is
/// set to `None`.
fn _new(rocket: Rocket, tracked: bool) -> Result<Client, LaunchError> {
let mut manifest = rocket.actualize_and_take_manifest();
async fn _new(rocket: Rocket, tracked: bool) -> Result<Client, LaunchError> {
let mut manifest = rocket.actualize_and_take_manifest().await;
manifest.prelaunch_check()?;
let cookies = match tracked {
@ -117,11 +117,13 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # let _ = async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// # };
/// ```
#[inline(always)]
pub fn new(rocket: Rocket) -> Result<Client, LaunchError> {
Client::_new(rocket, true)
pub async fn new(rocket: Rocket) -> Result<Client, LaunchError> {
Client::_new(rocket, true).await
}
/// Construct a new `Client` from an instance of `Rocket` _without_ cookie
@ -142,11 +144,13 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::untracked(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::untracked(rocket::ignite()).await.expect("valid rocket");
/// # });
/// ```
#[inline(always)]
pub fn untracked(rocket: Rocket) -> Result<Client, LaunchError> {
Client::_new(rocket, false)
pub async fn untracked(rocket: Rocket) -> Result<Client, LaunchError> {
Client::_new(rocket, false).await
}
/// Returns a reference to the `Manifest` of the `Rocket` this client is
@ -157,11 +161,13 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// # rocket::async_test(async {
/// let my_rocket = rocket::ignite();
/// let client = Client::new(my_rocket).expect("valid rocket");
/// let client = Client::new(my_rocket).await.expect("valid rocket");
///
/// // get access to the manifest within `client`
/// let manifest = client.manifest();
/// # });
/// ```
#[inline(always)]
pub fn manifest(&self) -> &Manifest {
@ -180,8 +186,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.get("/hello");
/// # });
/// ```
#[inline(always)]
pub fn get<'c, 'u: 'c, U: Into<Cow<'u, str>>>(&'c self, uri: U) -> LocalRequest<'c> {
@ -200,8 +208,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.put("/hello");
/// # });
/// ```
#[inline(always)]
pub fn put<'c, 'u: 'c, U: Into<Cow<'u, str>>>(&'c self, uri: U) -> LocalRequest<'c> {
@ -221,11 +231,13 @@ impl Client {
/// use rocket::local::Client;
/// use rocket::http::ContentType;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
///
/// let req = client.post("/hello")
/// .body("field=value&otherField=123")
/// .header(ContentType::Form);
/// # });
/// ```
#[inline(always)]
pub fn post<'c, 'u: 'c, U: Into<Cow<'u, str>>>(&'c self, uri: U) -> LocalRequest<'c> {
@ -244,8 +256,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.delete("/hello");
/// # });
/// ```
#[inline(always)]
pub fn delete<'c, 'u: 'c, U>(&'c self, uri: U) -> LocalRequest<'c>
@ -266,8 +280,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.options("/hello");
/// # });
/// ```
#[inline(always)]
pub fn options<'c, 'u: 'c, U>(&'c self, uri: U) -> LocalRequest<'c>
@ -288,8 +304,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.head("/hello");
/// # });
/// ```
#[inline(always)]
pub fn head<'c, 'u: 'c, U>(&'c self, uri: U) -> LocalRequest<'c>
@ -310,8 +328,10 @@ impl Client {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.patch("/hello");
/// # });
/// ```
#[inline(always)]
pub fn patch<'c, 'u: 'c, U>(&'c self, uri: U) -> LocalRequest<'c>
@ -333,8 +353,10 @@ impl Client {
/// use rocket::local::Client;
/// use rocket::http::Method;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.req(Method::Get, "/hello");
/// # });
/// ```
#[inline(always)]
pub fn req<'c, 'u: 'c, U>(&'c self, method: Method, uri: U) -> LocalRequest<'c>

View File

@ -23,8 +23,10 @@
//! ```rust
//! # use rocket::local::Client;
//! # let rocket = rocket::ignite();
//! let client = Client::new(rocket).expect("valid rocket instance");
//! # rocket::async_test(async {
//! let client = Client::new(rocket).await.expect("valid rocket instance");
//! # let _ = client;
//! # });
//! ```
//!
//! 3. Construct requests using the `Client` instance.
@ -32,9 +34,11 @@
//! ```rust
//! # use rocket::local::Client;
//! # let rocket = rocket::ignite();
//! # let client = Client::new(rocket).unwrap();
//! # rocket::async_test(async {
//! # let client = Client::new(rocket).await.unwrap();
//! let req = client.get("/");
//! # let _ = req;
//! # });
//! ```
//!
//! 3. Dispatch the request to retrieve the response.
@ -42,12 +46,12 @@
//! ```rust
//! # use rocket::local::Client;
//! # let rocket = rocket::ignite();
//! # let client = Client::new(rocket).unwrap();
//! # rocket::async_test(async {
//! # let client = Client::new(rocket).await.unwrap();
//! # let req = client.get("/");
//! # let _ = async {
//! let response = req.dispatch().await;
//! # let _ = response;
//! # };
//! # });
//! ```
//!
//! All together and in idiomatic fashion, this might look like:
@ -55,13 +59,13 @@
//! ```rust
//! use rocket::local::Client;
//!
//! # let _ = async {
//! let client = Client::new(rocket::ignite()).expect("valid rocket");
//! # rocket::async_test(async {
//! let client = Client::new(rocket::ignite()).await.expect("valid rocket");
//! let response = client.post("/")
//! .body("Hello, world!")
//! .dispatch().await;
//! # let _ = response;
//! # };
//! # });
//! ```
//!
//! # Unit/Integration Testing

View File

@ -28,12 +28,14 @@ use crate::local::Client;
/// use rocket::local::Client;
/// use rocket::http::{ContentType, Cookie};
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.post("/")
/// .header(ContentType::JSON)
/// .remote("127.0.0.1:8000".parse().unwrap())
/// .cookie(Cookie::new("name", "value"))
/// .body(r#"{ "value": 42 }"#);
/// # });
/// ```
///
/// # Dispatching
@ -125,9 +127,11 @@ impl<'c> LocalRequest<'c> {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).expect("valid rocket");
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.expect("valid rocket");
/// let req = client.get("/");
/// let inner_req = req.inner();
/// # });
/// ```
#[inline]
pub fn inner(&self) -> &Request<'c> {
@ -166,9 +170,11 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::ContentType;
///
/// # rocket::async_test(async {
/// # #[allow(unused_variables)]
/// let client = Client::new(rocket::ignite()).unwrap();
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let req = client.get("/").header(ContentType::JSON);
/// # });
/// ```
#[inline]
pub fn header<H: Into<Header<'static>>>(mut self, header: H) -> Self {
@ -186,9 +192,11 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::ContentType;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let mut req = client.get("/");
/// req.add_header(ContentType::JSON);
/// # });
/// ```
#[inline]
pub fn add_header<H: Into<Header<'static>>>(&mut self, header: H) {
@ -204,9 +212,11 @@ impl<'c> LocalRequest<'c> {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let address = "8.8.8.8:80".parse().unwrap();
/// let req = client.get("/").remote(address);
/// # });
/// ```
#[inline]
pub fn remote(mut self, address: SocketAddr) -> Self {
@ -224,11 +234,13 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::Cookie;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// # #[allow(unused_variables)]
/// let req = client.get("/")
/// .cookie(Cookie::new("username", "sb"))
/// .cookie(Cookie::new("user_id", "12"));
/// # });
/// ```
#[inline]
pub fn cookie(self, cookie: Cookie<'_>) -> Self {
@ -246,10 +258,12 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::Cookie;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let cookies = vec![Cookie::new("a", "b"), Cookie::new("c", "d")];
/// # #[allow(unused_variables)]
/// let req = client.get("/").cookies(cookies);
/// # });
/// ```
#[inline]
pub fn cookies(self, cookies: Vec<Cookie<'_>>) -> Self {
@ -275,9 +289,11 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::Cookie;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// # #[allow(unused_variables)]
/// let req = client.get("/").private_cookie(Cookie::new("user_id", "sb"));
/// # });
/// ```
#[inline]
#[cfg(feature = "private-cookies")]
@ -301,11 +317,13 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::ContentType;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// # #[allow(unused_variables)]
/// let req = client.post("/")
/// .header(ContentType::JSON)
/// .body(r#"{ "key": "value", "array": [1, 2, 3], }"#);
/// # });
/// ```
#[inline]
pub fn body<S: AsRef<[u8]>>(mut self, body: S) -> Self {
@ -323,9 +341,11 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
/// use rocket::http::ContentType;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let mut req = client.post("/").header(ContentType::JSON);
/// req.set_body(r#"{ "key": "value", "array": [1, 2, 3], }"#);
/// # });
/// ```
#[inline]
pub fn set_body<S: AsRef<[u8]>>(&mut self, body: S) {
@ -342,8 +362,10 @@ impl<'c> LocalRequest<'c> {
/// ```rust
/// use rocket::local::Client;
///
/// let client = Client::new(rocket::ignite()).unwrap();
/// # rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).await.unwrap();
/// let response = client.get("/").dispatch();
/// # });
/// ```
#[inline(always)]
pub async fn dispatch(mut self) -> LocalResponse<'c> {
@ -371,7 +393,7 @@ impl<'c> LocalRequest<'c> {
/// use rocket::local::Client;
///
/// rocket::async_test(async {
/// let client = Client::new(rocket::ignite()).unwrap();
/// let client = Client::new(rocket::ignite()).await.unwrap();
///
/// let mut req = client.get("/");
/// let response_a = req.mut_dispatch().await;

View File

@ -99,9 +99,11 @@ use crate::http::Status;
/// state.0.to_string()
/// }
///
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite().manage(MyManagedState(127));
/// let state = State::from(rocket.inspect()).expect("managing `MyManagedState`");
/// let state = State::from(rocket.inspect().await).expect("managing `MyManagedState`");
/// assert_eq!(handler(state), "127");
/// # });
/// ```
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct State<'r, T: Send + Sync + 'static>(&'r T);
@ -152,14 +154,16 @@ impl<'r, T: Send + Sync + 'static> State<'r, T> {
/// #[derive(Debug, PartialEq)]
/// struct Unmanaged(usize);
///
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite().manage(Managed(7));
/// let manifest = rocket.inspect();
/// let manifest = rocket.inspect().await;
///
/// let state: Option<State<Managed>> = State::from(manifest);
/// assert_eq!(state.map(|s| s.inner()), Some(&Managed(7)));
///
/// let state: Option<State<Unmanaged>> = State::from(manifest);
/// assert_eq!(state, None);
/// # });
/// ```
#[inline(always)]
pub fn from(manifest: &'r Manifest) -> Option<Self> {

View File

@ -52,7 +52,7 @@ impl<'r, R> Created<R> {
///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap();
/// # let client = Client::new(rocket).await.unwrap();
/// let mut response = client.get("/").dispatch().await;
///
/// let loc = response.headers().get_one("Location");
@ -84,7 +84,7 @@ impl<'r, R> Created<R> {
///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap();
/// # let client = Client::new(rocket).await.unwrap();
/// let mut response = client.get("/").dispatch().await;
///
/// let body = response.body_string().await;
@ -122,7 +122,7 @@ impl<'r, R> Created<R> {
///
/// # rocket::async_test(async move {
/// # let rocket = rocket::ignite().mount("/", routes![create]);
/// # let client = Client::new(rocket).unwrap();
/// # let client = Client::new(rocket).await.unwrap();
/// let mut response = client.get("/").dispatch().await;
///
/// let body = response.body_string().await;

View File

@ -407,13 +407,13 @@ impl Manifest {
}
#[inline]
fn _attach(mut self, fairing: Box<dyn Fairing>) -> Self {
async fn _attach(mut self, fairing: Box<dyn Fairing>) -> Self {
// Attach (and run attach) fairings, which requires us to move `self`.
let mut fairings = mem::replace(&mut self.fairings, Fairings::new());
let mut rocket = Rocket { manifest: Some(self), pending: vec![] };
rocket = fairings.attach(fairing, rocket);
self = rocket.actualize_and_take_manifest();
rocket = fairings.attach(fairing, rocket).await;
self = rocket.actualize_and_take_manifest().await;
// Make sure we keep all fairings around: the old and newly added ones!
fairings.append(self.fairings);
@ -811,33 +811,50 @@ impl Rocket {
self
}
pub(crate) fn actualize_manifest(&mut self) {
while !self.pending.is_empty() {
// We need to preserve insertion order here,
// so we can't use `self.pending.pop()`
let op = self.pending.remove(0);
let manifest = self.manifest.take().expect("TODO error message");
self.manifest = Some(match op {
BuildOperation::Mount(base, routes) => manifest._mount(base, routes),
BuildOperation::Register(catchers) => manifest._register(catchers),
BuildOperation::Manage(callback) => manifest._manage(callback),
BuildOperation::Attach(fairing) => manifest._attach(fairing),
});
}
// Instead of requiring the user to individually `await` each call to
// `attach()`, some operations are queued in `self.pending`. Functions that
// want to provide read access to any data from the Manifest, such as
// `inspect()`, need to apply those pending operations first.
//
// This function returns a future that executes those pending operations,
// requiring only a single `await` at the call site. After completion,
// `self.pending` will be empty and `self.manifest` will reflect all pending
// changes.
//
// Note that this returns a boxed future, because `_attach()` calls this
// function again creating a cycle.
pub(crate) fn actualize_manifest(&mut self) -> BoxFuture<'_, ()> {
Box::pin(async move {
while !self.pending.is_empty() {
// We need to preserve insertion order here,
// so we can't use `self.pending.pop()`
let op = self.pending.remove(0);
let manifest = self.manifest.take()
.expect("internal error: manifest was taken and not replaced. \
Was `inspect()` called but not polled to completion?");
self.manifest = Some(match op {
BuildOperation::Mount(base, routes) => manifest._mount(base, routes),
BuildOperation::Register(catchers) => manifest._register(catchers),
BuildOperation::Manage(callback) => manifest._manage(callback),
BuildOperation::Attach(fairing) => manifest._attach(fairing).await,
});
}
})
}
pub(crate) fn actualize_and_take_manifest(mut self) -> Manifest {
self.actualize_manifest();
pub(crate) async fn actualize_and_take_manifest(mut self) -> Manifest {
self.actualize_manifest().await;
self.manifest.take().expect("internal error: actualize_manifest() should have replaced self.manifest")
}
/// Returns a `Future` that drives the server, listening for and dispathcing
/// Returns a `Future` that drives the server, listening for and dispatching
/// requests to mounted routes and catchers. The `Future` completes when the
/// server is shut down (via a [`ShutdownHandle`] or encounters a fatal
/// server is shut down, via a [`ShutdownHandle`], or encounters a fatal
/// error. If the `ctrl_c_shutdown` feature is enabled, the server will
/// also shut down once `Ctrl-C` is pressed.
///
/// # Error
///
/// If there is a problem starting the application, an [`Error`] is
/// returned. Note that a value of type `Error` panics if dropped
/// without first being inspected. See the [`Error`] documentation for
@ -859,11 +876,10 @@ impl Rocket {
use crate::error::Error::Launch;
let mut manifest = self.actualize_and_take_manifest();
let mut manifest = self.actualize_and_take_manifest().await;
manifest.prelaunch_check().map_err(crate::error::Error::Launch)?;
let config = manifest.config();
let full_addr = format!("{}:{}", config.address, config.port);
let addrs = match full_addr.to_socket_addrs() {
Ok(a) => a.collect::<Vec<_>>(),
@ -961,13 +977,10 @@ impl Rocket {
/// rocket::ignite().launch();
/// # }
/// ```
pub fn launch(mut self) -> Result<(), crate::error::Error> {
let workers = self.inspect().config().workers as usize;
pub fn launch(self) -> Result<(), crate::error::Error> {
// Initialize the tokio runtime
let mut runtime = tokio::runtime::Builder::new()
.threaded_scheduler()
.core_threads(workers)
.enable_all()
.build()
.expect("Cannot build runtime!");
@ -976,24 +989,27 @@ impl Rocket {
}
pub(crate) fn _manifest(&self) -> &Manifest {
self.manifest.as_ref().expect("TODO error message")
self.manifest.as_ref().expect("internal error: manifest was taken and not replaced. \
Was `inspect()` called but not polled to completion?")
}
/// Access the current state of this `Rocket` instance.
///
/// The `Mnaifest` type provides methods such as [`Manifest::routes`]
/// and [`Manifest::state`]. This method is called to get an `Manifest`
/// The `Manifest` type provides methods such as [`Manifest::routes()`]
/// and [`Manifest::state()`]. This method is called to get a `Manifest`
/// instance.
///
/// # Example
///
/// ```rust
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite();
/// let config = rocket.inspect().config();
/// let config = rocket.inspect().await.config();
/// # let _ = config;
/// # });
/// ```
pub fn inspect(&mut self) -> &Manifest {
self.actualize_manifest();
pub async fn inspect(&mut self) -> &Manifest {
self.actualize_manifest().await;
self._manifest()
}
}
@ -1009,8 +1025,9 @@ impl Manifest {
/// # #![feature(proc_macro_hygiene)]
/// # use std::{thread, time::Duration};
/// #
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite();
/// let handle = rocket.inspect().get_shutdown_handle();
/// let handle = rocket.inspect().await.get_shutdown_handle();
///
/// # if false {
/// thread::spawn(move || {
@ -1022,6 +1039,7 @@ impl Manifest {
/// let shutdown_result = rocket.launch();
/// assert!(shutdown_result.is_ok());
/// # }
/// # });
/// ```
#[inline(always)]
pub fn get_shutdown_handle(&self) -> ShutdownHandle {
@ -1045,11 +1063,12 @@ impl Manifest {
/// }
///
/// fn main() {
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite()
/// .mount("/", routes![hello])
/// .mount("/hi", routes![hello]);
///
/// for route in rocket.inspect().routes() {
/// for route in rocket.inspect().await.routes() {
/// match route.base() {
/// "/" => assert_eq!(route.uri.path(), "/hello"),
/// "/hi" => assert_eq!(route.uri.path(), "/hi/hello"),
@ -1057,7 +1076,8 @@ impl Manifest {
/// }
/// }
///
/// assert_eq!(rocket.inspect().routes().count(), 2);
/// assert_eq!(rocket.inspect().await.routes().count(), 2);
/// # });
/// }
/// ```
#[inline(always)]
@ -1074,11 +1094,13 @@ impl Manifest {
/// #[derive(PartialEq, Debug)]
/// struct MyState(&'static str);
///
/// # rocket::async_test(async {
/// let mut rocket = rocket::ignite().manage(MyState("hello!"));
/// assert_eq!(rocket.inspect().state::<MyState>(), Some(&MyState("hello!")));
/// assert_eq!(rocket.inspect().await.state::<MyState>(), Some(&MyState("hello!")));
///
/// let client = rocket::local::Client::new(rocket).expect("valid rocket");
/// let client = rocket::local::Client::new(rocket).await.expect("valid rocket");
/// assert_eq!(client.manifest().state::<MyState>(), Some(&MyState("hello!")));
/// # });
/// ```
#[inline(always)]
pub fn state<T: Send + Sync + 'static>(&self) -> Option<&T> {

View File

@ -21,7 +21,7 @@ mod test_absolute_uris_okay {
#[rocket::async_test]
async fn redirect_works() {
let rocket = rocket::ignite().mount("/", routes![google, rocket]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let response = client.get("/google").dispatch().await;
let location = response.headers().get_one("Location");

View File

@ -22,7 +22,7 @@ mod conditionally_set_server_header {
#[rocket::async_test]
async fn do_not_overwrite_server_header() {
let rocket = rocket::ignite().mount("/", routes![do_not_overwrite, use_default]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let response = client.get("/do_not_overwrite").dispatch().await;
let server = response.headers().get_one("Server");

View File

@ -48,7 +48,7 @@ async fn test_derive_reexports() {
use rocket::local::Client;
let rocket = rocket::ignite().mount("/", routes![index, number]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "hello");

View File

@ -42,7 +42,7 @@ mod fairing_before_head_strip {
})
}));
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.head("/").dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert!(response.body().is_none());
@ -73,7 +73,7 @@ mod fairing_before_head_strip {
})
}));
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.head("/").dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert!(response.body().is_none());

View File

@ -30,7 +30,7 @@ mod flash_lazy_remove_tests {
async fn test() {
use super::*;
let r = rocket::ignite().mount("/", routes![set, unused, used]);
let client = Client::new(r).unwrap();
let client = Client::new(r).await.unwrap();
// Ensure the cookie's not there at first.
let response = client.get("/unused").dispatch().await;

View File

@ -22,7 +22,7 @@ mod tests {
#[rocket::async_test]
async fn method_eval() {
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
let client = Client::new(rocket::ignite().mount("/", routes![bug])).await.unwrap();
let mut response = client.post("/")
.header(ContentType::Form)
.body("_method=patch&form_data=Form+data")
@ -33,7 +33,7 @@ mod tests {
#[rocket::async_test]
async fn get_passes_through() {
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
let client = Client::new(rocket::ignite().mount("/", routes![bug])).await.unwrap();
let response = client.get("/")
.header(ContentType::Form)
.body("_method=patch&form_data=Form+data")

View File

@ -21,7 +21,7 @@ mod tests {
use rocket::http::Status;
async fn check_decoding(raw: &str, decoded: &str) {
let client = Client::new(rocket::ignite().mount("/", routes![bug])).unwrap();
let client = Client::new(rocket::ignite().mount("/", routes![bug])).await.unwrap();
let mut response = client.post("/")
.header(ContentType::Form)
.body(format!("form_data={}", raw))

View File

@ -47,7 +47,7 @@ mod head_handling_tests {
#[rocket::async_test]
async fn auto_head() {
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
let client = Client::new(rocket::ignite().mount("/", routes())).await.unwrap();
let mut response = client.head("/").dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert_empty_sized_body(response.body().unwrap(), 13).await;
@ -62,7 +62,7 @@ mod head_handling_tests {
#[rocket::async_test]
async fn user_head() {
let client = Client::new(rocket::ignite().mount("/", routes())).unwrap();
let client = Client::new(rocket::ignite().mount("/", routes())).await.unwrap();
let mut response = client.head("/other").dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert_empty_sized_body(response.body().unwrap(), 17).await;

View File

@ -30,7 +30,7 @@ mod limits_tests {
#[rocket::async_test]
async fn large_enough() {
let client = Client::new(rocket_with_forms_limit(128)).unwrap();
let client = Client::new(rocket_with_forms_limit(128)).await.unwrap();
let mut response = client.post("/")
.body("value=Hello+world")
.header(ContentType::Form)
@ -41,7 +41,7 @@ mod limits_tests {
#[rocket::async_test]
async fn just_large_enough() {
let client = Client::new(rocket_with_forms_limit(17)).unwrap();
let client = Client::new(rocket_with_forms_limit(17)).await.unwrap();
let mut response = client.post("/")
.body("value=Hello+world")
.header(ContentType::Form)
@ -52,7 +52,7 @@ mod limits_tests {
#[rocket::async_test]
async fn much_too_small() {
let client = Client::new(rocket_with_forms_limit(4)).unwrap();
let client = Client::new(rocket_with_forms_limit(4)).await.unwrap();
let response = client.post("/")
.body("value=Hello+world")
.header(ContentType::Form)
@ -63,7 +63,7 @@ mod limits_tests {
#[rocket::async_test]
async fn contracted() {
let client = Client::new(rocket_with_forms_limit(10)).unwrap();
let client = Client::new(rocket_with_forms_limit(10)).await.unwrap();
let mut response = client.post("/")
.body("value=Hello+world")
.header(ContentType::Form)

View File

@ -63,7 +63,7 @@ mod local_request_content_type_tests {
#[rocket::async_test]
async fn has_no_ct() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut req = client.post("/");
// assert_eq!(req.clone().dispatch().await.body_string().await, Some("Absent".to_string()));
@ -78,7 +78,7 @@ mod local_request_content_type_tests {
#[rocket::async_test]
async fn has_ct() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut req = client.post("/").header(ContentType::JSON);
// assert_eq!(req.clone().dispatch().await.body_string().await, Some("Present".to_string()));

View File

@ -26,7 +26,7 @@ mod private_cookie_test {
async fn private_cookie_is_returned() {
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let req = client.get("/").private_cookie(Cookie::new("cookie_name", "cookie_value"));
let mut response = req.dispatch().await;
@ -38,7 +38,7 @@ mod private_cookie_test {
async fn regular_cookie_is_not_returned() {
let rocket = rocket::ignite().mount("/", routes![return_private_cookie]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let req = client.get("/").cookie(Cookie::new("cookie_name", "cookie_value"));
let response = req.dispatch().await;

View File

@ -24,7 +24,7 @@ fn index(counter: State<'_, Counter>) -> String {
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![index])
.attach(AdHoc::on_attach("Outer", |rocket| {
.attach(AdHoc::on_attach("Outer", |rocket| async {
let counter = Counter::default();
counter.attach.fetch_add(1, Ordering::Relaxed);
let rocket = rocket.manage(counter)
@ -48,7 +48,7 @@ mod nested_fairing_attaches_tests {
#[rocket::async_test]
async fn test_counts() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("1, 1".into()));

View File

@ -37,7 +37,7 @@ mod tests {
macro_rules! check_dispatch {
($mount:expr, $ct:expr, $body:expr) => (
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut req = client.post($mount);
let ct: Option<ContentType> = $ct;
if let Some(ct) = ct {

View File

@ -16,7 +16,7 @@ mod tests {
#[rocket::async_test]
async fn error_catcher_redirect() {
let client = Client::new(rocket::ignite().register(catchers![not_found])).unwrap();
let client = Client::new(rocket::ignite().register(catchers![not_found])).await.unwrap();
let response = client.get("/unknown").dispatch().await;
println!("Response:\n{:?}", response);

View File

@ -26,7 +26,7 @@ mod route_guard_tests {
.mount("/first", routes![files])
.mount("/second", routes![files]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
assert_path(&client, "/first/some/path").await;
assert_path(&client, "/second/some/path").await;
assert_path(&client, "/first/second/b/c").await;

View File

@ -38,7 +38,7 @@ mod tests {
let rocket = rocket::ignite()
.mount("/", routes![test, two, one_two, none, dual])
.mount("/point", routes![test, two, one_two, dual]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
// We construct a path that matches each of the routes above. We ensure the
// prefix is stripped, confirming that dynamic segments are working.

View File

@ -27,13 +27,13 @@ mod strict_and_lenient_forms_tests {
const FIELD_VALUE: &str = "just_some_value";
fn client() -> Client {
Client::new(rocket::ignite().mount("/", routes![strict, lenient])).unwrap()
async fn client() -> Client {
Client::new(rocket::ignite().mount("/", routes![strict, lenient])).await.unwrap()
}
#[rocket::async_test]
async fn test_strict_form() {
let client = client();
let client = client().await;
let mut response = client.post("/strict")
.header(ContentType::Form)
.body(format!("field={}", FIELD_VALUE))
@ -52,7 +52,7 @@ mod strict_and_lenient_forms_tests {
#[rocket::async_test]
async fn test_lenient_form() {
let client = client();
let client = client().await;
let mut response = client.post("/lenient")
.header(ContentType::Form)
.body(format!("field={}", FIELD_VALUE))

View File

@ -35,7 +35,7 @@ mod tests {
#[rocket::async_test]
async fn uri_percent_encoding_redirect() {
let expected_location = vec!["/hello/John%5B%5D%7C%5C%25@%5E"];
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.get("/raw").dispatch().await;
let location: Vec<_> = response.headers().get("location").collect();
@ -50,7 +50,7 @@ mod tests {
#[rocket::async_test]
async fn uri_percent_encoding_get() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let name = Uri::percent_encode(NAME);
let mut response = client.get(format!("/hello/{}", name)).dispatch().await;
assert_eq!(response.status(), Status::Ok);

View File

@ -55,15 +55,15 @@ pub fn test_config(environment: Environment) {
std::env::set_var("ROCKET_ENV", environment.to_string());
let rocket = rocket::ignite()
.attach(AdHoc::on_attach("Local Config", |mut rocket| {
.attach(AdHoc::on_attach("Local Config", |mut rocket| async {
println!("Attaching local config.");
let config = rocket.inspect().config().clone();
let config = rocket.inspect().await.config().clone();
Ok(rocket.manage(LocalConfig(config)))
}))
.mount("/", routes![check_config]);
rocket::async_test(async move {
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let response = client.get("/check_config").dispatch().await;
assert_eq!(response.status(), Status::Ok);
})

View File

@ -9,7 +9,7 @@ async fn test<H>(method: Method, uri: &str, header: H, status: Status, body: Str
.mount("/hello", routes![super::get_hello, super::post_hello])
.register(catchers![super::not_found]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.req(method, uri).header(header).dispatch().await;
assert_eq!(response.status(), status);
assert_eq!(response.body_string().await, Some(body));

View File

@ -7,7 +7,7 @@ use rocket_contrib::templates::Template;
#[rocket::async_test]
async fn test_submit() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.post("/submit")
.header(ContentType::Form)
.body("message=Hello from Rocket!")
@ -23,7 +23,7 @@ async fn test_submit() {
async fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: String) {
// Attach a cookie if one is given.
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = match optional_cookie {
Some(cookie) => client.get("/").cookie(cookie).dispatch().await,
None => client.get("/").dispatch().await,
@ -35,7 +35,7 @@ async fn test_body(optional_cookie: Option<Cookie<'static>>, expected_body: Stri
#[rocket::async_test]
async fn test_index() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Render the template with an empty context.
let mut context: HashMap<&str, &str> = HashMap::new();

View File

@ -6,7 +6,7 @@ async fn test(uri: &str, status: Status, body: String) {
.mount("/", routes![super::hello])
.register(catchers![super::not_found]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get(uri).dispatch().await;
assert_eq!(response.status(), status);
assert_eq!(response.body_string().await, Some(body));

View File

@ -67,9 +67,9 @@ fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![hello, token])
.attach(Counter::default())
.attach(AdHoc::on_attach("Token State", |mut rocket| {
.attach(AdHoc::on_attach("Token State", |mut rocket| async {
println!("Adding token managed state...");
let token_val = rocket.inspect().config().get_int("token").unwrap_or(-1);
let token_val = rocket.inspect().await.config().get_int("token").unwrap_or(-1);
Ok(rocket.manage(Token(token_val)))
}))
.attach(AdHoc::on_launch("Launch Message", |_| {

View File

@ -3,14 +3,14 @@ use rocket::local::Client;
#[rocket::async_test]
async fn rewrite_get_put() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Hello, fairings!".into()));
}
#[rocket::async_test]
async fn counts() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Issue 1 GET request.
client.get("/").dispatch().await;
@ -30,7 +30,7 @@ async fn counts() {
#[rocket::async_test]
async fn token() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Ensure the token is '123', which is what we have in `Rocket.toml`.
let mut res = client.get("/token").dispatch().await;

View File

@ -14,31 +14,29 @@ impl fmt::Display for FormOption {
}
}
fn assert_form_eq(client: &Client, form_str: &str, expected: String) {
rocket::async_test(async move {
let mut res = client.post("/")
.header(ContentType::Form)
.body(form_str)
.dispatch().await;
async fn assert_form_eq(client: &Client, form_str: &str, expected: String) {
let mut res = client.post("/")
.header(ContentType::Form)
.body(form_str)
.dispatch().await;
assert_eq!(res.body_string().await, Some(expected));
})
assert_eq!(res.body_string().await, Some(expected));
}
fn assert_valid_form(client: &Client, input: &FormInput<'_>) {
async fn assert_valid_form(client: &Client, input: &FormInput<'_>) {
let f = format!("checkbox={}&number={}&type={}&password={}&textarea={}&select={}",
input.checkbox, input.number, input.radio, input.password,
input.text_area, input.select);
assert_form_eq(client, &f, format!("{:?}", input));
assert_form_eq(client, &f, format!("{:?}", input)).await;
}
fn assert_valid_raw_form(client: &Client, form_str: &str, input: &FormInput<'_>) {
assert_form_eq(client, form_str, format!("{:?}", input));
async fn assert_valid_raw_form(client: &Client, form_str: &str, input: &FormInput<'_>) {
assert_form_eq(client, form_str, format!("{:?}", input)).await;
}
#[test]
fn test_good_forms() {
let client = Client::new(rocket()).unwrap();
#[rocket::async_test]
async fn test_good_forms() {
let client = Client::new(rocket()).await.unwrap();
let mut input = FormInput {
checkbox: true,
number: 310,
@ -48,137 +46,137 @@ fn test_good_forms() {
select: FormOption::B
};
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.checkbox = false;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.number = 0;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.number = 120;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.number = 133;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.radio = FormOption::B;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.radio = FormOption::C;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.password = "".into();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.password = "----90138490285u2o3hndslkv".into();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.password = "hi".into();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.text_area = "".to_string();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.text_area = "----90138490285u2o3hndslkv".to_string();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.text_area = "hey".to_string();
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.select = FormOption::A;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
input.select = FormOption::C;
assert_valid_form(&client, &input);
assert_valid_form(&client, &input).await;
// checkbox need not be present; defaults to false; accepts 'on' and 'off'
assert_valid_raw_form(&client,
"number=133&type=c&password=hi&textarea=hey&select=c",
&input);
&input).await;
assert_valid_raw_form(&client,
"checkbox=off&number=133&type=c&password=hi&textarea=hey&select=c",
&input);
&input).await;
input.checkbox = true;
assert_valid_raw_form(&client,
"checkbox=on&number=133&type=c&password=hi&textarea=hey&select=c",
&input);
&input).await;
}
fn assert_invalid_form(client: &Client, vals: &mut [&str; 6]) {
async fn assert_invalid_form(client: &Client, vals: &mut [&str; 6]) {
let s = format!("checkbox={}&number={}&type={}&password={}&textarea={}&select={}",
vals[0], vals[1], vals[2], vals[3], vals[4], vals[5]);
assert_form_eq(client, &s, format!("Invalid form input: {}", s));
assert_form_eq(client, &s, format!("Invalid form input: {}", s)).await;
*vals = ["true", "1", "a", "hi", "hey", "b"];
}
fn assert_invalid_raw_form(client: &Client, form_str: &str) {
assert_form_eq(client, form_str, format!("Invalid form input: {}", form_str));
async fn assert_invalid_raw_form(client: &Client, form_str: &str) {
assert_form_eq(client, form_str, format!("Invalid form input: {}", form_str)).await;
}
#[test]
fn check_semantically_invalid_forms() {
let client = Client::new(rocket()).unwrap();
#[rocket::async_test]
async fn check_semantically_invalid_forms() {
let client = Client::new(rocket()).await.unwrap();
let mut form_vals = ["true", "1", "a", "hi", "hey", "b"];
form_vals[0] = "not true";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[0] = "bing";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[0] = "true0";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[0] = " false";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[1] = "-1";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[1] = "1e10";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[1] = "-1-1";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[1] = "NaN";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[2] = "A?";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[2] = " B";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[2] = "d";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[2] = "100";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[2] = "";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
// password and textarea are always valid, so we skip them
form_vals[5] = "A.";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[5] = "b ";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[5] = "d";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[5] = "-a";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
form_vals[5] = "";
assert_invalid_form(&client, &mut form_vals);
assert_invalid_form(&client, &mut form_vals).await;
// now forms with missing fields
assert_invalid_raw_form(&client, "number=10&type=a&password=hi&textarea=hey");
assert_invalid_raw_form(&client, "number=10&radio=a&password=hi&textarea=hey&select=b");
assert_invalid_raw_form(&client, "number=10&password=hi&select=b");
assert_invalid_raw_form(&client, "number=10&select=b");
assert_invalid_raw_form(&client, "password=hi&select=b");
assert_invalid_raw_form(&client, "password=hi");
assert_invalid_raw_form(&client, "");
assert_invalid_raw_form(&client, "number=10&type=a&password=hi&textarea=hey").await;
assert_invalid_raw_form(&client, "number=10&radio=a&password=hi&textarea=hey&select=b").await;
assert_invalid_raw_form(&client, "number=10&password=hi&select=b").await;
assert_invalid_raw_form(&client, "number=10&select=b").await;
assert_invalid_raw_form(&client, "password=hi&select=b").await;
assert_invalid_raw_form(&client, "password=hi").await;
assert_invalid_raw_form(&client, "").await;
}
#[test]
fn check_structurally_invalid_forms() {
let client = Client::new(rocket()).unwrap();
assert_invalid_raw_form(&client, "==&&&&&&==");
assert_invalid_raw_form(&client, "a&=b");
assert_invalid_raw_form(&client, "=");
#[rocket::async_test]
async fn check_structurally_invalid_forms() {
let client = Client::new(rocket()).await.unwrap();
assert_invalid_raw_form(&client, "==&&&&&&==").await;
assert_invalid_raw_form(&client, "a&=b").await;
assert_invalid_raw_form(&client, "=").await;
}
#[test]
fn check_bad_utf8() {
let client = Client::new(rocket()).unwrap();
#[rocket::async_test]
async fn check_bad_utf8() {
let client = Client::new(rocket()).await.unwrap();
unsafe {
let bad_str = std::str::from_utf8_unchecked(b"a=\xff");
assert_form_eq(&client, bad_str, "Form input was invalid UTF-8.".into());
assert_form_eq(&client, bad_str, "Form input was invalid UTF-8.".into()).await;
}
}

View File

@ -6,7 +6,7 @@ fn test_login<T>(user: &str, pass: &str, age: &str, status: Status, body: T)
where T: Into<Option<&'static str>> + Send
{
rocket::async_test(async move {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let query = format!("username={}&password={}&age={}", user, pass, age);
let mut response = client.post("/login")
.header(ContentType::Form)
@ -47,7 +47,7 @@ fn test_invalid_age() {
fn check_bad_form(form_str: &str, status: Status) {
rocket::async_test(async {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.post("/login")
.header(ContentType::Form)
.body(form_str)

View File

@ -7,7 +7,7 @@ use rocket_contrib::templates::Template;
macro_rules! dispatch {
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
let $client = Client::new(rocket()).unwrap();
let $client = Client::new(rocket()).await.unwrap();
let mut $response = $client.req($method, $path).dispatch().await;
$body
})

View File

@ -3,7 +3,7 @@ use rocket::{self, routes, local::Client};
#[rocket::async_test]
async fn hello_world() {
let rocket = rocket::ignite().mount("/", routes![super::hello]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Hello, Rust 2018!".into()));
}
@ -36,14 +36,14 @@ mod scoped_uri_tests {
#[rocket::async_test]
async fn test_inner_hello() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Hello! Try /Rust%202018.".into()));
}
#[rocket::async_test]
async fn test_hello_name() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/Rust%202018").dispatch().await;
assert_eq!(response.body_string().await.unwrap(), "Hello, Rust 2018! This is /Rust%202018.");
}

View File

@ -1,17 +1,17 @@
use rocket::local::Client;
use rocket::http::Status;
fn client() -> Client {
Client::new(rocket::ignite().mount("/", routes![super::hello, super::hi])).unwrap()
async fn client() -> Client {
Client::new(rocket::ignite().mount("/", routes![super::hello, super::hi])).await.unwrap()
}
async fn test(uri: String, expected: String) {
let client = client();
let client = client().await;
assert_eq!(client.get(&uri).dispatch().await.body_string().await, Some(expected));
}
async fn test_404(uri: &'static str) {
let client = client();
let client = client().await;
assert_eq!(client.get(uri).dispatch().await.status(), Status::NotFound);
}

View File

@ -3,7 +3,7 @@ use rocket::local::Client;
#[rocket::async_test]
async fn hello_world() {
let rocket = rocket::ignite().mount("/", routes![super::hello]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Hello, world!".into()));
}

View File

@ -4,7 +4,7 @@ use rocket::http::{Status, ContentType};
#[rocket::async_test]
async fn bad_get_put() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Try to get a message with an ID that doesn't exist.
let mut res = client.get("/message/99").header(ContentType::JSON).dispatch().await;
@ -35,7 +35,7 @@ async fn bad_get_put() {
#[rocket::async_test]
async fn post_get_put_get() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Check that a message with ID 1 doesn't exist.
let res = client.get("/message/1").header(ContentType::JSON).dispatch().await;

View File

@ -3,7 +3,7 @@ use rocket::http::Status;
#[rocket::async_test]
async fn test_push_pop() {
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let response = client.put("/push?event=test1").dispatch().await;
assert_eq!(response.status(), Status::Ok);

View File

@ -4,7 +4,7 @@ use rocket::http::{ContentType, Status};
fn test(uri: &str, content_type: ContentType, status: Status, body: String) {
rocket::async_test(async move {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get(uri).header(content_type).dispatch().await;
assert_eq!(response.status(), status);
assert_eq!(response.body_string().await, Some(body));
@ -32,7 +32,7 @@ fn test_echo() {
#[rocket::async_test]
async fn test_upload() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let expected_body = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, \
sed do eiusmod tempor incididunt ut labore et dolore \
magna aliqua".to_string();

View File

@ -10,7 +10,7 @@ struct Message {
#[rocket::async_test]
async fn msgpack_get() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut res = client.get("/message/1").header(ContentType::MsgPack).dispatch().await;
assert_eq!(res.status(), Status::Ok);
assert_eq!(res.content_type(), Some(ContentType::MsgPack));
@ -23,7 +23,7 @@ async fn msgpack_get() {
#[rocket::async_test]
async fn msgpack_post() {
// Dispatch request with a message of `[2, "Goodbye, world!"]`.
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut res = client.post("/message")
.header(ContentType::MsgPack)
.body(&[146, 2, 175, 71, 111, 111, 100, 98, 121, 101, 44, 32, 119, 111, 114, 108, 100, 33])

View File

@ -1,22 +1,22 @@
use rocket::local::Client;
use rocket::http::Status;
fn client() -> Client {
async fn client() -> Client {
let rocket = rocket::ignite()
.mount("/", routes![super::root, super::user, super::login]);
Client::new(rocket).unwrap()
Client::new(rocket).await.unwrap()
}
async fn test_200(uri: &str, expected_body: &str) {
let client = client();
let client = client().await;
let mut response = client.get(uri).dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.body_string().await, Some(expected_body.to_string()));
}
async fn test_303(uri: &str, expected_location: &str) {
let client = client();
let client = client().await;
let response = client.get(uri).dispatch().await;
let location_headers: Vec<_> = response.headers().get("Location").collect();
assert_eq!(response.status(), Status::SeeOther);

View File

@ -8,7 +8,7 @@ fn extract_id(from: &str) -> Option<String> {
#[rocket::async_test]
async fn check_index() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Ensure the index returns what we expect.
let mut response = client.get("/").dispatch().await;
@ -32,7 +32,7 @@ async fn download_paste(client: &Client, id: &str) -> String {
#[rocket::async_test]
async fn pasting() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
// Do a trivial upload, just to make sure it works.
let body_1 = "Hello, world!";

View File

@ -4,7 +4,7 @@ use rocket::http::Status;
macro_rules! run_test {
($query:expr, |$response:ident| $body:expr) => ({
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
#[allow(unused_mut)]
let mut $response = client.get(format!("/hello{}", $query)).dispatch().await;
$body

View File

@ -2,7 +2,7 @@ use rocket::local::Client;
async fn test(uri: String, expected: String) {
let rocket = rocket::ignite().mount("/", routes![super::hello, super::hi]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get(&uri).dispatch().await;
assert_eq!(response.body_string().await, Some(expected));
}

View File

@ -3,7 +3,7 @@ use rocket::local::Client;
#[rocket::async_test]
async fn hello() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Rocketeer".into()));
}

View File

@ -9,7 +9,7 @@ const UPLOAD_CONTENTS: &str = "Hey! I'm going to be uploaded. :D Yay!";
#[rocket::async_test]
async fn test_index() {
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let mut res = client.get("/").dispatch().await;
assert_eq!(res.body_string().await, Some(super::index().to_string()));
}
@ -21,7 +21,7 @@ async fn test_raw_upload() {
let _ = fs::remove_file(&upload_file);
// Do the upload. Make sure we get the expected results.
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let mut res = client.post("/upload")
.header(ContentType::Plain)
.body(UPLOAD_CONTENTS)

View File

@ -1,14 +1,14 @@
use rocket::local::Client;
use rocket::http::Status;
fn client() -> Client {
async fn client() -> Client {
let rocket = rocket::ignite().mount("/", routes![super::root, super::login]);
Client::new(rocket).unwrap()
Client::new(rocket).await.unwrap()
}
#[rocket::async_test]
async fn test_root() {
let client = client();
let client = client().await;
let mut response = client.get("/").dispatch().await;
assert!(response.body().is_none());
@ -24,7 +24,7 @@ async fn test_root() {
#[rocket::async_test]
async fn test_login() {
let client = client();
let client = client().await;
let mut r = client.get("/login").dispatch().await;
assert_eq!(r.body_string().await, Some("Hi! Please log in before continuing.".into()));
}

View File

@ -36,7 +36,7 @@ mod test {
use rocket::http::Header;
async fn test_header_count<'h>(headers: Vec<Header<'static>>) {
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let mut req = client.get("/");
for header in headers.iter().cloned() {
req.add_header(header);

View File

@ -5,7 +5,7 @@ use rocket::local::Client;
#[rocket::async_test]
async fn test() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
client.get("/sync").dispatch().await;
let atomics = client.manifest().state::<Atomics>().unwrap();

View File

@ -24,7 +24,7 @@ async fn login(client: &Client, user: &str, pass: &str) -> Option<Cookie<'static
#[rocket::async_test]
async fn redirect_on_index() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let response = client.get("/").dispatch().await;
assert_eq!(response.status(), Status::SeeOther);
assert_eq!(response.headers().get_one("Location"), Some("/login"));
@ -32,7 +32,7 @@ async fn redirect_on_index() {
#[rocket::async_test]
async fn can_login() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/login").dispatch().await;
let body = response.body_string().await.unwrap();
@ -42,14 +42,14 @@ async fn can_login() {
#[rocket::async_test]
async fn login_fails() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
assert!(login(&client, "Seergio", "password").await.is_none());
assert!(login(&client, "Sergio", "idontknow").await.is_none());
}
#[rocket::async_test]
async fn login_logout_succeeds() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let login_cookie = login(&client, "Sergio", "password").await.expect("logged in");
// Ensure we're logged in.

View File

@ -13,7 +13,7 @@ async fn get_count(client: &Client) -> usize {
#[rocket::async_test]
async fn test_count() {
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
// Count should start at 0.
assert_eq!(get_count(&client).await, 0);
@ -25,13 +25,13 @@ async fn test_count() {
assert_eq!(get_count(&client).await, 100);
}
#[test]
fn test_raw_state_count() {
#[rocket::async_test]
async fn test_raw_state_count() {
use rocket::State;
use super::{count, index};
let mut rocket = super::rocket();
let manifest = rocket.inspect();
let manifest = rocket.inspect().await;
assert_eq!(count(State::from(manifest).unwrap()), "0");
assert!(index(State::from(manifest).unwrap()).0.contains("Visits: 1"));

View File

@ -9,7 +9,7 @@ use super::rocket;
async fn test_query_file<T> (path: &str, file: T, status: Status)
where T: Into<Option<&'static str>>
{
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get(path).dispatch().await;
assert_eq!(response.status(), status);

View File

@ -5,7 +5,7 @@ use rocket::local::Client;
#[rocket::async_test]
async fn test_root() {
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let mut res = client.get("/").dispatch().await;
// Check that we have exactly 25,000 'a'.
@ -24,7 +24,7 @@ async fn test_file() {
file.write_all(CONTENTS.as_bytes()).expect("write to big_file");
// Get the big file contents, hopefully.
let client = Client::new(super::rocket()).unwrap();
let client = Client::new(super::rocket()).await.unwrap();
let mut res = client.get("/big_file").dispatch().await;
assert_eq!(res.body_string().await, Some(CONTENTS.into()));

View File

@ -6,7 +6,7 @@ use rocket_contrib::templates::Template;
macro_rules! dispatch {
($method:expr, $path:expr, |$client:ident, $response:ident| $body:expr) => ({
let $client = Client::new(rocket()).unwrap();
let $client = Client::new(rocket()).await.unwrap();
let mut $response = $client.req($method, $path).dispatch().await;
$body
})

View File

@ -23,7 +23,7 @@ mod test {
#[rocket::async_test]
async fn test_hello() {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.body_string().await, Some("Hello, world!".into()));

View File

@ -3,7 +3,7 @@ use rocket::local::Client;
#[rocket::async_test]
async fn hello_world() {
let rocket = rocket::ignite().mount("/", routes![super::hello]);
let client = Client::new(rocket).unwrap();
let client = Client::new(rocket).await.unwrap();
let mut response = client.get("/").dispatch().await;
assert_eq!(response.body_string().await, Some("Hello, world!".into()));
}

View File

@ -93,8 +93,8 @@ fn index(msg: Option<FlashMessage<'_, '_>>, conn: DbConn) -> Template {
})
}
fn run_db_migrations(mut rocket: Rocket) -> Result<Rocket, Rocket> {
let conn = DbConn::get_one(rocket.inspect()).expect("database connection");
async fn run_db_migrations(mut rocket: Rocket) -> Result<Rocket, Rocket> {
let conn = DbConn::get_one(rocket.inspect().await).expect("database connection");
match embedded_migrations::run(&*conn) {
Ok(()) => Ok(rocket),
Err(e) => {

View File

@ -17,8 +17,8 @@ macro_rules! run_test {
rocket::async_test(async move {
let mut rocket = super::rocket();
let db = super::DbConn::get_one(rocket.inspect());
let $client = Client::new(rocket).expect("Rocket client");
let db = super::DbConn::get_one(rocket.inspect().await);
let $client = Client::new(rocket).await.expect("Rocket client");
let $conn = db.expect("failed to get database connection for testing");
Task::delete_all(&$conn).expect("failed to delete all tasks for testing");

View File

@ -3,13 +3,13 @@ use rocket::local::Client;
use rocket::http::Status;
async fn test(uri: &str, expected: &str) {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let mut res = client.get(uri).dispatch().await;
assert_eq!(res.body_string().await, Some(expected.into()));
}
async fn test_404(uri: &str) {
let client = Client::new(rocket()).unwrap();
let client = Client::new(rocket()).await.unwrap();
let res = client.get(uri).dispatch().await;
assert_eq!(res.status(), Status::NotFound);
}

View File

@ -210,7 +210,7 @@ fn main() {
rocket::ignite()
.mount("/", routes![assets])
.attach(AdHoc::on_attach("Assets Config", |mut rocket| {
let assets_dir = rocket.inspect().config()
let assets_dir = rocket.inspect().await.config()
.get_str("assets_dir")
.unwrap_or("assets/")
.to_string();