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
Show file tree
Hide file tree
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
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 4 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Up @@ -15,6 +15,7 @@ version = "0.2.99"

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

[dependencies]
bumpalo = "3.0.0"
Expand Down
31 changes: 21 additions & 10 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}
Expand Down Expand Up @@ -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) {
Expand All @@ -320,7 +321,6 @@ impl ToTokens for ast::Struct {
let _ = <#name as #wasm_bindgen::convert::FromWasmAbi>::from_abi(ptr);
}
}
}
};

#[automatically_derived]
Expand Down Expand Up @@ -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>
{
Expand All @@ -517,7 +518,6 @@ impl ToTokens for ast::StructField {
let val = #val;
<#ty as IntoWasmAbi>::into_abi(val).into()
}
}
};
})
.to_tokens(tokens);
Expand All @@ -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,)*
Expand All @@ -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);
Expand All @@ -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) => {
Expand Down Expand Up @@ -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)*
Expand All @@ -841,7 +841,6 @@ impl TryToTokens for ast::Export {
let #ret = #call;
#convert_ret
}
}
};
})
.to_tokens(into);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Up @@ -15,6 +15,7 @@ version = "0.2.99"

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

[dependencies]
Expand Down
1 change: 1 addition & 0 deletions crates/macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []

Expand Down
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
|
Expand Down
3 changes: 3 additions & 0 deletions crates/test-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ version = "0.3.49"
[lib]
proc-macro = true

[features]
msrv = []

[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
Expand Down
9 changes: 7 additions & 2 deletions crates/test-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
};
},
);
Expand Down
16 changes: 5 additions & 11 deletions crates/test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions guide/src/wasm-bindgen-test/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand All @@ -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]"
)
Expand Down
Loading
Loading