-
Notifications
You must be signed in to change notification settings - Fork 43
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
By-reference fixtures #241
Comments
Yes, it'll be very nice to have this feature. Freak free to open a PR. |
While I was fixing #230 I noted that the following syntax will work use std::cell::Cell;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum E<'a> {
A(bool),
B(&'a Cell<E<'a>>),
}
fn make_e_from_bool<'a>(b: bool) -> E<'a> {
E::A(b)
}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[rstest]
#[case(true, E::A(true))]
fn it_works<'a>(#[case] b: bool, #[case] expected: E<'a>) {
let actual = make_e_from_bool(b);
assert_eq!(actual, expected);
}
} Is this code fine for you? |
Unfortunately not. This is my real code: #[rstest]
#[case::bool("true", Value::Bool(true))]
fn test_eval<'a>(bump: &'a Bump, #[case] src: &'static str, #[case] expected: Value<'a>) {
pretty_assertions::assert_eq!(eval_str(bump, src).unwrap(), expected);
}
|
And what about to use With the unreleased version follow code works use std::cell::Cell;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum E<'a> {
A(bool),
B(&'a Cell<E<'a>>),
}
fn make_e_from_bool<'a>(_bump: &'a (), b: bool) -> E<'a> {
E::A(b)
}
fn new_bump() {}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[fixture]
#[once]
fn bump() -> () {}
#[rstest]
#[case(true, E::A(true))]
fn it_works<'a>(bump: &'a (), #[case] b: bool, #[case] expected: E<'a>) {
let actual = make_e_from_bool(&bump, b);
assert_eq!(actual, expected);
}
} |
A |
That's new for me... why static reference is marked as memory leak in valgrind? Ok, verbose set up will report it as an not released static reference but should not be an issue. Anyway I cannot accept a PR about this just because is a breaking change when Beside that my next feature will be a use std::cell::Cell;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum E<'a> {
A(bool),
B(&'a Cell<E<'a>>),
}
fn make_e_from_bool<'a>(_bump: &'a (), b: bool) -> E<'a> {
E::A(b)
}
fn new_bump() {}
#[cfg(test)]
mod tests {
use rstest::rstest;
use super::*;
#[fixture]
fn bump() -> () {}
#[rstest]
#[case(true, E::A(true))]
fn it_works<'a>(#[map(|b| &b)] bump: &'a (), #[case] b: bool, #[case] expected: E<'a>) {
let actual = make_e_from_bool(&bump, b);
assert_eq!(actual, expected);
}
} |
I think that even with a
I think there’s a non-breaking way to implement this by annotating fixture parameters with an attribute to enable pass-by-reference, like this: #[fixture]
fn f() -> u32 { 42 }
#[rstest]
fn test(#[by_reference] f: &u32) {
assert_eq!(*f, 42);
}
How would that work? It looks like the closure returns a reference to a local variable? |
Right!
Yes, that's feasible. Maybe the right syntax can be just |
I don’t think
You mean also for rstest/rstest_macros/src/parse/rstest.rs Lines 134 to 140 in 06a2117
fn f(#[case] #[by_reference] x: u32) as both a test case input and a fixture when both parsers recognise #[by_reference] .
For now I’d like to get this feature working (and robust) for |
Ok Example : #[fixture]
fn f() -> u32 { 42 }
#[rstest]
#[case(42)]
fn test(#[by_ref] f: &u32, #[case] #[by_ref] c: &u32, #[values(42, 142)] #[by_ref] v: &u32) {
assert_eq!(f, c);
assert_eq!(*c, *v%100);
} it'll be expanded in something like follow: mod f {
fn default() -> u32 {
42
}
}
fn test(f: &u32, c: &u32, v: &u32) {
assert_eq!(f, c);
assert_eq!(*c, *v%100);
}
mod test {
use super::*;
mod case_1 {
use super::*;
#[test]
fn v_1_42() {
let f = f::default();
let c = 42;
let v = 42;
test(&f, &c, &v)
}
#[test]
fn v_2_142() {
let f = f::default();
let c = 42;
let v = 142;
test(&f, &c, &v)
}
}
} |
@narpfel I've implemented it in https://github.com/la10736/rstest/tree/by_ref |
That branch works for my use case. Thanks! |
I have an annoying problem regarding invariant lifetimes in test case inputs.
A simplified example:
E
contains a reference to aCell
containing anE
, making it invariant in the lifetime parameter'a
. This means that the automatically derivedPartialEq
instance requires that bothE
objects have the same lifetime parameter. However,actual
’s lifetime is tied to the lifetime ofbump
viamake_e_from_bool
, whileexpected
can have any lifetime. (In my real code,bump
is abumpalo::Bump
, so I can’t leak it if I don’t want memory leaks. Another solution that I don’t really want to use is to implementPartialEq
forE
by hand, because that’s error-prone whenE
is changed.)If it was possible to take
bump
by reference from a fixture, this would not be a problem, because the signature ofit_works
could specify the correct lifetimes forbump
andexpected
:I have an (untested proof-of-concept) implementation of this here that checks if parameters to test functions are references and adds
&
inrender_exec_call
if they are. Is this a feature you’d like to have inrstest
? The generated code looks like this:The text was updated successfully, but these errors were encountered: