Skip to content

Commit

Permalink
add runtime_http and runtime_https (#67)
Browse files Browse the repository at this point in the history
* add runtime_http and runtime_https

* doc for runtime features
  • Loading branch information
yanganto authored Aug 28, 2023
1 parent e30d6d5 commit 4af2eec
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "test-with"
version = "0.10.1"
version = "0.10.2"
authors = ["Antonio Yang <[email protected]>"]
edition = "2021"
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,10 @@ We can let an example to do thing that cargo test runner do, and ignore testcase
The testcase of in the example will not in `#[cfg(test)]` or `#[test]` anymore, and use `#[test_with::runtime_*]`,
the test runner will treat it as the test in Rust and also provide the same summary as `cargo test`.

The `runtime` feature should be enabled and also include the `libtest-with` in `Cargo.toml`
The `runtime` feature should be enabled and include as normal dependency, and also include the `libtest-with` with corresponding features in `Cargo.toml`.
```toml
test-with = { version = "0.10", features = ["runtime"] }
libtest-with = "0.6.1-0"
libtest-with = { version = "0.6.1-1", features = ["net", "resource", "user", "executable"] }
```

Create an example with the following runtime macros (`test_with::runner!`, `#[test_with::module]`, `#[test_with::runtime_env()]`).
Expand Down
2 changes: 1 addition & 1 deletion examples/runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ edition = "2021"

[dependencies]
test-with = { path = "../../", features = ["runtime"] }
libtest-with = "0.6.1-0"
libtest-with = { version = "0.6.1-1", features = ["net", "resource", "user", "executable"]}
20 changes: 16 additions & 4 deletions examples/runner/examples/test.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
test_with::runner!(env, file, path);
test_with::runner!(env, file, path, net);

#[test_with::module]
mod env {
#[test_with::runtime_env(PWD)]
fn test_works() {
fn env_test_works() {
assert!(true);
}

Expand All @@ -28,7 +28,7 @@ mod env {
// }

#[test_with::runtime_env(PWD, SAYING)]
fn test_works_too() {
fn env_test_works_too() {
assert!(true);
}

Expand All @@ -46,7 +46,7 @@ mod env {
#[test_with::module]
mod file {
#[test_with::runtime_file(/etc/hostname)]
fn test_works() {
fn file_test_works() {
assert!(true);
}
}
Expand All @@ -58,3 +58,15 @@ mod path {
assert!(true);
}
}

#[test_with::module]
mod net {
#[test_with::runtime_http(httpbin.org)]
fn http_test_works() {
assert!(true);
}
#[test_with::runtime_https(httpbin.org)]
fn https_test_works() {
assert!(true);
}
}
136 changes: 135 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@
//! The solution to have a real runtime condition check, we need to put the test as normal function
//! as an example, then use `cargo run --example`
//! The `test-with` need be included as normal dependency with `runtime` feature.
//! And also include the `libtest-with` with corresponding features in `Cargo.toml`
//! [macro@runner] and [macro@module] are for the basic skeleton of the test runner.
//! [macro@runtime_env], [macro@runtime_no_env], [macro@runtime_file] and [macro@runtime_path] are
//! [macro@runtime_env], [macro@runtime_no_env], [macro@runtime_file], [macro@runtime_path] and
//! [macro@runtime_http] are
//! used to transform a normal function to a
//! testcase.
//!
//! ```toml
//! [dependencies]
//! test-with = { version = "*", default-features = false, features = ["runtime"] }
//! libtest-with = { version = "0.6.1-1", features = ["net", "resource", "user", "executable"] }
//! ```
//!
//! ```rust
Expand Down Expand Up @@ -57,6 +60,7 @@ use syn::{parse_macro_input, ItemFn, ItemMod};

#[cfg(feature = "runtime")]
use syn::Item;

#[cfg(feature = "resource")]
use sysinfo::SystemExt;
#[cfg(feature = "executable")]
Expand Down Expand Up @@ -627,6 +631,71 @@ fn check_http_condition(attr_str: String) -> (bool, String) {
(missing_links.is_empty(), ignore_msg)
}

/// Run test case when the example running and the http service exist.
///```rust
/// // write as example in exmaples/*rs
/// test_with::runner!(http);
/// #[test_with::module]
/// mod http {
/// #[test_with::runtime_http(httpbin.org)]
/// fn test_works() {
/// assert!(true);
/// }
/// }
#[cfg(not(feature = "runtime"))]
#[proc_macro_attribute]
#[proc_macro_error]
pub fn runtime_http(_attr: TokenStream, _stream: TokenStream) -> TokenStream {
panic!("should be used with runtime feature")
}

#[cfg(all(feature = "runtime", feature = "http"))]
#[proc_macro_attribute]
#[proc_macro_error]
pub fn runtime_http(attr: TokenStream, stream: TokenStream) -> TokenStream {
let attr_str = attr.to_string().replace(' ', "");
let links: Vec<&str> = attr_str.split(',').collect();
let ItemFn {
attrs,
vis,
sig,
block,
} = parse_macro_input!(stream as ItemFn);
let syn::Signature { ident, .. } = sig.clone();
let check_ident = syn::Ident::new(
&format!("_check_{}", ident.to_string()),
proc_macro2::Span::call_site(),
);
quote::quote! {
fn #check_ident() -> Result<(), libtest_with::Failed> {

let mut missing_links = vec![];
let client = libtest_with::reqwest::blocking::Client::new();
#(
if client.head(&format!("http://{}", #links)).send().is_err() {
missing_links.push(format!("http://{}", #links));
}
)*
match missing_links.len() {
0 => #ident(),
1 => return Err(
format!("{}because {} not response",
libtest_with::RUNTIME_IGNORE_PREFIX, missing_links[0]
).into()),
_ => return Err(
format!("{}because following links not response: \n{}\n",
libtest_with::RUNTIME_IGNORE_PREFIX, missing_links.join(", ")
).into()),
}
Ok(())
}

#(#attrs)*
#vis #sig #block
}
.into()
}

/// Run test case when the https service exist.
/// ```
/// #[cfg(test)]
Expand Down Expand Up @@ -687,6 +756,71 @@ fn check_https_condition(attr_str: String) -> (bool, String) {
(missing_links.is_empty(), ignore_msg)
}

/// Run test case when the example running and the http service exist.
///```rust
/// // write as example in exmaples/*rs
/// test_with::runner!(http);
/// #[test_with::module]
/// mod http {
/// #[test_with::runtime_https(httpbin.org)]
/// fn test_works() {
/// assert!(true);
/// }
/// }
#[cfg(not(feature = "runtime"))]
#[proc_macro_attribute]
#[proc_macro_error]
pub fn runtime_https(_attr: TokenStream, _stream: TokenStream) -> TokenStream {
panic!("should be used with runtime feature")
}

#[cfg(all(feature = "runtime", feature = "http"))]
#[proc_macro_attribute]
#[proc_macro_error]
pub fn runtime_https(attr: TokenStream, stream: TokenStream) -> TokenStream {
let attr_str = attr.to_string().replace(' ', "");
let links: Vec<&str> = attr_str.split(',').collect();
let ItemFn {
attrs,
vis,
sig,
block,
} = parse_macro_input!(stream as ItemFn);
let syn::Signature { ident, .. } = sig.clone();
let check_ident = syn::Ident::new(
&format!("_check_{}", ident.to_string()),
proc_macro2::Span::call_site(),
);
quote::quote! {
fn #check_ident() -> Result<(), libtest_with::Failed> {

let mut missing_links = vec![];
let client = libtest_with::reqwest::blocking::Client::new();
#(
if client.head(&format!("https://{}", #links)).send().is_err() {
missing_links.push(format!("https://{}", #links));
}
)*
match missing_links.len() {
0 => #ident(),
1 => return Err(
format!("{}because {} not response",
libtest_with::RUNTIME_IGNORE_PREFIX, missing_links[0]
).into()),
_ => return Err(
format!("{}because following links not response: \n{}\n",
libtest_with::RUNTIME_IGNORE_PREFIX, missing_links.join(", ")
).into()),
}
Ok(())
}

#(#attrs)*
#vis #sig #block
}
.into()
}

/// Run test case when the server online.
/// Please make sure the role of test case runner have capability to open socket
///
Expand Down

0 comments on commit 4af2eec

Please sign in to comment.