I have a piece of code that should only be compiled in "pedantic" mode, which is set up as a crate feature. Said pedantic mode is also expected to be enabled in testing. This lives nested inside an if branch, in a fn foo() inside an impl Bar for trait Baz:
#[cfg(test)] is only enabled on unit tests, in other words tests marked as #[test] under the src directory. Tests under the tests are called integration tests, and they're treated as independent crates which have your library as a dependency.
AFAIK it's not possible purely with cargo. There's required-features flag, but it's to skip the test if appropriate features are not enabled. You can use external task runner or command alias to call cargo test with proper features, and/or configure the CI.
@2e71828 thanks! Indeed, putting this expression in a pub(crate) constant solves the problem in a way that is perfectly acceptable to me.
@VorfeedCanal thank you for your input. However, you lack all the context here - pedantism here means equivalence of output with a legacy tool that was unnecessarily more stringent than spec. It's my conscious decision to hide this behaviour behind an optional feature (for new client code), but always running the integration tests of this equivalence helps maintain backwards compatibility. As Hyeonu pointed out, I'd have to use external tooling to achieve this otherwise, which has its own drawbacks. All in all, principles can be the enemy of shipping good software.
required-features is not an adequate solution, BTW, because it can only ever skip tests. And skipping tests is functionally equivalent to relaxing the requirements. I'm not entirely sure why this was considered a good idea in the first place.
Yes, principles often push you to make a decision: ship crap or not ship anything at all.
And sometimes shipping crap is the right decision. In fact it's very often the right decision. Perfect is enemy of good, if you wouldn't ship crap very often you would lose financing and as a result wouldn't ship anything at all. But it has to be conscious decision.
So now you both can not remove code which implement that strict mode and users couldn't get benefits from your efforts, too.
That's rarely a good long-term solution. Additional hassle which is needed to maintain that state of affairs would be a constant incentive to do something about that. Which is a good thing.
Because it is the right solution. Next step: when you no longer maintain backward compatibility in your crate unconditionally but still want to keep that old, obsolete, mode around for some time.
Look, I don't have time to argue about the validity of my choices with a random opinionated person on the internet. I will not engage with this line any further.
@2e71828 unfortunately, this will ultimately not work - the environment variables are only set when building the test targets, while the code that needs to know about the pedantic switch lives in the lib target. It seems I'll have to go the external way after all.