graduate tests
This commit is contained in:
parent
e1e3404946
commit
a67fcad5c0
11 changed files with 164 additions and 53 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -686,7 +686,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ok_macros"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
@ -697,7 +697,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "okstd"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "okstd"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
@ -26,7 +26,7 @@ fastvlq = "1.1.1"
|
|||
futures = "0.3.30"
|
||||
hex = "0.4.3"
|
||||
num_cpus = "1.16.0"
|
||||
ok_macros = { version = "0.1.4", path = "ok_macros", registry = "oksoftware" }
|
||||
ok_macros = { version = "0.1.6", path = "ok_macros", registry = "oksoftware" }
|
||||
rustc-demangle = "0.1.23"
|
||||
serde = "*"
|
||||
serde_json = "*"
|
||||
|
|
50
README.md
50
README.md
|
@ -13,7 +13,9 @@ cargo add okstd@0.1.0
|
|||
```rust
|
||||
use okstd::prelude::*;
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### `okstd::main`
|
||||
|
||||
```rust
|
||||
|
@ -24,6 +26,7 @@ async fn main() {
|
|||
```
|
||||
|
||||
### `okstd::log`
|
||||
|
||||
```rust
|
||||
#[okstd::log(debug)]
|
||||
fn something() {
|
||||
|
@ -32,7 +35,49 @@ fn something() {
|
|||
}
|
||||
```
|
||||
|
||||
## Experimental Features
|
||||
### `okstd::test`
|
||||
|
||||
take a function and if it's not async, just add the #[test] attribute
|
||||
if it's async, add the #[test] attribute and setup the runtime
|
||||
take the previous function body then pass it into block_on as a closure
|
||||
|
||||
```rust
|
||||
#[okstd::test]
|
||||
fn does_something() {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn does_something() {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```rust
|
||||
#[okstd::test]
|
||||
async fn does_something() {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```rust
|
||||
#[test]
|
||||
fn does_something() {
|
||||
Runtimes::setup_runtimes().unwrap().block_on(async {
|
||||
// do something
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Experimental Features
|
||||
|
||||
> [!CAUTION]
|
||||
> Very unstable and only available under `unstable` feature flag.
|
||||
|
@ -50,6 +95,7 @@ async fn main() {
|
|||
panic!("This is a panic");
|
||||
}
|
||||
```
|
||||
|
||||
will return a crashdump string like so
|
||||
|
||||
```text
|
||||
|
@ -58,4 +104,4 @@ Filename: Ok("/scratch/cargo_target/debug/panics")
|
|||
Crashdump URL: https://crashdu.mp/🐧/♔/aea3ab2067116e3327bb51dc3bed94cd0/g98qBgj9qBg80qBg7r2Ng7gmOg4nxOgrnxOgt9wOgnmxOg4gpBghhpBggnpBg2spBg7npBg9lpBgp9pBgjsqBgk9pBgwqqBgl+pBgxmpBg/upOg4mqBg4kqBg500Cgnl6Kg6yuDgilvOg500Cgnl6Kg6yuDgohvOgzkqBg9mpBgslpB?cGFuaWMgb2NjdXJyZWQ6IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8gYXQgaW50ZWdyYXRpb24vc3JjL3Bhbmljcy5yczoxMToxMw
|
||||
```
|
||||
|
||||
[crashdu.mp/🐧/♔/aea3ab2067116e3327bb51dc3bed94cd0/g98qBgj9qBg80qBg7r2Ng7gmOg4nxOgrnxOgt9wOgnmxOg4gpBghhpBggnpBg2spBg7npBg9lpBgp9pBgjsqBgk9pBgwqqBgl+pBgxmpBg/upOg4mqBg4kqBg500Cgnl6Kg6yuDgilvOg500Cgnl6Kg6yuDgohvOgzkqBg9mpBgslpB?cGFuaWMgb2NjdXJyZWQ6IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8gYXQgaW50ZWdyYXRpb24vc3JjL3Bhbmljcy5yczoxMToxMw](https://crashdu.mp/🐧/♔/aea3ab2067116e3327bb51dc3bed94cd0/g98qBgj9qBg80qBg7r2Ng7gmOg4nxOgrnxOgt9wOgnmxOg4gpBghhpBggnpBg2spBg7npBg9lpBgp9pBgjsqBgk9pBgwqqBgl+pBgxmpBg/upOg4mqBg4kqBg500Cgnl6Kg6yuDgilvOg500Cgnl6Kg6yuDgohvOgzkqBg9mpBgslpB?cGFuaWMgb2NjdXJyZWQ6IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8gYXQgaW50ZWdyYXRpb24vc3JjL3Bhbmljcy5yczoxMToxMw)
|
||||
[crashdu.mp/🐧/♔/aea3ab2067116e3327bb51dc3bed94cd0/g98qBgj9qBg80qBg7r2Ng7gmOg4nxOgrnxOgt9wOgnmxOg4gpBghhpBggnpBg2spBg7npBg9lpBgp9pBgjsqBgk9pBgwqqBgl+pBgxmpBg/upOg4mqBg4kqBg500Cgnl6Kg6yuDgilvOg500Cgnl6Kg6yuDgohvOgzkqBg9mpBgslpB?cGFuaWMgb2NjdXJyZWQ6IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8gYXQgaW50ZWdyYXRpb24vc3JjL3Bhbmljcy5yczoxMToxMw](https://crashdu.mp/🐧/♔/aea3ab2067116e3327bb51dc3bed94cd0/g98qBgj9qBg80qBg7r2Ng7gmOg4nxOgrnxOgt9wOgnmxOg4gpBghhpBggnpBg2spBg7npBg9lpBgp9pBgjsqBgk9pBgwqqBgl+pBgxmpBg/upOg4mqBg4kqBg500Cgnl6Kg6yuDgilvOg500Cgnl6Kg6yuDgohvOgzkqBg9mpBgslpB?cGFuaWMgb2NjdXJyZWQ6IGF0dGVtcHQgdG8gZGl2aWRlIGJ5IHplcm8gYXQgaW50ZWdyYXRpb24vc3JjL3Bhbmljcy5yczoxMToxMw)
|
||||
|
|
|
@ -16,3 +16,6 @@ path = "src/main.rs"
|
|||
name = "panics"
|
||||
path = "src/panics.rs"
|
||||
|
||||
[lib]
|
||||
name = "tests"
|
||||
path = "src/tests.rs"
|
|
@ -10,4 +10,4 @@ async fn main() {
|
|||
let b = 1;
|
||||
let _c = b / a;
|
||||
panic!("This is a panic");
|
||||
}
|
||||
}
|
||||
|
|
9
integration/src/tests.rs
Normal file
9
integration/src/tests.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
mod tests {
|
||||
use okstd::prelude::*;
|
||||
|
||||
#[okstd::test]
|
||||
async fn debug() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ok_macros"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
edition = "2021"
|
||||
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use proc_macro::TokenStream;
|
|||
use quote::quote;
|
||||
use syn::{parse_macro_input, punctuated::Punctuated, ItemFn};
|
||||
|
||||
pub fn transform_function(
|
||||
pub fn setup_logging(
|
||||
args: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
|
@ -149,5 +149,87 @@ pub fn setup_panic_hook(
|
|||
|
||||
};
|
||||
|
||||
TokenStream::from(result)
|
||||
}
|
||||
|
||||
/// testing
|
||||
/// take a function and if it's not async, just add the #[test] attribute
|
||||
/// if it's async, add the #[test] attribute and setup the runtime
|
||||
/// take the previous function body then pass it into block_on as
|
||||
/// a closure
|
||||
/// ```rust,notest
|
||||
/// #[okstd::test]
|
||||
/// fn does_something() {
|
||||
/// // do something
|
||||
/// }
|
||||
/// ```
|
||||
/// to
|
||||
/// ```rust,notest
|
||||
/// #[test]
|
||||
/// fn does_something() {
|
||||
/// // do something
|
||||
/// }
|
||||
/// ```
|
||||
/// or
|
||||
/// ```rust,notest
|
||||
/// #[okstd::test]
|
||||
/// async fn does_something() {
|
||||
/// // do something
|
||||
/// }
|
||||
/// ```
|
||||
/// to
|
||||
/// ```rust,notest
|
||||
/// #[test]
|
||||
/// fn does_something() {
|
||||
/// Runtimes::setup_runtimes().unwrap().block_on(async #body)
|
||||
/// }
|
||||
/// ```
|
||||
pub fn test(
|
||||
_args: proc_macro::TokenStream,
|
||||
input: proc_macro::TokenStream,
|
||||
) -> proc_macro::TokenStream {
|
||||
let mut item_fn = parse_macro_input!(input as ItemFn);
|
||||
|
||||
let fn_name = &item_fn.clone().sig.ident;
|
||||
|
||||
let attrs: &Vec<syn::Attribute> = &item_fn.attrs;
|
||||
let asyncness: &Option<syn::token::Async> = &item_fn.sig.asyncness;
|
||||
let generics: &syn::Generics = &item_fn.sig.generics;
|
||||
let inputs: &Punctuated<syn::FnArg, syn::token::Comma> = &item_fn.sig.inputs;
|
||||
|
||||
let output: &syn::ReturnType = &item_fn.sig.output;
|
||||
let where_clause: &Option<syn::WhereClause> = &item_fn.sig.generics.where_clause;
|
||||
|
||||
let orig_ident = item_fn.sig.ident.clone();
|
||||
// Rename the `test` function to `old_test`
|
||||
let new_name = format!("__test_{}", orig_ident);
|
||||
let old_ident = syn::Ident::new(new_name.as_str(), item_fn.sig.ident.span());
|
||||
item_fn.sig.ident = old_ident.clone();
|
||||
|
||||
let body = &item_fn.block;
|
||||
|
||||
if asyncness.is_none() {
|
||||
let result = quote! {
|
||||
#[allow(unused_must_use)]
|
||||
#[test]
|
||||
fn #fn_name #generics(#inputs) #output
|
||||
#where_clause {
|
||||
#body
|
||||
}
|
||||
};
|
||||
|
||||
return TokenStream::from(result)
|
||||
}
|
||||
|
||||
|
||||
let result = quote! {
|
||||
#[allow(unused_must_use)]
|
||||
#[test]
|
||||
fn #fn_name #generics(#inputs) #output
|
||||
#where_clause {
|
||||
Runtimes::setup_runtimes().unwrap().block_on(async #body)
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(result)
|
||||
}
|
|
@ -41,40 +41,8 @@ pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
|
||||
// test, just like main, but for tests.
|
||||
#[proc_macro_attribute]
|
||||
pub fn test(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let mut input = parse_macro_input!(item as ItemFn);
|
||||
let orig_ident = input.sig.ident.clone();
|
||||
// Rename the `test` function to `old_test`
|
||||
let new_name = format!("old_test_{}", orig_ident);
|
||||
let old_test_ident = syn::Ident::new(new_name.as_str(), input.sig.ident.span());
|
||||
input.sig.ident = old_test_ident.clone();
|
||||
|
||||
// Check if the function is async
|
||||
let new_test = if input.sig.asyncness.is_none() {
|
||||
quote! {
|
||||
#[test]
|
||||
fn #orig_ident() {
|
||||
#old_test_ident()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#[test]
|
||||
fn #orig_ident() {
|
||||
// set_hook(Box::new(panic_hook));
|
||||
let rt = Runtimes::setup_runtimes().unwrap();
|
||||
rt.block_on(#old_test_ident())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Combine the input and the new `test` function
|
||||
let output = quote! {
|
||||
#input
|
||||
#new_test
|
||||
};
|
||||
|
||||
output.into()
|
||||
pub fn test(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
func_transformer::test(args, input)
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
|
@ -84,5 +52,5 @@ pub fn crashdump(args: TokenStream, input: TokenStream) -> TokenStream {
|
|||
|
||||
#[proc_macro_attribute]
|
||||
pub fn log(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
func_transformer::transform_function(args, input)
|
||||
func_transformer::setup_logging(args, input)
|
||||
}
|
||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -1,6 +1,6 @@
|
|||
//!
|
||||
|
||||
pub mod log;
|
||||
pub mod oklog;
|
||||
pub mod okasync;
|
||||
|
||||
#[cfg(feature = "unstable")]
|
||||
|
@ -8,23 +8,26 @@ pub mod notokpanic;
|
|||
mod e2e_tests;
|
||||
|
||||
extern crate fern;
|
||||
extern crate log as rustlog;
|
||||
|
||||
use log as rustlog;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::okasync::*;
|
||||
|
||||
pub use crate::log::setup_logging;
|
||||
pub use crate::oklog::setup_logging;
|
||||
|
||||
pub use super::main;
|
||||
pub use super::log;
|
||||
|
||||
// re-export the slog macros
|
||||
pub use fern::*;
|
||||
pub use rustlog::debug;
|
||||
pub use rustlog::error;
|
||||
pub use rustlog::info;
|
||||
pub use rustlog::trace;
|
||||
pub use rustlog::warn;
|
||||
pub use crate::rustlog::debug;
|
||||
pub use crate::rustlog::error;
|
||||
pub use crate::rustlog::info;
|
||||
pub use crate::rustlog::trace;
|
||||
pub use crate::rustlog::warn;
|
||||
|
||||
pub use rustlog::LevelFilter;
|
||||
pub use crate::rustlog::LevelFilter;
|
||||
|
||||
pub use std::panic::set_hook;
|
||||
|
||||
|
|
Loading…
Reference in a new issue