59 lines
1.4 KiB
Rust
59 lines
1.4 KiB
Rust
|
use cucumber::{given, then, when, World};
|
||
|
|
||
|
// These `Cat` definitions would normally be inside your project's code,
|
||
|
// not test code, but we create them here for the show case.
|
||
|
#[derive(Debug, Default)]
|
||
|
struct Cat {
|
||
|
pub hungry: bool,
|
||
|
}
|
||
|
|
||
|
impl Cat {
|
||
|
fn feed(&mut self) {
|
||
|
self.hungry = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// `World` is your shared, likely mutable state.
|
||
|
// Cucumber constructs it via `Default::default()` for each scenario.
|
||
|
#[derive(Debug, World)]
|
||
|
// Accepts both sync/async and fallible/infallible functions.
|
||
|
// We can set a non default constructor like this vvvv
|
||
|
#[world(init = Self::new)]
|
||
|
pub struct AnimalWorld {
|
||
|
cat: Cat,
|
||
|
}
|
||
|
|
||
|
// new constructor
|
||
|
impl AnimalWorld {
|
||
|
fn new() -> Self {
|
||
|
Self {
|
||
|
cat: Cat { hungry: true },
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Steps are defined with `given`, `when` and `then` attributes.
|
||
|
#[given(regex = r"^a (hungry|satiated) cat$")]
|
||
|
async fn hungry_cat(world: &mut AnimalWorld, state: String) {
|
||
|
match state.as_str() {
|
||
|
"hungry" => world.cat.hungry = true,
|
||
|
"satiated" => world.cat.hungry = false,
|
||
|
_ => unreachable!(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[when("I feed the cat")]
|
||
|
async fn feed_cat(world: &mut AnimalWorld) {
|
||
|
world.cat.feed();
|
||
|
}
|
||
|
|
||
|
#[then("the cat is not hungry")]
|
||
|
async fn cat_is_fed(world: &mut AnimalWorld) {
|
||
|
assert!(!world.cat.hungry);
|
||
|
}
|
||
|
|
||
|
#[tokio::main]
|
||
|
async fn main() {
|
||
|
futures::executor::block_on(AnimalWorld::run("tests/features/book/animal.feature"));
|
||
|
}
|