1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
//! [![crates.io version](https://img.shields.io/crates/v/safina-async-test.svg)](https://crates.io/crates/safina-async-test) //! [![license: Apache 2.0](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/license-apache-2.0.svg)](http://www.apache.org/licenses/LICENSE-2.0) //! [![unsafe forbidden](https://gitlab.com/leonhard-llc/safina-rs/-/raw/main/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) //! [![pipeline status](https://gitlab.com/leonhard-llc/safina-rs/badges/main/pipeline.svg)](https://gitlab.com/leonhard-llc/safina-rs/-/pipelines) //! //! An `async_test` macro for running `async fn` tests. //! //! It is part of [`safina`](https://crates.io/crates/safina), a safe async runtime. //! //! # Features //! - Runs tests with [`safina_executor`](https://docs.rs/safina-executor) //! - Each test gets its own executor with 2 threads for async tasks and 1 thread for blocking tasks. //! - Also calls //! [`safina_timer::start_timer_thread`](https://docs.rs/safina-timer/latest/safina_timer/fn.start_timer_thread.html) //! before running the test //! - `forbid(unsafe_code)` //! - Lightweight dependencies //! - Straightforward implementation //! //! # Limitations //! - Building on `stable` requires [`once_cell`](https://crates.io/crates/once_cell) //! crate which contains some unsafe code. //! This is necessary until //! [`std::lazy::OnceCell`](https://doc.rust-lang.org/std/lazy/struct.OnceCell.html) //! is stable. //! //! # Examples //! ```rust //! use safina_async_test::async_test; //! # async fn async_work() -> Result<(), std::io::Error> { Ok(()) } //! //! #[async_test] //! async fn test1() { //! async_work().await.unwrap(); //! } //! ``` //! //! ```rust //! use safina; //! use safina_async_test::async_test; //! # use core::time::Duration; //! # fn blocking_work() -> Result<u8, std::io::Error> { Ok(3) } //! # async fn background_task() {} //! # async fn async_work() -> Result<u8, std::io::Error> { Ok(42) } //! //! // Make your test an `async fn`. //! #[async_test] //! async fn test2() { //! // You can `await`. //! async_work().await.unwrap(); //! //! // You can spawn tasks which will run on //! // the executor. //! // These tasks stop when the test //! // function returns and drops the //! // executor. //! safina::spawn(background_task()); //! //! // You can run blocking code without //! // stalling other async tasks. //! let result = safina::schedule_blocking( //! || blocking_work() //! ); //! assert_eq!(3, result.await.unwrap()); //! //! // You can use timer functions. //! safina::sleep_for( //! Duration::from_millis(10)).await; //! safina::with_timeout( //! async_work(), //! Duration::from_millis(100) //! ).await.unwrap(); //! } //! ``` //! //! # Documentation //! <https://docs.rs/safina-async-test> //! //! # Alternatives //! - [`async_std::test`](https://docs.rs/async-std/latest/async_std/attr.test.html) //! - [`futures_await_test::async_test`](https://docs.rs/futures-await-test/0.3.0/futures_await_test/) //! - [`tokio::test`](https://docs.rs/tokio/latest/tokio/attr.test.html) //! //! # Changelog //! - v0.1.9 - Don't require users to also depend on `safina-executor` and //! `safina-timer` crates. //! - v0.1.8 //! - Support stable with rust 1.51 and `once_cell`. //! - Start an Executor for each test //! - v0.1.7 - Update to safina-executor v0.1.4 //! - v0.1.6 - Start [`safina-timer`](https://crates.io/crates/safina-timer) //! thread //! - v0.1.5 - Use [`safina-executor`](https://crates.io/crates/safina-executor) //! v0.1.3 API //! - v0.1.4 - Upgrade to new //! [`safina-executor`](https://crates.io/crates/safina-executor) //! version which removes need for `Box::pin`. //! - v0.1.3 - Rename [`safina`](https://crates.io/crates/safina) package to //! [`safina-executor`](https://crates.io/crates/safina-executor). //! - v0.1.2 - Update docs //! - v0.1.1 - First published version //! //! # Happy Contributors 🙂 //! Fixing bugs and adding features is easy and fast. //! Send us a pull request and we intend to: //! - Always respond within 24 hours //! - Provide clear & concrete feedback //! - Immediately make a new release for your accepted change //! //! # TO DO //! - DONE - Implement as declarative macro. UX is bad. //! - DONE - Implement as procedural macro. //! - DONE - Report errors nicely //! - DONE - Publish on crates.io //! - DONE - Automatically start a worker thread and timer thread. //! - DONE - Let users depend only on safina-async-test: //! - DONE - Move proc macro to its own crate. //! - DONE - Make `safina_async_test` re-export the macro and `safina_executor::block_on`. //! - DONE - Change the macro to call `safina_async_test::block_on`. //! //! # Release Process //! 1. Edit `Cargo.toml` and bump version number. //! 1. Run `./release.sh` #![forbid(unsafe_code)] pub use safina_async_test_core::async_test; pub use safina_executor::Executor; pub use safina_timer::start_timer_thread;