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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ All user visible changes to `cucumber` crate will be documented in this file. Th

### BC Breaks

- Bump up [MSRV] to 1.62 for more clever support of [Cargo feature]s and simplified codegen. ([fbd08ec2], [cf055ac0], [todo])
- Bumped up [MSRV] to 1.62 for more clever support of [Cargo feature]s and simplified codegen. ([fbd08ec2], [cf055ac0], [8ad5cc86])
- Replaced `#[derive(WorldInit)]` with `#[derive(World)]` to remove the need of manual `World` trait implementation. ([#219], [#217])
- Merged `WorldInit` trait into the `World` trait. ([#219])

### Changed

- Provided default CLI options are now global (allowed to be specified after custom subcommands). ([#216], [#215])

[#215]: /../../issues/215
[#216]: /../../pull/216
[#217]: /../../issues/217
[#219]: /../../pull/219
[8ad5cc86]: /../../commit/8ad5cc866bb9d6b49470790e3b0dd40690f63a09
[cf055ac0]: /../../commit/cf055ac06c7b72f572882ce15d6a60da92ad60a0
[fbd08ec2]: /../../commit/fbd08ec24dbd036c89f5f0af4d936b616790a166

Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ rustdoc-args = ["--cfg", "docsrs"]
[features]
default = ["macros"]
# Enables step attributes and auto-wiring.
macros = ["dep:cucumber-codegen", "dep:cucumber-expressions", "dep:inventory"]
macros = ["dep:anyhow", "dep:cucumber-codegen", "dep:cucumber-expressions", "dep:inventory"]
# Enables support for outputting in Cucumber JSON format.
output-json = ["dep:Inflector", "dep:serde", "dep:serde_json", "timestamps"]
# Enables support for outputting JUnit XML report.
Expand All @@ -37,6 +37,7 @@ output-junit = ["dep:junit-report", "timestamps"]
timestamps = []

[dependencies]
anyhow = { version = "1.0.58", optional = true }
async-trait = "0.1.40"
atty = "0.2.14"
clap = { version = "3.0", features = ["derive"] }
Expand Down
16 changes: 3 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,17 @@ Feature: Eating too much cucumbers may not be good for you

Implement `World` trait and describe steps:
```rust
use std::{convert::Infallible, time::Duration};
use std::time::Duration;

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

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

#[async_trait(?Send)]
impl cucumber::World for World {
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 World, user: String) {
sleep(Duration::from_secs(2)).await;
Expand Down
17 changes: 3 additions & 14 deletions book/src/architecture/parser.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Let's start by implementing a custom [`Parser`] which statically emits a single
[`Parser`] represents anything that emits a [`Stream`] of [feature]s.

```rust
# use std::{convert::Infallible, path::PathBuf, time::Duration};
# use std::{path::PathBuf, time::Duration};
#
# use async_trait::async_trait;
# use cucumber::{cli, gherkin, given, parser, then, when, World, WorldInit};
# use cucumber::{cli, gherkin, given, parser, then, when, World};
# use futures::{future, stream};
# use tokio::time::sleep;
#
Expand All @@ -24,22 +24,11 @@ Let's start by implementing a custom [`Parser`] which statically emits a single
# }
# }
#
# #[derive(Debug, WorldInit)]
# #[derive(Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# sleep(Duration::from_secs(2)).await;
Expand Down
15 changes: 1 addition & 14 deletions book/src/architecture/runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Now, let's implement a custom [`Runner`] which simply executes [scenario]s in [f

```rust
# use std::{
# convert::Infallible,
# panic::{self, AssertUnwindSafe},
# path::PathBuf,
# sync::Arc,
Expand All @@ -17,7 +16,6 @@ Now, let's implement a custom [`Runner`] which simply executes [scenario]s in [f
# use async_trait::async_trait;
# use cucumber::{
# cli, event, gherkin, given, parser, step, then, when, Event, World,
# WorldInit,
# };
# use futures::{
# future::{self, FutureExt as _},
Expand All @@ -37,22 +35,11 @@ Now, let's implement a custom [`Runner`] which simply executes [scenario]s in [f
# }
# }
#
# #[derive(Clone, Debug, WorldInit)]
# #[derive(Clone, Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# sleep(Duration::from_secs(2)).await;
Expand Down
33 changes: 5 additions & 28 deletions book/src/architecture/writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Finally, let's implement a custom [`Writer`] which simply outputs [cucumber even

```rust
# use std::{
# convert::Infallible,
# panic::{self, AssertUnwindSafe},
# path::PathBuf,
# sync::Arc,
Expand All @@ -17,7 +16,7 @@ Finally, let's implement a custom [`Writer`] which simply outputs [cucumber even
# use async_trait::async_trait;
# use cucumber::{
# cli, event, gherkin, given, parser, step, then, when, Event, World,
# WorldInit, WriterExt as _,
# WriterExt as _,
# };
# use futures::{
# future::{self, FutureExt as _},
Expand All @@ -37,22 +36,11 @@ Finally, let's implement a custom [`Writer`] which simply outputs [cucumber even
# }
# }
#
# #[derive(Clone, Debug, WorldInit)]
# #[derive(Clone, Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# sleep(Duration::from_secs(2)).await;
Expand Down Expand Up @@ -301,11 +289,11 @@ async fn main() {
> __TIP__: `CustomWriter` will print trash if we feed unordered [`event::Cucumber`]s into it. Though, we shouldn't care about order normalization in our implementations. Instead, we may just wrap `CustomWriter` into [`writer::Normalize`], which will do that for us.

```rust
# use std::{convert::Infallible, path::PathBuf, time::Duration};
# use std::{path::PathBuf, time::Duration};
#
# use async_trait::async_trait;
# use cucumber::{
# cli, event, gherkin, given, parser, then, when, Event, World, WorldInit,
# cli, event, gherkin, given, parser, then, when, Event, World,
# WriterExt as _,
# };
# use futures::{future, stream};
Expand All @@ -322,22 +310,11 @@ async fn main() {
# }
# }
#
# #[derive(Clone, Debug, WorldInit)]
# #[derive(Clone, Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# sleep(Duration::from_secs(2)).await;
Expand Down
36 changes: 6 additions & 30 deletions book/src/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ By default, the whole CLI is composed of [`Parser::Cli`], [`Runner::Cli`] and [`
CLI may be extended even more with arbitrary options, if required. In such case we should combine the final CLI by ourselves and apply it via [`Cucumber::with_cli()`] method.

```rust
# use std::{convert::Infallible, time::Duration};
# use std::time::Duration;
#
# use async_trait::async_trait;
# use cucumber::{cli, given, then, when, World, WorldInit};
# use cucumber::{cli, given, then, when, World};
# use futures::FutureExt as _;
# use tokio::time::sleep;
#
Expand All @@ -86,22 +85,11 @@ CLI may be extended even more with arbitrary options, if required. In such case
# }
# }
#
# #[derive(Debug, WorldInit)]
# #[derive(Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# match state.as_str() {
Expand Down Expand Up @@ -157,10 +145,9 @@ async fn main() {
[Cargo alias] is a neat way to define shortcuts for regularly used customized tests running commands.

```rust
# use std::{convert::Infallible, time::Duration};
# use std::time::Duration;
#
# use async_trait::async_trait;
# use cucumber::{cli, given, then, when, World, WorldInit};
# use cucumber::{cli, given, then, when, World};
# use futures::FutureExt as _;
# use tokio::time::sleep;
#
Expand All @@ -175,22 +162,11 @@ async fn main() {
# }
# }
#
# #[derive(Debug, WorldInit)]
# #[derive(Debug, Default, World)]
# pub struct AnimalWorld {
# cat: Animal,
# }
#
# #[async_trait(?Send)]
# impl World for AnimalWorld {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Infallible> {
# Ok(Self {
# cat: Animal::default(),
# })
# }
# }
#
# #[given(regex = r"^a (hungry|satiated) cat$")]
# async fn hungry_cat(world: &mut AnimalWorld, state: String) {
# match state.as_str() {
Expand Down
16 changes: 3 additions & 13 deletions book/src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,17 @@ These features are agnostic to the implementation, the only requirement is that
[Cucumber] implementations then simply hook into these keywords and execute the logic corresponding to the keywords. [`cucumber`] crate is one of such implementations and is the subject of this book.

```rust
# use std::{convert::Infallible, time::Duration};
# use std::time::Duration;
#
# use async_trait::async_trait;
# use cucumber::{given, then, when, WorldInit};
# use cucumber::{given, then, when, World as _};
# use tokio::time::sleep;
#
# #[derive(Debug, WorldInit)]
# #[derive(cucumber::World, Debug, Default)]
# struct World {
# user: Option<String>,
# capacity: usize,
# }
#
# #[async_trait(?Send)]
# impl cucumber::World for World {
# 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 World, user: String) {
sleep(Duration::from_secs(2)).await;
Expand Down
18 changes: 3 additions & 15 deletions book/src/output/json.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,11 @@ cucumber = { version = "0.13", features = ["output-json"] }

And configuring output to [`writer::Json`]:
```rust
# use std::{convert::Infallible, fs, io};
#
# use async_trait::async_trait;
# use cucumber::WorldInit;
use cucumber::writer;
# use std::{fs, io};
use cucumber::{writer, World as _};

# #[derive(Debug, WorldInit)]
# #[derive(cucumber::World, Debug, Default)]
# struct World;
#
# #[async_trait(?Send)]
# impl cucumber::World for World {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Self::Error> {
# Ok(World)
# }
# }
#
# #[tokio::main]
# async fn main() -> io::Result<()> {
Expand Down
18 changes: 3 additions & 15 deletions book/src/output/junit.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,11 @@ cucumber = { version = "0.13", features = ["output-junit"] }

And configuring output to [`writer::JUnit`]:
```rust
# use std::{convert::Infallible, fs, io};
#
# use async_trait::async_trait;
# use cucumber::WorldInit;
use cucumber::writer;
# use std::{fs, io};
use cucumber::{writer, World as _};

# #[derive(Debug, WorldInit)]
# #[derive(cucumber::World, Debug, Default)]
# struct World;
#
# #[async_trait(?Send)]
# impl cucumber::World for World {
# type Error = Infallible;
#
# async fn new() -> Result<Self, Self::Error> {
# Ok(World)
# }
# }
#
# #[tokio::main]
# async fn main() -> io::Result<()> {
Expand Down
Loading