I'm try to compose a generic solution to provide fixtures for unit testing Rust code. I have come up with a macro, which allows the user to define setup and teardown methods. Here is my solution so far:
struct FooTestFixture {
pub name : String
}
impl FooTestFixture {
fn setup() -> FooTestFixture {
FooTestFixture { name: String::from("Initialised") }
}
}
fn teardown(fixture : &mut FooTestFixture) {
fixture.name = "".to_string();
}
macro_rules! unit_test {
($name:ident $fixt:ident $expr:expr) => (
#[test]
fn $name() {
let mut $fixt : FooTestFixture = FooTestFixture::setup();
$expr;
teardown(&mut $fixt);
}
)
}
unit_test! (heap_foo_fixture_should_be_initialised_using_macro f {
assert_eq!(f.name, "Initialised");
});
This works. The only problem is, that the macro unit_test is not generic, and is bound to the fixture name FooTestFixture. This means that each test module needs to redefine this macro for every test fixture, which is not ideal. What I'd like to be able to do is to also introduce a type variable and use that type in the macro expansion. Delving more into macros I have found that there is a 'ty' item, that represents a type, and I thought I could do this ...
macro_rules! unit_test {
($name:ident $fixt:ident $ftype:ty $expr:expr) => (
#[test]
fn $name() {
let mut $fixt : $ftype = $ftype::setup();
$expr;
teardown(&mut $fixt);
}
)
}
unit_test! (heap_foo_fixture_should_be_initialised_using_macro FooTestFixture f {
assert_eq!(f.name, "Initialised");
});
However, this doesn't work and results in the following error:
src\tests\heap_fixture_with_new.rs:48:40: 48:50 error:
$ftype:tyis followed by$expr:expr, which is not allowed fortyfragments src\tests\heap_fixture_with_new.rs:48 ($name:ident $fixt:ident $ftype:ty $expr:expr) => (
As you can see, in the macro definition, I have replaced references to FooTestFixture with $ftype.
Is what I'm trying to achieve possible? It's almost like I'd like the macro to be generic, allowing you to pass in a type, to be used inside the macro definition.
Aucun commentaire:
Enregistrer un commentaire