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

Consider supporting re-exporting rstest crate #299

Open
FirelightFlagboy opened this issue Feb 27, 2025 · 2 comments
Open

Consider supporting re-exporting rstest crate #299

FirelightFlagboy opened this issue Feb 27, 2025 · 2 comments

Comments

@FirelightFlagboy
Copy link

FirelightFlagboy commented Feb 27, 2025

Hello,

I've a scenario where I've a tests-utils crate that contain some stuff useful for testing.
This crate notably re-export rstest so I just have to import the utility crate when needed.

So it can be used like this:

#[test_utils::utils::rstest::rstest]
#[case("foo")]
fn it_works(#[case] s: &str) {
    assert_eq!(s, "foo");
}

But with crate-name feature disable, the test fail to compile with the following error:

error[E0433]: failed to resolve: use of undeclared crate or module `rstest`
 --> src/lib.rs:3:5
  |
3 |     #[test_utils::utils::rstest::rstest]
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared crate or module `rstest`
  |
  = note: this error originates in the attribute macro `test_utils::utils::rstest::rstest` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0425]: cannot find function, tuple struct or tuple variant `Magic` in this scope
 --> src/lib.rs:3:5
  |
3 |     #[test_utils::utils::rstest::rstest]
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
  |
  = note: this error originates in the attribute macro `test_utils::utils::rstest::rstest` (in Nightly builds, run with -Z macro-backtrace for more info)
Using cargo expand, I can see that the issue is caused by the use rstest::magic_conversion::*.
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
#[cfg(test)]
mod tests {
    #[cfg(test)]
    fn it_works(s: &str) {
        {
            match (&s, &"foo") {
                (left_val, right_val) => {
                    if !(*left_val == *right_val) {
                        let kind = ::core::panicking::AssertKind::Eq;
                        ::core::panicking::assert_failed(
                            kind,
                            &*left_val,
                            &*right_val,
                            ::core::option::Option::None,
                        );
                    }
                }
            };
        }
    }
    #[cfg(test)]
    mod it_works {
        use super::*;
        extern crate test;
        #[cfg(test)]
        #[rustc_test_marker = "tests::it_works::case_1"]
        #[doc(hidden)]
        pub const case_1: test::TestDescAndFn = test::TestDescAndFn {
            desc: test::TestDesc {
                name: test::StaticTestName("tests::it_works::case_1"),
                ignore: false,
                ignore_message: ::core::option::Option::None,
                source_file: "src/lib.rs",
                start_line: 5usize,
                start_col: 8usize,
                end_line: 5usize,
                end_col: 16usize,
                compile_fail: false,
                no_run: false,
                should_panic: test::ShouldPanic::No,
                test_type: test::TestType::UnitTest,
            },
            testfn: test::StaticTestFn(
                #[coverage(off)]
                || test::assert_test_result(case_1()),
            ),
        };
        fn case_1() {
            let s = {
                use rstest::magic_conversion::*;
                (&&&Magic::<&str>(core::marker::PhantomData)).magic_conversion("foo")
            };
            it_works(s)
        }
    }
}
#[rustc_main]
#[coverage(off)]
#[doc(hidden)]
pub fn main() -> () {
    extern crate test;
    test::test_main_static(&[&case_1])
}

If I enable crate-name feature, I get another error:

error: custom attribute panicked
 --> src/lib.rs:3:5
  |
3 |     #[test_utils::utils::rstest::rstest]
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = help: message: rstest is present in `Cargo.toml` qed: Could not find `rstest` in `dependencies` or `dev-dependencies` in `/tmp/rstest-re-export/Cargo.toml`!

I would like to known if you are interested to add the attribute crate to fixture and rstest macro to allow to specify the path to the rstest crate?

It would be used like this:

#[test_utils::utils::rstest::rstest(crate = ::test_utils::utils::rstest)]
#[case("foo")]
fn it_works(#[case] s: &str) {
    assert_eq!(s, "foo");
}

This issue is similar to #221 but here the crate rstest is not renamed but re-exported from another crate.

I could provide a PR if needed.


Sources code

cargo.toml:

[package]
name = "rstest-re-export"
version = "0.1.0"
edition = "2021"

[dev-dependencies]
test-utils = { path = "./test-utils" }

[workspace.dependencies]
rstest = { version = "=0.24.0", default-features = false }

src/lib.rs:

#[cfg(test)]
mod tests {
    #[test_utils::utils::rstest::rstest]
    #[case("foo")]
    fn it_works(#[case] s: &str) {
        assert_eq!(s, "foo");
    }
}

test-utils/Cargo.toml:

[package]
name = "test-utils"
version = "0.1.0"
edition = "2021"

[dependencies]
rstest = { workspace = true }

test-utils/src/lib.rs:

pub mod utils {
    pub use rstest;
}
@la10736
Copy link
Owner

la10736 commented Feb 28, 2025

AFAIK there is no way to know how the user call a procedural macro in a procedural macro: to be more explicit rstest procedural macro will not receive test_utils::utils::rstest::rstest path anymore: that means that isn't possible to know how to identify the crate path where rstest is. Unfortunately in procedural macro you don't have the $crate like in normal macro's to identify the crate where the macro come, the crate-name feature just use a work around but suppose that rstest is imported as dependency in you manifest.

But, even if I was able to identify the path, your crate should also rexport all rstest pub's.

Only way to do it is feature gate the lib utilities like magic conversion and timeout. But I'm not sure it's a worth of it.

If you would provide a PR for feature gating these functionalities, enabled by default with a clear error in the case that a use a function gated out, I'll be happy to review and include it.

@FirelightFlagboy
Copy link
Author

AFAIK there is no way to know how the user call a procedural macro in a procedural macro:
to be more explicit rstest procedural macro will not receive test_utils::utils::rstest::rstest

I understand that, that's why I proposed to add the attribute crate to allow user to indicate the path to rstest crate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants