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

Cannot use non-inline modules in a proc macro (second attempt to move tests to separate file) #1632

Open
theory opened this issue Apr 3, 2024 · 5 comments

Comments

@theory
Copy link
Contributor

theory commented Apr 3, 2024

In follow-up to #1631, I followed the second example in this Discord post, setting up the test module like so:

#[cfg(test)]
#[path = "./tests.rs"]
mod test;

And the contents of tests.rs are:

#![pg_schema]
use pgrx::prelude::*;

#[pg_test]
fn test_hello_separate_tests() {
    assert_eq!("Hello, separate_tests", crate::hello_separate_tests());
}

/// This module is required by `cargo pgrx test` invocations.
/// It must be visible at the root of your extension crate.
#[cfg(test)]
pub mod pg_test {
    pub fn setup(_options: Vec<&str>) {
        // perform one-off initialization when the pg_test framework starts
    }

    pub fn postgresql_conf_options() -> Vec<&'static str> {
        // return any postgresql.conf settings that are required for your tests
        vec![]
    }
}

But the compiler complains:

error[E0658]: non-inline modules in proc macro input are unstable
  --> src/lib.rs:12:1
   |
12 | mod tests;
   | ^^^^^^^^^^
   |
   = note: see issue #54727 <https://github.com/rust-lang/rust/issues/54727> for more information

error: custom attribute panicked
  --> src/lib.rs:11:1
   |
11 | #[pg_schema]
   | ^^^^^^^^^^^^
   |
   = help: message: Can only support `mod {}` right now.

For more information about this error, try `rustc --explain E0658`.
error: could not compile `separate_tests` (lib test) due to 2 previous errors

The errors go away if I remove #![pg_schema] and change the test_hello_separate_tests from #[pg_test] to #[test].

@theory
Copy link
Contributor Author

theory commented Apr 3, 2024

This almost works for the contents of tests.rs:

use pgrx::prelude::*;

#[cfg(any(test, feature = "pg_test"))]
#[pg_schema]
mod gotest {

    #[pg_test]
    fn test_hello_separate_tests() {
        assert_eq!("Hello, separate_tests", crate::hello_separate_tests());
    }
}

/// This module is required by `cargo pgrx test` invocations.
/// It must be visible at the root of your extension crate.
#[cfg(test)]
pub mod pg_test {
    pub fn setup(_options: Vec<&str>) {
        // perform one-off initialization when the pg_test framework starts
    }

    pub fn postgresql_conf_options() -> Vec<&'static str> {
        // return any postgresql.conf settings that are required for your tests
        vec![]
    }
}

The only error is from #[pg_test] over the test function:

cannot find attribute `pg_test` in this scope

It works if I use #[test] instead; maybe I need to qualify the name somehow?

@workingjubilee
Copy link
Member

workingjubilee commented Apr 4, 2024

In follow-up to #1631, I followed the second example in this Discord post, setting up the test module like so:

#[cfg(test)]
#[path = "./tests.rs"]
mod test;

Hmm, this should be

#[cfg(test)]
mod tests;

This doesn't matter, however.

Interesting. A comment in the pg_schema macro's entrypoint claims that this usage is blocked on rust-lang/rust#54725 but I don't think so since we pervasively reference module_path. Everything here should work just fine for pg_schema as an inner attribute, it just requires hitting it with a wrench fixing a few codepaths.

It works if I use #[test] instead; maybe I need to qualify the name somehow?

This requires the test module to contain:

mod gotest {
    use super::*;

Because the prelude of pgrx is not automatically visible inside submodules inside a file.

@theory
Copy link
Contributor Author

theory commented Apr 15, 2024

Hmm, this should be

#[cfg(test)]
mod tests;

I think it could be if I named the file ./tests/lib.rs or something. But I named it tests.rs so had to tell it where to find the module.

This requires the test module to contain:

mod gotest {
    use super::*;

Because the prelude of pgrx is not automatically visible inside submodules inside a file.

After my original post I got as far as a single issue by adding use super::pg_test;, which achieves the same thing (better to import all tho). It still complains:

error[E0433]: failed to resolve: unresolved import
 --> src/./tests.rs:8:5
  |
8 |     #[pg_test]
  |     ^^^^^^^^^^ unresolved import
  |
  = note: this error originates in the attribute macro `pg_test` (in Nightly builds, run with -Z macro-backtrace for more info)
help: a similar path exists
  |
8 |     crate::tests::pg_test
  |
help: consider importing this module
  |
6 +     use crate::tests::pg_test;
  |

Amusingly I get exactly the same error if I use crate::tests::pg_test;.

@workingjubilee
Copy link
Member

I think it could be if I named the file ./tests/lib.rs or something. But I named it tests.rs so had to tell it where to find the module.

That is not the case.

Are you writing this somewhere other than lib.rs? Modules are hierarchical.

You may find reading fasterthanlime's article helpful.

@theory
Copy link
Contributor Author

theory commented Apr 16, 2024

I think it could be if I named the file ./tests/lib.rs or something. But I named it tests.rs so had to tell it where to find the module.

That is not the case.

Okay I just removed the #[path = "./tests.rs"] and it's no different. I must have previous had it named mod test or something, hence the confusion.

Are you writing this somewhere other than lib.rs? Modules are hierarchical.

I am not.

You may find reading fasterthanlime's article helpful.

🔖ed!

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

No branches or pull requests

2 participants