diff --git a/examples/runner/examples/test.rs b/examples/runner/examples/test.rs index 47137c9..f4cfffc 100644 --- a/examples/runner/examples/test.rs +++ b/examples/runner/examples/test.rs @@ -73,4 +73,8 @@ mod net { fn test_ignored_with_non_existing_host() { panic!("should be ignored with non existing host") } + #[test_with::runtime_tcp(8.8.8.8:53)] + fn test_works_with_domain_name_server() { + assert!(true); + } } diff --git a/src/lib.rs b/src/lib.rs index b508d0c..be1f6be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1011,6 +1011,72 @@ fn check_tcp_condition(attr_str: String) -> (bool, String) { (missing_sockets.is_empty(), ignore_msg) } +/// Run test case when socket connected +///```rust +/// // write as example in exmaples/*rs +/// test_with::runner!(tcp); +/// #[test_with::module] +/// mod tcp { +/// // Google DNS is online +/// #[test_with::runtime_tcp(8.8.8.8:53)] +/// fn test_works_with_DNS_server() { +/// assert!(true); +/// } +/// } +#[cfg(not(feature = "runtime"))] +#[proc_macro_attribute] +#[proc_macro_error] +pub fn runtime_tcp(_attr: TokenStream, _stream: TokenStream) -> TokenStream { + panic!("should be used with runtime feature") +} + +#[cfg(all(feature = "runtime"))] +#[proc_macro_attribute] +#[proc_macro_error] +pub fn runtime_tcp(attr: TokenStream, stream: TokenStream) -> TokenStream { + let attr_str = attr.to_string().replace(' ', ""); + let sockets: 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_sockets = vec![]; + let client = libtest_with::reqwest::blocking::Client::new(); + #( + if client.head(&format!("https://{}", #sockets)).send().is_err() { + missing_sockets.push(format!("https://{}", #sockets)); + } + )* + match missing_sockets.len() { + 0 => #ident(), + 1 => return Err( + format!("{}because {} not response", + libtest_with::RUNTIME_IGNORE_PREFIX, missing_sockets[0] + ).into()), + _ => return Err( + format!("{}because following sockets not response: \n{}\n", + libtest_with::RUNTIME_IGNORE_PREFIX, missing_sockets.join(", ") + ).into()), + } + Ok(()) + } + + #(#attrs)* + #vis #sig #block + } + .into() +} + /// Run test case when runner is root /// /// ```