Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to wasm-bindgen-test/unstable-test-coverage #4369

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -40,6 +40,12 @@
* `console.*()` calls in tests are now always intercepted by default. To show them use `--nocapture`. When shown they are always printed in-place instead of after test results, analogous to `cargo test`.
[#4356](https://github.com/rustwasm/wasm-bindgen/pull/4356)

* Instrumentation is now disabled on internal functions with the `msrv` crate feature instead of `cfg(wasm_bindgen_unstable_test_coverage)`.
[#4369](https://github.com/rustwasm/wasm-bindgen/pull/4369)

* Replaced `cfg(wasm_bindgen_unstable_test_coverage)` with crate feature `unstable-test-coverage` on `wasm-bindgen-test`.
[#4369](https://github.com/rustwasm/wasm-bindgen/pull/4369)

### Fixed

- Fixed using [JavaScript keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) as identifiers not being handled correctly.
@@ -67,6 +73,9 @@
* Internal functions are now removed instead of invalidly imported if they are unused.
[#4366](https://github.com/rustwasm/wasm-bindgen/pull/4366)

* No coverage data is emitted when the module is not instrumented even if `unstable-test-coverage` is enabled.
[#4369](https://github.com/rustwasm/wasm-bindgen/pull/4369)

--------------------------------------------------------------------------------

## [0.2.99](https://github.com/rustwasm/wasm-bindgen/compare/0.2.98...0.2.99)
14 changes: 4 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ std = []
# The current rustc version is detected at compile-time, so enabling this
# feature for older compilers will NOT result in a compilation error. Instead,
# any unsupported language feature will not be used.
msrv = ["rustversion"]
msrv = ["rustversion", "wasm-bindgen-macro/msrv"]

# Whether or not the `#[wasm_bindgen]` macro is strict and generates an error on
# all unused attributes
@@ -67,15 +67,8 @@ wasm-bindgen-futures = { path = 'crates/futures' }
wasm-bindgen-test-crate-a = { path = 'tests/crates/a' }
wasm-bindgen-test-crate-b = { path = 'tests/crates/b' }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }

[lints.clippy]
large_enum_variant = "allow"
new_without_default = "allow"
overly_complex_bool_expr = "allow"
too_many_arguments = "allow"
type_complexity = "allow"
[lints]
workspace = true

[workspace.lints.clippy]
large_enum_variant = "allow"
@@ -135,6 +128,7 @@ resolver = "2"

[patch.crates-io]
js-sys = { path = 'crates/js-sys' }
minicov = { git = 'https://github.com/daxpedda/minicov', branch = 'counters' }
wasm-bindgen = { path = '.' }
wasm-bindgen-futures = { path = 'crates/futures' }
web-sys = { path = 'crates/web-sys' }
1 change: 1 addition & 0 deletions crates/backend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ version = "0.2.99"

[features]
extra-traits = ["syn/extra-traits"]
msrv = []

[dependencies]
bumpalo = "3.0.0"
31 changes: 21 additions & 10 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
@@ -223,6 +223,7 @@ impl ToTokens for ast::Struct {
let free_fn = Ident::new(&shared::free_function(&name_str), Span::call_site());
let unwrap_fn = Ident::new(&shared::unwrap_function(&name_str), Span::call_site());
let wasm_bindgen = &self.wasm_bindgen;
let coverage = coverage(wasm_bindgen);
(quote! {
#[automatically_derived]
impl #wasm_bindgen::__rt::marker::SupportsConstructor for #name {}
@@ -301,9 +302,9 @@ impl ToTokens for ast::Struct {
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#wasm_bindgen::__wbindgen_coverage! {
#[no_mangle]
#[doc(hidden)]
#coverage
// `allow_delayed` is whether it's ok to not actually free the `ptr` immediately
// if it's still borrowed.
pub unsafe extern "C" fn #free_fn(ptr: u32, allow_delayed: u32) {
@@ -320,7 +321,6 @@ impl ToTokens for ast::Struct {
let _ = <#name as #wasm_bindgen::convert::FromWasmAbi>::from_abi(ptr);
}
}
}
};

#[automatically_derived]
@@ -496,13 +496,14 @@ impl ToTokens for ast::StructField {
}

let wasm_bindgen = &self.wasm_bindgen;
let coverage = coverage(wasm_bindgen);

(quote! {
#[automatically_derived]
const _: () = {
#wasm_bindgen::__wbindgen_coverage! {
#[cfg_attr(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")), no_mangle)]
#[doc(hidden)]
#coverage
pub unsafe extern "C" fn #getter(js: u32)
-> #wasm_bindgen::convert::WasmRet<<#ty as #wasm_bindgen::convert::IntoWasmAbi>::Abi>
{
@@ -517,7 +518,6 @@ impl ToTokens for ast::StructField {
let val = #val;
<#ty as IntoWasmAbi>::into_abi(val).into()
}
}
};
})
.to_tokens(tokens);
@@ -543,9 +543,9 @@ impl ToTokens for ast::StructField {
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#wasm_bindgen::__wbindgen_coverage! {
#[no_mangle]
#[doc(hidden)]
#coverage
pub unsafe extern "C" fn #setter(
js: u32,
#(#args,)*
@@ -559,7 +559,6 @@ impl ToTokens for ast::StructField {
let val = <#ty as FromWasmAbi>::from_abi(val);
(*js).borrow_mut().#rust_name = val;
}
}
};
})
.to_tokens(tokens);
@@ -584,6 +583,7 @@ impl TryToTokens for ast::Export {

let name = &self.rust_name;
let wasm_bindgen = &self.wasm_bindgen;
let coverage = coverage(wasm_bindgen);
let wasm_bindgen_futures = &self.wasm_bindgen_futures;
let receiver = match self.method_self {
Some(ast::MethodSelf::ByValue) => {
@@ -827,12 +827,12 @@ impl TryToTokens for ast::Export {
(quote! {
#[automatically_derived]
const _: () = {
#wasm_bindgen::__wbindgen_coverage! {
#(#attrs)*
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
export_name = #export_name,
)]
#coverage
pub unsafe extern "C" fn #generated_name(#(#args),*) -> #wasm_bindgen::convert::WasmRet<#projection::Abi> {
const _: () = {
#(#checks)*
@@ -841,7 +841,6 @@ impl TryToTokens for ast::Export {
let #ret = #call;
#convert_ret
}
}
};
})
.to_tokens(into);
@@ -1870,21 +1869,21 @@ impl<T: ToTokens> ToTokens for Descriptor<'_, T> {
let inner = &self.inner;
let attrs = &self.attrs;
let wasm_bindgen = &self.wasm_bindgen;
let coverage = coverage(wasm_bindgen);
(quote! {
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#[automatically_derived]
const _: () = {
#wasm_bindgen::__wbindgen_coverage! {
#(#attrs)*
#[no_mangle]
#[doc(hidden)]
#coverage
pub extern "C" fn #name() {
use #wasm_bindgen::describe::*;
// See definition of `link_mem_intrinsics` for what this is doing
#wasm_bindgen::__rt::link_mem_intrinsics();
#inner
}
}
};
})
.to_tokens(tokens);
@@ -1969,3 +1968,15 @@ fn respan(input: TokenStream, span: &dyn ToTokens) -> TokenStream {
}
new_tokens.into_iter().collect()
}

#[cfg(feature = "msrv")]
fn coverage(wasm_bindgen: &syn::Path) -> TokenStream {
quote! {
#[#wasm_bindgen::__rt::rustversion::attr(since(2024-12-18), coverage(off))]
}
}

#[cfg(not(feature = "msrv"))]
fn coverage(_: &syn::Path) -> TokenStream {
TokenStream::new()
}
1 change: 1 addition & 0 deletions crates/macro-support/Cargo.toml
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@ version = "0.2.99"

[features]
extra-traits = ["syn/extra-traits"]
msrv = ["wasm-bindgen-backend/msrv"]
strict-macro = []

[dependencies]
1 change: 1 addition & 0 deletions crates/macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ version = "0.2.99"
proc-macro = true

[features]
msrv = ["wasm-bindgen-macro-support/msrv"]
strict-macro = ["wasm-bindgen-macro-support/strict-macro"]
xxx_debug_only_print_generated_code = []

18 changes: 16 additions & 2 deletions crates/macro/ui-tests/wasm-bindgen.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
error[E0433]: failed to resolve: could not find `__wbindgen_coverage` in `test`
error[E0433]: failed to resolve: could not find `__rt` in `test`
--> ui-tests/wasm-bindgen.rs:37:1
|
37 | #[wasm_bindgen(wasm_bindgen = test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not find `__wbindgen_coverage` in `test`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not find `__rt` in `test`
|
= note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0433]: failed to resolve: could not find `convert` in `test`
--> ui-tests/wasm-bindgen.rs:37:1
|
37 | #[wasm_bindgen(wasm_bindgen = test)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ could not find `convert` in `test`
|
= note: this error originates in the attribute macro `wasm_bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
|
3 + use crate::extern_test::convert;
|
3 + use wasm_bindgen::convert;
|

error[E0425]: cannot find function `future_to_promise` in module `test`
--> ui-tests/wasm-bindgen.rs:40:1
|
3 changes: 3 additions & 0 deletions crates/test-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@ version = "0.3.49"
[lib]
proc-macro = true

[features]
msrv = []

[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
9 changes: 7 additions & 2 deletions crates/test-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -93,17 +93,22 @@ pub fn wasm_bindgen_test(
let ignore_name = if ignore.is_some() { "$" } else { "" };

let wasm_bindgen_path = attributes.wasm_bindgen_path;
#[cfg(feature = "msrv")]
let coverage = quote! {
#[#wasm_bindgen_path::__rt::wasm_bindgen::__rt::rustversion::attr(since(2024-12-18), coverage(off))]
};
#[cfg(not(feature = "msrv"))]
let coverage = TokenStream::new();
tokens.extend(
quote! {
const _: () = {
#wasm_bindgen_path::__rt::wasm_bindgen::__wbindgen_coverage! {
#[export_name = ::core::concat!("__wbgt_", #ignore_name, ::core::module_path!(), "::", ::core::stringify!(#ident))]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
#coverage
extern "C" fn __wbgt_test(cx: &#wasm_bindgen_path::__rt::Context) {
let test_name = ::core::concat!(::core::module_path!(), "::", ::core::stringify!(#ident));
#test_body
}
}
};
},
);
16 changes: 5 additions & 11 deletions crates/test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ version = "0.3.49"

[features]
default = ["std"]
msrv = ["wasm-bindgen/msrv", "wasm-bindgen-test-macro/msrv"]
std = ["wasm-bindgen/std", "js-sys/std", "wasm-bindgen-futures/std"]

[dependencies]
@@ -20,18 +21,11 @@ wasm-bindgen = { path = '../..', version = '=0.2.99', default-features = false }
wasm-bindgen-futures = { path = '../futures', version = '=0.4.49', default-features = false }
wasm-bindgen-test-macro = { path = '../test-macro', version = '=0.3.49' }

[target.'cfg(all(target_arch = "wasm32", wasm_bindgen_unstable_test_coverage))'.dependencies]
minicov = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
unstable-test-coverage = { package = "minicov", version = "0.3", optional = true }

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(wasm_bindgen_unstable_test_coverage)'] }

[lints.clippy]
large_enum_variant = "allow"
new_without_default = "allow"
overly_complex_bool_expr = "allow"
too_many_arguments = "allow"
type_complexity = "allow"
[lints]
workspace = true

[lib]
test = false
24 changes: 12 additions & 12 deletions crates/test/src/coverage.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
use alloc::vec::Vec;
use wasm_bindgen::prelude::wasm_bindgen;

#[cfg(wasm_bindgen_unstable_test_coverage)]
#[cfg(feature = "unstable-test-coverage")]
#[wasm_bindgen]
pub fn __wbgtest_cov_dump() -> Option<Vec<u8>> {
let mut coverage = Vec::new();
// SAFETY: this function is not thread-safe, but our whole test runner is running single-threaded.
unsafe {
minicov::capture_coverage(&mut coverage).unwrap();
}
if coverage.is_empty() {
console_error!(
"Empty coverage data received. Make sure you compile the tests with
RUSTFLAGS=\"-Cinstrument-coverage -Zno-profile-runtime --emit=llvm-ir\"",
);

if unstable_test_coverage::counters() > 0 {
// SAFETY: this function is not thread-safe, but our whole test runner is running single-threaded.
unsafe {
unstable_test_coverage::capture_coverage(&mut coverage).unwrap();
}

Some(coverage)
} else {
None
}
Some(coverage)
}

#[cfg(not(wasm_bindgen_unstable_test_coverage))]
#[cfg(not(feature = "unstable-test-coverage"))]
#[wasm_bindgen]
pub fn __wbgtest_cov_dump() -> Option<Vec<u8>> {
None
6 changes: 3 additions & 3 deletions guide/src/wasm-bindgen-test/coverage.md
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ You can ask the runner to generate coverage data from functions marked as `#[was

## Enabling the feature

To enable this feature, you need to enable `cfg(wasm_bindgen_unstable_test_coverage)`.
To enable this feature, you need to enable the crate feature `unstable-test-coverage` on `wasm-bindgen-test`. Additionally its recommended to use the `msrv` crate feature on `wasm-bindgen-test` as well to disable profiling on internal functions, significantly improving the accuracy of the test coverage results.

## Generating the data

@@ -43,7 +43,7 @@ This adapts code taken from the [Rustc book], see that for more examples and gen
```sh
# Run the tests:
# `--tests` to not run documentation tests, which is currently not supported.
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir --cfg=wasm_bindgen_unstable_test_coverage" \
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir" \
CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUNNER=wasm-bindgen-test-runner \
cargo +nightly test --tests
# Compile to object files:
@@ -54,7 +54,7 @@ crate_name=name_of_the_tested_crate_in_snake_case
objects=()
IFS=$'\n'
for file in $(
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir --cfg=wasm_bindgen_unstable_test_coverage" \
RUSTFLAGS="-Cinstrument-coverage -Zno-profiler-runtime --emit=llvm-ir" \
cargo +nightly test --tests --no-run --message-format=json | \
jq -r "select(.reason == \"compiler-artifact\") | (select(.target.kind == [\"test\"]) // select(.target.name == \"$crate_name\")) | .filenames[0]"
)
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.