I have some code I am working on that has a certain struct object Permissions:-
// Stores permissions with a bit flag
/// 1 << ? - Vote - Anyone with a weight > 0 can vote.
/// 1 << ? - Execute - If the proposal passed then anyone can execute the transaction.
/// 1 << 0 - Propose
/// 1 << 1 - Add asset
#[derive(Clone, Copy)]
pub struct Permissions {
permissions: u8,
}
Its fields are private so it is less likely to be in an invalid state, it is accessed through functions.
All the functions to be used in the actual production code, ensure that every instance is valid, but to be sure of that I want to make invalid instances so I can run tests and see how the code would behave.
To do that I wrote some helper functions, which I wanted to gate from the actual code using #[cfg(test)], additionally the Permissions object is never used alone, so the test cases that are constructed are not in the same module as the Permissions object, they are in a different module dedicated for unit tests.
The problem is that I can't import the functions defined in that module into the other module for tests.
This is an MRE imitating the structure of the project and giving the same errors:-
mre-1/
mre-1/src
mre-1/src/lib.rs
mre-1/tests
mre-1/tests/test.rs
mre-1/Cargo.toml
lib.rs:-
pub fn hello_world() {
println!("Hello, world!");
}
pub struct Test{
field:u8
}
#[cfg(test)]
impl Test{
pub fn testing_1(){
println!("Testing")
}
pub(crate) fn testing_2(){
println!("Testing")
}
}
test.rs:-
#![cfg(test)]
use mre_1::{
Test,
hello_world
};
#[cfg(test)]
fn testing(){
hello_world();
Test::testing_1();
Test::testing_2();
}
The code in test.rs cannot find testing_1 from lib.rs
I have gotten around this by using custom feature flags instead, which would gate it and then I would have to enable the feature when running the tests, rather than gating it with #[cfg(test)], this works, but when I do this rust-analyzer stop offering services, but I can work around this by changing some settings manually in my IDE.
What is a more idiomatic way of doing this, so anyone viewing the project can look through it without having to touch their IDE settings or anything of that sort?
#[cfg(test)]-- Did you also make these functions at leastpub(crate)if notpub? It works for me. Please show a minimal reproducible example.testonly applies to that crate - not your library. You'll need to either use unit tests (probably preferable if relying on non-public functionality), or some other feature gating like it sounds you've already tried.tests/. These are tests are from the perspective of an external consumer, you would be importing your library as an external crate. These don't need acfg(test)flag either. Unit tests, that @kmdreko mentioned, are stored as part of your library code, and can access non-public functionality. Keep those tests withinsrc, either in separate files, or under a test gate within the module. See: rust-exercises.com/advanced-testing/04_interlude/…