diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a69295..8246a9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: - stable - beta - nightly - - 1.51.0 + - 1.56.0 steps: - uses: actions/checkout@v2.3.4 - uses: actions-rs/toolchain@v1.0.7 diff --git a/Cargo.lock b/Cargo.lock index 9fd615a..bff4274 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + [[package]] name = "cfg-if" version = "0.1.10" @@ -61,6 +67,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + [[package]] name = "dashmap" version = "5.2.0" @@ -184,12 +200,6 @@ dependencies = [ "slab", ] -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - [[package]] name = "hermit-abi" version = "0.1.17" @@ -215,10 +225,13 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "0.4.8" +name = "js-sys" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "lazy_static" @@ -339,30 +352,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.24" @@ -408,16 +397,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] -name = "rustversion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" - -[[package]] -name = "ryu" -version = "1.0.5" +name = "scoped-tls" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" [[package]] name = "scopeguard" @@ -425,37 +408,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "serial_test" version = "0.9.0" @@ -477,12 +429,9 @@ name = "serial_test_derive" version = "0.9.0" dependencies = [ "env_logger", - "proc-macro-error", "proc-macro2", "quote", - "rustversion", "syn", - "trybuild", ] [[package]] @@ -494,8 +443,10 @@ dependencies = [ "futures-util", "lazy_static", "parking_lot", + "scoped-tls", "serial_test", "tokio", + "wasm-bindgen-test", ] [[package]] @@ -578,45 +529,116 @@ dependencies = [ ] [[package]] -name = "toml" -version = "0.5.8" +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ - "serde", + "cfg-if 1.0.0", + "wasm-bindgen-macro", ] [[package]] -name = "trybuild" -version = "1.0.50" +name = "wasm-bindgen-backend" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbaccfa9796293406a02ec790614628c88d0b3246249a620ac1ee7076274716b" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ - "glob", + "bumpalo", "lazy_static", - "serde", - "serde_json", - "termcolor", - "toml", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", ] [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "wasm-bindgen-futures" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] [[package]] -name = "version_check" -version = "0.9.3" +name = "wasm-bindgen-macro" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "wasm-bindgen-macro-support" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b30cf2cba841a812f035c40c50f53eb9c56181192a9dd2c71b65e6a87a05ba" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad594bf33e73cafcac2ae9062fc119d4f75f9c77e25022f91c9a64bd5b6463" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "web-sys" +version = "0.3.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" diff --git a/README.md b/README.md index 49a803e..3369e54 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Docs](https://docs.rs/serial_test/badge.svg)](https://docs.rs/serial_test/) [![MIT license](https://img.shields.io/crates/l/serial_test.svg)](./LICENSE) [![Build Status](https://github.com/palfrey/serial_test/workflows/Continuous%20integration/badge.svg?branch=main)](https://github.com/palfrey/serial_test/actions) -[![MSRV: 1.51.0](https://flat.badgen.net/badge/MSRV/1.51.0/purple)](https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html) +[![MSRV: 1.56.0](https://flat.badgen.net/badge/MSRV/1.56.0/purple)](https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html) `serial_test` allows for the creation of serialised Rust tests using the `serial` attribute e.g. @@ -29,15 +29,12 @@ async fn test_serial_another() { ``` Multiple tests with the `serial` attribute are guaranteed to be executed in serial. Ordering of the tests is not guaranteed however. Other tests with the `parallel` attribute may run at the same time as each other, but not at the same time as a test with `serial`. Tests with neither attribute may run at any time and no guarantees are made about their timing! -Note that if you're using an async test reactor attribute (e.g. `tokio::test` or `actix_rt::test`) then they should be listed *before* `serial`, otherwise we -don't get an async function and things break. There's now an error for this case to improve debugging. - For cases like doctests and integration tests where the tests are run as separate processes, we also support `file_serial`, with similar properties but based off file locking. Note that there are no guarantees about one test with `serial` and another with `file_serial` as they lock using different methods, and `parallel` doesn't support `file_serial` yet (patches welcomed!). ## Usage -We require at least Rust 1.51. Upgrades to this will require at least a minor version bump (while in 0.x versions) and a major version bump post-1.0. +We require at least Rust 1.56. Upgrades to this will require at least a minor version bump (while in 0.x versions) and a major version bump post-1.0. Add to your Cargo.toml ```toml diff --git a/serial_test/Cargo.toml b/serial_test/Cargo.toml index 3d8a8b1..fb826e7 100644 --- a/serial_test/Cargo.toml +++ b/serial_test/Cargo.toml @@ -33,7 +33,7 @@ default = ["logging", "async"] logging = ["log"] ## Enables async features (and requires the `futures` package) -async = ["futures"] +async = ["futures", "serial_test_derive/async"] ## The file_locks feature unlocks the `file_serial`/`file_parallel` macros (and requires the `fslock` package) file_locks = ["fslock"] diff --git a/serial_test/src/lib.rs b/serial_test/src/lib.rs index 25a4967..49ef6a4 100644 --- a/serial_test/src/lib.rs +++ b/serial_test/src/lib.rs @@ -30,10 +30,6 @@ //! at the same time as each other, but not at the same time as a test with [serial](macro@serial). Tests with //! neither attribute may run at any time and no guarantees are made about their timing! //! -//! Note that if you're using an async test reactor attribute (e.g. -//! `tokio::test` or `actix_rt::test`) then they should be listed *before* [serial](macro@serial)/[parallel](macro@parallel), otherwise we don't get an -//! async function and things break. There's now an error for this case to improve debugging. -//! //! For cases like doctests and integration tests where the tests are run as separate processes, we also support //! [file_serial](macro@file_serial)/[file_parallel](macro@file_parallel), with similar properties but based off file locking. Note that there are no //! guarantees about one test with [serial](macro@serial)/[parallel](macro@parallel) and another with [file_serial](macro@file_serial)/[file_parallel](macro@file_parallel) diff --git a/serial_test_derive/Cargo.toml b/serial_test_derive/Cargo.toml index f4b1d7b..4151aef 100644 --- a/serial_test_derive/Cargo.toml +++ b/serial_test_derive/Cargo.toml @@ -16,9 +16,9 @@ proc-macro = true quote = "1.0" syn = { version="1.0", features=["full"] } proc-macro2 = "1.0" -proc-macro-error = { version = "1" } [dev-dependencies] env_logger = "0.9" -rustversion = "1.0" -trybuild = "1" \ No newline at end of file + +[features] +async = [] \ No newline at end of file diff --git a/serial_test_derive/src/lib.rs b/serial_test_derive/src/lib.rs index 46d8f17..9e9b764 100644 --- a/serial_test_derive/src/lib.rs +++ b/serial_test_derive/src/lib.rs @@ -8,7 +8,6 @@ extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::TokenTree; -use proc_macro_error::{abort_call_site, proc_macro_error}; use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use std::ops::Deref; @@ -64,7 +63,6 @@ use std::ops::Deref; /// /// Nested serialised tests (i.e. a [serial](macro@serial) tagged test calling another) are supported #[proc_macro_attribute] -#[proc_macro_error] pub fn serial(attr: TokenStream, input: TokenStream) -> TokenStream { local_serial_core(attr.into(), input.into()).into() } @@ -98,7 +96,6 @@ pub fn serial(attr: TokenStream, input: TokenStream) -> TokenStream { /// Note that this has zero effect on [file_serial](macro@file_serial) tests, as that uses a different /// serialisation mechanism. For that, you want [file_parallel](macro@file_parallel). #[proc_macro_attribute] -#[proc_macro_error] pub fn parallel(attr: TokenStream, input: TokenStream) -> TokenStream { local_parallel_core(attr.into(), input.into()).into() } @@ -139,7 +136,6 @@ pub fn parallel(attr: TokenStream, input: TokenStream) -> TokenStream { /// ```` /// Note that in this case you need to specify the `name` arg as well (as per [serial](macro@serial)). The path defaults to a reasonable temp directory for the OS if not specified. #[proc_macro_attribute] -#[proc_macro_error] #[cfg_attr(docsrs, doc(cfg(feature = "file_locks")))] pub fn file_serial(attr: TokenStream, input: TokenStream) -> TokenStream { fs_serial_core(attr.into(), input.into()).into() @@ -184,7 +180,6 @@ pub fn file_serial(attr: TokenStream, input: TokenStream) -> TokenStream { /// ```` /// Note that in this case you need to specify the `name` arg as well (as per [parallel](macro@parallel)). The path defaults to a reasonable temp directory for the OS if not specified. #[proc_macro_attribute] -#[proc_macro_error] #[cfg_attr(docsrs, doc(cfg(feature = "file_locks")))] pub fn file_parallel(attr: TokenStream, input: TokenStream) -> TokenStream { fs_parallel_core(attr.into(), input.into()).into() @@ -338,17 +333,6 @@ where .filter(|at| { if let Ok(m) = at.parse_meta() { let path = m.path(); - if asyncness.is_some() - && path.segments.len() == 2 - && path.segments[1].ident == "test" - { - // We assume that any 2-part attribute with the second part as "test" on an async function - // is the "do this test with reactor" wrapper. This is true for actix, tokio and async_std. - abort_call_site!( - "Found async test attribute after serial/parallel, which will break" - ); - } - // we skip ignore/should_panic because the test framework already deals with it !(path.is_ident("ignore") || path.is_ident("should_panic")) } else { @@ -360,11 +344,15 @@ where match asyncness { Some(_) => { let fnname = format_ident!("{}_async_{}_core_with_return", prefix, kind); + let temp_fn = format_ident!("_{}_internal", name); quote! { + async fn #temp_fn () -> #ret + #block + #(#attrs) * #vis async fn #name () -> #ret { - serial_test::#fnname(#(#args ),*, || async #block ).await; + serial_test::#fnname(#(#args ),*, #temp_fn()).await } } } @@ -383,11 +371,15 @@ where match asyncness { Some(_) => { let fnname = format_ident!("{}_async_{}_core", prefix, kind); + let temp_fn = format_ident!("_{}_internal", name); quote! { + async fn #temp_fn () + #block + #(#attrs) * #vis async fn #name () { - serial_test::#fnname(#(#args ),*, || async #block ).await; + serial_test::#fnname(#(#args ),*, #temp_fn()).await; } } } @@ -499,8 +491,9 @@ mod tests { }; let stream = local_serial_core(attrs.into(), input); let compare = quote! { + async fn _foo_internal () { } async fn foo () { - serial_test::local_async_serial_core("", || async {} ).await; + serial_test::local_async_serial_core("", _foo_internal() ).await; } }; assert_eq!(format!("{}", compare), format!("{}", stream)); @@ -515,22 +508,14 @@ mod tests { }; let stream = local_serial_core(attrs.into(), input); let compare = quote! { + async fn _foo_internal () -> Result<(), ()> { Ok(()) } async fn foo () -> Result<(), ()> { - serial_test::local_async_serial_core_with_return("", :: std :: option :: Option :: None, || async { Ok(()) } ).await; + serial_test::local_async_serial_core_with_return("", _foo_internal() ).await } }; assert_eq!(format!("{}", compare), format!("{}", stream)); } - // 1.54 needed for https://github.com/rust-lang/rust/commit/9daf546b77dbeab7754a80d7336cd8d00c6746e4 change in note message - #[rustversion::since(1.54)] - #[test] - #[cfg(feature = "async")] - fn test_serial_async_before_wrapper() { - let t = trybuild::TestCases::new(); - t.compile_fail("tests/broken/test_serial_async_before_wrapper.rs"); - } - #[test] fn test_file_serial() { let attrs = vec![TokenTree::Ident(format_ident!("foo"))]; diff --git a/serial_test_derive/tests/broken/test_serial_async_before_wrapper.rs b/serial_test_derive/tests/broken/test_serial_async_before_wrapper.rs deleted file mode 100644 index 690eccf..0000000 --- a/serial_test_derive/tests/broken/test_serial_async_before_wrapper.rs +++ /dev/null @@ -1,7 +0,0 @@ -use serial_test_derive::serial; - -#[serial] -#[actix_rt::test] -async fn test_async_serial_no_arg_actix() {} - -fn main() {} \ No newline at end of file diff --git a/serial_test_derive/tests/broken/test_serial_async_before_wrapper.stderr b/serial_test_derive/tests/broken/test_serial_async_before_wrapper.stderr deleted file mode 100644 index 35703d1..0000000 --- a/serial_test_derive/tests/broken/test_serial_async_before_wrapper.stderr +++ /dev/null @@ -1,7 +0,0 @@ -error: Found async test attribute after serial/parallel, which will break - --> tests/broken/test_serial_async_before_wrapper.rs:3:1 - | -3 | #[serial] - | ^^^^^^^^^ - | - = note: this error originates in the attribute macro `serial` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/serial_test_test/Cargo.toml b/serial_test_test/Cargo.toml index 1a0d923..2396ba0 100644 --- a/serial_test_test/Cargo.toml +++ b/serial_test_test/Cargo.toml @@ -11,6 +11,8 @@ serial_test = { path="../serial_test", default_features = false } lazy_static = "^1.2" env_logger = "^0.9" parking_lot = "^0.12" +wasm-bindgen-test = {version="0.3.0", optional=true} +scoped-tls = {version="=1.0.0", optional=true} # Locked down for 1.56 compat [dev-dependencies] tokio = { version = "^1.17", features = ["macros", "rt"] } @@ -18,5 +20,9 @@ actix-rt = { version = "^2.7", features = ["macros"] } futures-util = {version = "^0.3", default_features = false } [features] -default = ["serial_test/logging"] -file_locks = ["serial_test/file_locks"] \ No newline at end of file +default = ["serial_test/logging", "async"] +file_locks = ["serial_test/file_locks"] +async = ["serial_test/async", "wasm-bindgen-test", "scoped-tls"] + +[package.metadata.cargo-all-features] +skip_optional_dependencies = true \ No newline at end of file diff --git a/serial_test_test/src/lib.rs b/serial_test_test/src/lib.rs index 0150b90..bb3f220 100644 --- a/serial_test_test/src/lib.rs +++ b/serial_test_test/src/lib.rs @@ -93,6 +93,8 @@ mod tests { thread, time::Duration, }; + #[cfg(feature = "async")] + use wasm_bindgen_test::wasm_bindgen_test; lazy_static! { static ref THREAD_ORDERINGS: Arc>> = Arc::new(Mutex::new(Vec::new())); @@ -160,18 +162,35 @@ mod tests { Ok(()) } + #[cfg(feature = "async")] #[tokio::test] #[serial] - async fn test_async_serial_no_arg() { + async fn test_async_serial_no_arg_tokio_first() { init(); } + #[cfg(feature = "async")] + #[serial] + #[tokio::test] + async fn test_async_serial_no_arg_serial_first() { + init(); + } + + #[cfg(feature = "async")] + #[serial] + #[actix_rt::test] + async fn test_async_serial_no_arg_actix_with_serial_firs() { + init(); + } + + #[cfg(feature = "async")] #[actix_rt::test] #[serial] - async fn test_async_serial_no_arg_actix() { + async fn test_async_serial_no_arg_actix_first() { init(); } + #[cfg(feature = "async")] #[tokio::test] #[serial] async fn test_async_can_return() -> Result<(), ()> { @@ -319,17 +338,38 @@ mod tests { Ok(()) } - #[cfg(feature = "file_locks")] + #[cfg(all(feature = "file_locks", feature = "async"))] #[tokio::test] #[file_parallel] async fn file_parallel_with_async_return() -> Result<(), ()> { Ok(()) } - #[cfg(feature = "file_locks")] + #[cfg(all(feature = "file_locks", feature = "async"))] #[tokio::test] #[file_parallel] async fn file_parallel_with_async() { init(); } + + // Note, not actually a test as such, just a "can you wrap serial functions" compile-time check + #[cfg(feature = "async")] + #[serial] + async fn async_attribute_works() {} + + #[cfg(feature = "async")] + #[serial] + async fn async_attribute_works_with_return() -> Result<(), ()> { + Ok(()) + } + + #[cfg(feature = "async")] + #[wasm_bindgen_test] + #[serial] + async fn wasm_works_first() {} + + #[cfg(feature = "async")] + #[serial] + #[wasm_bindgen_test] + async fn wasm_works_second() {} }