Skip to content
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

Replace #[derive(WorldInit)] macro with #[derive(World)] (#217) #219

Merged
merged 6 commits into from
Jul 7, 2022

Conversation

ilslv
Copy link
Member

@ilslv ilslv commented Jul 7, 2022

Resolves #217

Synopsis

To improve ergonomics we should unify WorldInit and World traits and macros.

Solution

Replace #[derive(WorldInit)] macro with #[derive(World)] and remove the WorldInit trait by moving all methods from it into the World trait.

Checklist

  • Created PR:
    • In draft mode
    • Name contains Draft: prefix
    • Name contains issue reference
    • Has assignee
  • Documentation is updated (if required)
  • Tests are updated (if required)
  • Changes conform code style
  • CHANGELOG entry is added (if required)
  • FCM (final commit message) is posted
    • and approved
  • Review is completed and changes are approved
  • Before merge:
    • Milestone is set
    • PR's name and description are correct and up-to-date
    • Draft: prefix is removed
    • All temporary labels are removed

@ilslv ilslv added enhancement Improvement of existing features or bugfix semver::breaking Represents breaking changes labels Jul 7, 2022
@ilslv ilslv added this to the 0.14.0 milestone Jul 7, 2022
@ilslv ilslv self-assigned this Jul 7, 2022
@ilslv
Copy link
Member Author

ilslv commented Jul 7, 2022

FCM

Replace `#[derive(WorldInit)]` macro with `#[derive(World)]` (#219, #217)

- merge `WorldInit` trait into the `World` trait

@ilslv
Copy link
Member Author

ilslv commented Jul 7, 2022

@tyranron I've also decided to remove WorldInit trait entirely and move all blanket methods into the World trait itself. I'm not sure though is it ok to have different number of trait methods based on macros feature. But as they are blanket impls and I don't think practically anyone uses this crate without macros, I've decided to do it to simplify imports.

In case you have a different view, just revert the last commit. All changes related to WorldInit removal are there.

Before:

use std::{convert::Infallible, time::Duration};

use async_trait::async_trait;
use cucumber::{given, then, when, World, WorldInit};
use tokio::time::sleep;

#[derive(Debug, WorldInit)]
struct MyWorld {
    user: Option<String>,
    capacity: usize,
}

#[async_trait(?Send)]
impl World for MyWorld {
    type Error = Infallible;

    async fn new() -> Result<Self, Self::Error> {
        Ok(Self { user: None, capacity: 0 })
    }
}

#[given(expr = "{word} is hungry")] // Cucumber Expression
async fn someone_is_hungry(w: &mut MyWorld, user: String) {
    sleep(Duration::from_secs(2)).await;
    
    w.user = Some(user);
}

#[when(regex = r"^(?:he|she|they) eats? (\d+) cucumbers?$")]
async fn eat_cucumbers(w: &mut MyWorld, count: usize) {
    sleep(Duration::from_secs(2)).await;

    w.capacity += count;
    
    assert!(w.capacity < 4, "{} exploded!", w.user.as_ref().unwrap());
}

#[then("she is full")]
async fn is_full(w: &mut MyWorld) {
    sleep(Duration::from_secs(2)).await;

    assert_eq!(w.capacity, 3, "{} isn't full!", w.user.as_ref().unwrap());
}

#[tokio::main]
async fn main() {
    MyWorld::run("tests/features/readme").await;
}

After:

use std::time::Duration;

use cucumber::{given, then, when, World};
use tokio::time::sleep;

#[derive(Debug, Default, World)]
struct MyWorld {
    user: Option<String>,
    capacity: usize,
}

#[given(expr = "{word} is hungry")] // Cucumber Expression
async fn someone_is_hungry(w: &mut MyWorld, user: String) {
    sleep(Duration::from_secs(2)).await;
    
    w.user = Some(user);
}

#[when(regex = r"^(?:he|she|they) eats? (\d+) cucumbers?$")]
async fn eat_cucumbers(w: &mut MyWorld, count: usize) {
    sleep(Duration::from_secs(2)).await;

    w.capacity += count;
    
    assert!(w.capacity < 4, "{} exploded!", w.user.as_ref().unwrap());
}

#[then("she is full")]
async fn is_full(w: &mut MyWorld) {
    sleep(Duration::from_secs(2)).await;

    assert_eq!(w.capacity, 3, "{} isn't full!", w.user.as_ref().unwrap());
}

#[tokio::main]
async fn main() {
    MyWorld::run("tests/features/readme").await;
}

@ilslv ilslv requested a review from tyranron July 7, 2022 11:43
@tyranron tyranron merged commit 820dd99 into main Jul 7, 2022
@tyranron tyranron deleted the replace-world-init-macro-with-world branch July 7, 2022 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement of existing features or bugfix semver::breaking Represents breaking changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merge confusing World and WorldInit derives
2 participants