From 718aa2d5bf87c91268b11123a4f756d549c261bf Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 18 Sep 2025 18:12:21 +0300 Subject: [PATCH 01/16] Fix `pr` CI job conditions --- .github/workflows/ci.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 035eb92c..34640cb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,7 @@ jobs: ################ pr: - if: ${{ github.event_name == 'pull_request' - && needs.clippy.result == 'success' - && needs.feature.result == 'success' - && needs.msrv.result == 'success' - && needs.rustdoc.result == 'success' - && needs.rustfmt.result == 'success' - && needs.test.result == 'success' - && needs.test-book.result == 'success' }} + if: ${{ always() && github.event_name == 'pull_request' }} needs: - clippy - feature @@ -39,7 +32,13 @@ jobs: - test-book runs-on: ubuntu-latest steps: - - run: true + - run: ${{ needs.clippy.result == 'success' + && needs.feature.result == 'success' + && needs.msrv.result == 'success' + && needs.rustdoc.result == 'success' + && needs.rustfmt.result == 'success' + && needs.test.result == 'success' + && needs.test-book.result == 'success' }} From 5a11df24109d7ec7986b4803ef401c6115f3ca4b Mon Sep 17 00:00:00 2001 From: tyranron Date: Thu, 18 Sep 2025 18:28:30 +0300 Subject: [PATCH 02/16] Tune lints for 1.90 Rust --- codegen/src/attribute.rs | 3 +-- src/runner/basic.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/codegen/src/attribute.rs b/codegen/src/attribute.rs index b81d1996..9395c564 100644 --- a/codegen/src/attribute.rs +++ b/codegen/src/attribute.rs @@ -302,8 +302,7 @@ impl Step { let (ident, ty) = parse_fn_arg(arg)?; let is_ctx_arg = - self.arg_name_of_step_context.as_ref().map(|i| *i == *ident) - == Some(true); + self.arg_name_of_step_context.as_ref().is_some_and(|i| i == ident); let decl = if is_ctx_arg { quote! { diff --git a/src/runner/basic.rs b/src/runner/basic.rs index 64e090ef..7679f7ca 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -188,7 +188,7 @@ impl RetryOptions { apply_cli( parse_tags(&scenario.tags) - .or_else(|| rule.and_then(|r| parse_tags(&r.tags))) + .or_else(|| parse_tags(&rule?.tags)) .or_else(|| parse_tags(&feature.tags)), ) } From 9ca76970b1d094251a8dddf7893101b200e4d79e Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 31 Oct 2025 18:23:13 +0200 Subject: [PATCH 03/16] Improve @dependabot PR labels --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2cb26e7c..d06be3e4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,6 +8,6 @@ updates: - package-ecosystem: github-actions directory: / - labels: ["enhancement", "github_actions", "k::dependencies"] + labels: ["enhancement", "github_actions", "k::dependencies", "k::toolchain"] schedule: interval: daily From 4c0925619d337cbde7d3c65cf0c82ed56be150e4 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 31 Oct 2025 18:25:36 +0200 Subject: [PATCH 04/16] Tune lints for 1.91 Rust --- codegen/src/lib.rs | 1 - src/lib.rs | 3 +-- src/runner/basic.rs | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 053927fa..ce4504bf 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -109,7 +109,6 @@ clippy::string_lit_as_bytes, clippy::string_lit_chars_any, clippy::string_slice, - clippy::string_to_string, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::suspicious_xor_used_as_pow, diff --git a/src/lib.rs b/src/lib.rs index 2bf68c09..7f6bce42 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,7 @@ html_logo_url = "https://avatars.githubusercontent.com/u/91469139?s=128", html_favicon_url = "https://avatars.githubusercontent.com/u/91469139?s=256" )] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(any(doc, test), doc = include_str!("../README.md"))] #![cfg_attr(not(any(doc, test)), doc = env!("CARGO_PKG_NAME"))] #![deny(nonstandard_style, rustdoc::all, trivial_casts, trivial_numeric_casts)] @@ -110,7 +110,6 @@ clippy::string_lit_as_bytes, clippy::string_lit_chars_any, clippy::string_slice, - clippy::string_to_string, clippy::suboptimal_flops, clippy::suspicious_operation_groupings, clippy::suspicious_xor_used_as_pow, diff --git a/src/runner/basic.rs b/src/runner/basic.rs index 7679f7ca..ab29c80e 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -976,10 +976,6 @@ async fn execute( coll.start_scenarios(&runnable); } async { - #[expect( // intentional - clippy::infinite_loop, - reason = "cannot annotate `async` block with `-> !" - )] loop { while let Some(logs) = logs_collector .as_mut() From 065cd9d701d49afe87bbdea5629110973ecc9c84 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 13:53:09 +0100 Subject: [PATCH 05/16] Upgrade `actions/checkout` from 5 to 6 version (#383) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/audit.yml | 2 +- .github/workflows/ci.yml | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/audit.yml b/.github/workflows/audit.yml index 1c1c088d..f4a9dde7 100644 --- a/.github/workflows/audit.yml +++ b/.github/workflows/audit.yml @@ -15,7 +15,7 @@ jobs: cargo-audit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: stable diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 34640cb0..293ff005 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: clippy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: stable @@ -61,7 +61,7 @@ jobs: rustfmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: nightly @@ -90,7 +90,7 @@ jobs: - tracing runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: nightly @@ -119,7 +119,7 @@ jobs: os: ["ubuntu", "macOS", "windows"] runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: nightly @@ -142,7 +142,7 @@ jobs: os: ["ubuntu", "macOS", "windows"] runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: ${{ matrix.toolchain }} @@ -163,7 +163,7 @@ jobs: os: ["ubuntu", "macOS", "windows"] runs-on: ${{ matrix.os }}-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: stable @@ -187,7 +187,7 @@ jobs: - cucumber runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: nightly @@ -211,7 +211,7 @@ jobs: needs: ["release-github"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: dtolnay/rust-toolchain@v1 with: toolchain: stable @@ -237,7 +237,7 @@ jobs: - test-book runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Parse release version id: release @@ -289,7 +289,7 @@ jobs: needs: ["test-book"] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: peaceiris/actions-mdbook@v2 - run: make book.build From a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 12 Dec 2025 15:07:34 +0100 Subject: [PATCH 06/16] Tune lints for 1.92 Rust - upgrade `cucumber-expressions` crate from 0.4 to 0.5 version - upgrade `gherkin` crate from 0.14 to 0.15 version - upgrade `synthez` crate from 0.3 to 0.4 version - bump up MSRV to 1.88 Additionally: - fix Book manifest for `mdBook` 0.5 --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 2 +- Cargo.toml | 6 +++--- README.md | 2 +- book/book.toml | 1 - codegen/CHANGELOG.md | 4 ++-- codegen/Cargo.toml | 6 +++--- codegen/README.md | 2 +- codegen/src/attribute.rs | 16 ++++++++-------- codegen/src/lib.rs | 1 + src/lib.rs | 1 + src/runner/basic.rs | 18 ++++++++---------- src/tracing.rs | 4 +--- src/writer/summarize.rs | 4 +--- 14 files changed, 32 insertions(+), 37 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 293ff005..f1a516a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -112,7 +112,7 @@ jobs: strategy: fail-fast: false matrix: - msrv: ["1.87.0"] + msrv: ["1.88.0"] crate: - cucumber-codegen - cucumber diff --git a/CHANGELOG.md b/CHANGELOG.md index ada5d03d..0c118f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ### BC Breaks -- Bumped up [MSRV] to 1.87 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c]) +- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c], [todo]) - Replaced `Arc` with `PartialEq`/`Hash` pointer-optimized `Source` in `event`s: ([#352]) - `Source` in `event::Cucumber::Feature`. - `Source` in `event::Feature::Rule`. diff --git a/Cargo.toml b/Cargo.toml index d970a94c..6346679c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "cucumber" version = "0.21.1" edition = "2024" -rust-version = "1.87" +rust-version = "1.88" description = """\ Cucumber testing framework for Rust, with async support. \ Fully native, no external test runners or dependencies.\ @@ -69,7 +69,7 @@ console = "0.16" derive_more = { version = "2.0", features = ["as_ref", "debug", "deref", "deref_mut", "display", "error", "from", "from_str", "into"] } either = "1.6" futures = "0.3.17" -gherkin = "0.14" +gherkin = "0.15" globwalk = "0.9" humantime = "2.1" itertools = "0.14" @@ -83,7 +83,7 @@ smart-default = "0.7.1" # "macros" feature dependencies. anyhow = { version = "1.0.58", optional = true } cucumber-codegen = { version = "=0.21.1", path = "./codegen", optional = true } -cucumber-expressions = { version = "0.4", features = ["into-regex"], optional = true } +cucumber-expressions = { version = "0.5", features = ["into-regex"], optional = true } inventory = { version = "0.3", optional = true } # "output-json" and/or "libtest" features dependencies. diff --git a/README.md b/README.md index dcc2f444..d4e7c170 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Cucumber testing framework for Rust =================================== [![crates.io](https://img.shields.io/crates/v/cucumber.svg?maxAge=2592000 "crates.io")](https://crates.io/crates/cucumber) -[![Rust 1.87+](https://img.shields.io/badge/rustc-1.87+-lightgray.svg "Rust 1.87+")](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0) +[![Rust 1.88+](https://img.shields.io/badge/rustc-1.88+-lightgray.svg "Rust 1.88+")](https://blog.rust-lang.org/2025/06/26/Rust-1.88.0) [![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg "Unsafe forbidden")](https://github.com/rust-secure-code/safety-dance)\ [![CI](https://github.com/cucumber-rs/cucumber/actions/workflows/ci.yml/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain) [![Rust docs](https://docs.rs/cucumber/badge.svg "Rust docs")](https://docs.rs/cucumber) diff --git a/book/book.toml b/book/book.toml index f94485a3..8fb4bb05 100644 --- a/book/book.toml +++ b/book/book.toml @@ -2,7 +2,6 @@ title = "Cucumber Rust Book" description = "User guide for Cucumber Rust" language = "en" -multilingual = false authors = [ "Olga Gaponenko (@alvskar)", "Ilya Solovyiov (@ilslv)", diff --git a/codegen/CHANGELOG.md b/codegen/CHANGELOG.md index 788aae26..e697a8a1 100644 --- a/codegen/CHANGELOG.md +++ b/codegen/CHANGELOG.md @@ -13,13 +13,13 @@ All user visible changes to `cucumber-codegen` crate will be documented in this ### BC Breaks -- Bumped up [MSRV] to 1.87 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [todo]) +- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c]) +[0c7dfc3c]: /../../commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed [4010c1ad]: /../../commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f [9705253b]: /../../commit/9705253bda5caadfe3eea91f50420222158dd944 [b46930c3]: /../../commit/b46930c32ef5ae490df8063905144a45de27eda1 [f1307038]: /../../commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf -[todo]: /../../commit/todo diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index db3cb34f..e46cf6ac 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -2,7 +2,7 @@ name = "cucumber-codegen" version = "0.21.1" # should be the same as main crate version edition = "2024" -rust-version = "1.87" +rust-version = "1.88" description = "Code generation for `cucumber` crate." license = "MIT OR Apache-2.0" authors = [ @@ -21,14 +21,14 @@ exclude = ["/tests/"] proc-macro = true [dependencies] -cucumber-expressions = { version = "0.4", features = ["into-regex"] } +cucumber-expressions = { version = "0.5", features = ["into-regex"] } inflections = "1.1" itertools = "0.14" proc-macro2 = "1.0.28" quote = "1.0.9" regex = "1.5.5" syn = { version = "2.0", features = ["derive", "extra-traits", "full"] } -synthez = "0.3" +synthez = "0.4" [dev-dependencies] cucumber = { path = "..", features = ["libtest", "macros"] } diff --git a/codegen/README.md b/codegen/README.md index 8c5a255a..18c523cd 100644 --- a/codegen/README.md +++ b/codegen/README.md @@ -2,7 +2,7 @@ ======================== [![crates.io](https://img.shields.io/crates/v/cucumber-codegen.svg?maxAge=2592000 "crates.io")](https://crates.io/crates/cucumber-codegen) -[![Rust 1.87+](https://img.shields.io/badge/rustc-1.87+-lightgray.svg "Rust 1.87+")](https://blog.rust-lang.org/2025/05/15/Rust-1.87.0) +[![Rust 1.88+](https://img.shields.io/badge/rustc-1.88+-lightgray.svg "Rust 1.88+")](https://blog.rust-lang.org/2025/06/26/Rust-1.88.0) [![Unsafe Forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg "Unsafe forbidden")](https://github.com/rust-secure-code/safety-dance)\ [![CI](https://github.com/cucumber-rs/cucumber/actions/workflows/ci.yml/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain) [![Rust docs](https://docs.rs/cucumber-codegen/badge.svg "Rust docs")](https://docs.rs/cucumber-codegen) diff --git a/codegen/src/attribute.rs b/codegen/src/attribute.rs index 9395c564..d05922fa 100644 --- a/codegen/src/attribute.rs +++ b/codegen/src/attribute.rs @@ -84,10 +84,10 @@ impl Step { }? .or_else(|| { func.sig.inputs.iter().find_map(|arg| { - if let Ok((ident, _)) = parse_fn_arg(arg) { - if ident == "step" { - return Some(ident.clone()); - } + if let Ok((ident, _)) = parse_fn_arg(arg) + && ident == "step" + { + return Some(ident.clone()); } None }) @@ -793,10 +793,10 @@ fn remove_attr(attr_arg: &str, arg: &mut syn::FnArg) -> Option { let (mut other, mut removed): (Vec<_>, Vec<_>) = attrs.into_iter().partition_map(|attr| { - if let Some(ident) = attr.meta.path().get_ident() { - if ident == attr_arg { - return Either::Right(attr); - } + if let Some(ident) = attr.meta.path().get_ident() + && ident == attr_arg + { + return Either::Right(attr); } Either::Left(attr) }); diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index ce4504bf..27014d48 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -135,6 +135,7 @@ clippy::use_self, clippy::useless_let_if_seq, clippy::verbose_file_reads, + clippy::volatile_composites, clippy::while_float, clippy::wildcard_enum_match_arm, ambiguous_negative_literals, diff --git a/src/lib.rs b/src/lib.rs index 7f6bce42..f1b8bbbb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,6 +136,7 @@ clippy::use_self, clippy::useless_let_if_seq, clippy::verbose_file_reads, + clippy::volatile_composites, clippy::while_float, clippy::wildcard_enum_match_arm, ambiguous_negative_literals, diff --git a/src/runner/basic.rs b/src/runner/basic.rs index ab29c80e..70d3ff6d 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -1017,23 +1017,21 @@ async fn execute( select_with_biased_first(forward_logs, run_scenarios.next()) .await .factor_first(); - if finished_scenario.is_some() { - if let ControlFlow::Continue(Some(sc)) = &mut started_scenarios - { - *sc += 1; - } + if finished_scenario.is_some() + && let ControlFlow::Continue(Some(sc)) = &mut started_scenarios + { + *sc += 1; } } while let Ok(Some((id, feat, rule, scenario_failed, retried))) = storage.finished_receiver.try_next() { - if let Some(rule) = rule { - if let Some(f) = + if let Some(rule) = rule + && let Some(f) = storage.rule_scenario_finished(feat.clone(), rule, retried) - { - executor.send_event(f); - } + { + executor.send_event(f); } if let Some(f) = storage.feature_scenario_finished(feat, retried) { executor.send_event(f); diff --git a/src/tracing.rs b/src/tracing.rs index 647c8acd..b7c98f42 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -303,9 +303,7 @@ impl Collector { } } -// TODO: Try remove on next Rust version update. -#[expect(clippy::allow_attributes, reason = "`#[expect]` doesn't work here")] -#[allow( // intentional +#[expect( // related to `tracing` capabilities only clippy::multiple_inherent_impl, reason = "related to `tracing` capabilities only" )] diff --git a/src/writer/summarize.rs b/src/writer/summarize.rs index 27a5c18d..39f94564 100644 --- a/src/writer/summarize.rs +++ b/src/writer/summarize.rs @@ -539,9 +539,7 @@ pub trait Summarizable {} impl Summarizable for T {} -// TODO: Try remove on next Rust version update. -#[expect(clippy::allow_attributes, reason = "`#[expect]` doesn't work here")] -#[allow( // intentional +#[expect( // related to summarization only clippy::multiple_inherent_impl, reason = "related to summarization only" )] From d030f68bd0921a9f9e956aaf431d8c850f04aad0 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 12 Dec 2025 15:17:23 +0100 Subject: [PATCH 07/16] Omit building docs for dependencies of `cucumber` crate on CI --- .github/workflows/ci.yml | 4 ++++ Makefile | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1a516a0..a68f656a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -192,9 +192,13 @@ jobs: with: toolchain: nightly + # TODO: Use `deps=yes` always once new version of `anstyle-parse` crate + # is released. - run: make cargo.doc crate=${{ matrix.crate }} private=yes docsrs=yes open=no + deps=${{ (matrix.crate == 'cucumber' && 'no') + || 'yes' }} env: RUSTFLAGS: -D warnings diff --git a/Makefile b/Makefile index c4ba459b..f91605ce 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ test: test.cargo # # Usage: # make cargo.doc [crate=] -# [private=(yes|no)] [docsrs=(no|yes)] +# [private=(yes|no)] [deps=(yes|no)] [docsrs=(no|yes)] # [open=(yes|no)] [clean=(no|yes)] cargo.doc: @@ -55,6 +55,7 @@ endif $(if $(call eq,$(crate),),--workspace,-p $(crate)) \ --all-features \ $(if $(call eq,$(private),no),,--document-private-items) \ + $(if $(call eq,$(deps),no),--no-deps,) \ $(if $(call eq,$(open),no),,--open) From 23a0169b98bf7079184b1e3b5f8606f4a620337a Mon Sep 17 00:00:00 2001 From: Sergio Machado Date: Fri, 12 Dec 2025 10:11:16 -0500 Subject: [PATCH 08/16] Support `CUCUMBER_FILTER_TAGS` env var (#372) Co-authored-by: Kai Ren --- CHANGELOG.md | 8 +++++++- Cargo.toml | 3 ++- book/src/cli.md | 16 +++++++++------- book/src/writing/tags.md | 15 ++++++++------- codegen/CHANGELOG.md | 3 ++- src/cli.rs | 1 + tests/cli.rs | 32 +++++++++++++++++++++++++++++++- 7 files changed, 60 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c118f49..607baf3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ### BC Breaks -- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c], [todo]) +- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c], [a4cbd3d2]) - Replaced `Arc` with `PartialEq`/`Hash` pointer-optimized `Source` in `event`s: ([#352]) - `Source` in `event::Cucumber::Feature`. - `Source` in `event::Feature::Rule`. @@ -26,6 +26,10 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - `event::Scenario::background_step_started()`, `event::Scenario::background_step_passed()` and `event::Scenario::background_step_skipped()`. - Kept only currently executed row of `Examples` table in expanded `Scenario Outline`s. ([#371], [#369]) +### Added + +- `CUCUMBER_FILTER_TAGS` environment variable support. ([#372]) + ### Fixed - Performance degradation on large `.feature` files. ([#352], [#331]) @@ -34,9 +38,11 @@ All user visible changes to `cucumber` crate will be documented in this file. Th [#352]: /../../pull/352 [#369]: /../../issues/369 [#371]: /../../pull/371 +[#372]: /../../pull/372 [0c7dfc3c]: /../../commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed [4010c1ad]: /../../commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f [9705253b]: /../../commit/9705253bda5caadfe3eea91f50420222158dd944 +[a4cbd3d2]: /../../commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 [b46930c3]: /../../commit/b46930c32ef5ae490df8063905144a45de27eda1 [f1307038]: /../../commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf diff --git a/Cargo.toml b/Cargo.toml index 6346679c..e713b358 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -64,7 +64,7 @@ timestamps = [] tracing = ["dep:crossbeam-utils", "dep:tracing", "dep:tracing-subscriber"] [dependencies] -clap = { version = "4.3.2", features = ["derive", "wrap_help"] } +clap = { version = "4.3.2", features = ["derive", "env", "wrap_help"] } console = "0.16" derive_more = { version = "2.0", features = ["as_ref", "debug", "deref", "deref_mut", "display", "error", "from", "from_str", "into"] } either = "1.6" @@ -104,6 +104,7 @@ tracing-subscriber = { version = "0.3.16", optional = true } [dev-dependencies] rand = "0.9" +serial_test = "3.0" tempfile = "3.2" tokio = { version = "1.40", features = ["macros", "rt-multi-thread", "sync", "time"] } diff --git a/book/src/cli.md b/book/src/cli.md index cd949a88..38be11d5 100644 --- a/book/src/cli.md +++ b/book/src/cli.md @@ -17,14 +17,16 @@ Usage: cucumber [OPTIONS] Options: -n, --name Regex to filter scenarios by their name - + [aliases: scenario-name] -t, --tags Tag expression to filter scenarios by. - + Note: Tags from Feature, Rule and Scenario are merged together on filtering, so be careful about conflicting tags on different levels. + [env: CUCUMBER_FILTER_TAGS=] + -i, --input Glob pattern to look for feature files with. If not specified, looks for `*.feature` files in the path configured in the test runner @@ -33,7 +35,7 @@ Options: --fail-fast Run tests until the first failure - + [aliases: ff] --retry @@ -41,7 +43,7 @@ Options: --retry-after Delay between each scenario retry attempt. - + Duration is represented in a human-readable format like `12min5s`. Supported suffixes: - `nsec`, `ns` — nanoseconds. @@ -55,12 +57,12 @@ Options: -v... Verbosity of an output. - + `-v` is default verbosity, `-vv` additionally outputs world on failed steps, `-vvv` additionally outputs step's doc string (if present). --color Coloring policy for a console output - + [default: auto] -h, --help @@ -235,7 +237,7 @@ struct Smoke { #[tokio::main] async fn main() { let opts = cli::Opts::<_, _, _, CustomOpts>::parsed(); - + let pre_pause = if let Some(SubCommand::Smoke(Smoke { pre_pause })) = opts.custom.command { diff --git a/book/src/writing/tags.md b/book/src/writing/tags.md index 662f9484..498879ff 100644 --- a/book/src/writing/tags.md +++ b/book/src/writing/tags.md @@ -31,7 +31,8 @@ Feature: Animal feature ``` To filter out running [scenario]s we may use: -- either `--tags` [CLI] option providing [tag expressions] (also consider [escaping]); +- either `--tags` [CLI] option providing [tag expressions] (also consider [escaping]). +- or `CUCUMBER_FILTER_TAGS` environment variable containing [tag expressions] (also consider [escaping]). - or [`filter_run()`]-like method. ![record](../rec/writing_tags_filtering.gif) @@ -65,13 +66,13 @@ Feature: Animal feature Then the is not hungry @home - Examples: + Examples: | animal | n | | cat | 2 | | dog | 3 | @dire - Examples: + Examples: | animal | n | | lion | 1 | | wolf | 1 | @@ -90,7 +91,7 @@ Feature: Animal feature ```gherkin Feature: Animal feature - + Scenario: If we feed a hungry cat it will no longer be hungry Given a hungry cat When I feed the cat @@ -120,7 +121,7 @@ Using [`Cucumber::fail_on_skipped()`] method fails the whole test suite if some ```gherkin Feature: Animal feature - + Scenario: If we feed a hungry cat it will no longer be hungry Given a hungry cat When I feed the cat @@ -139,7 +140,7 @@ Feature: Animal feature # # use cucumber::{World, given, then, when}; # use tokio::time::sleep; -# +# # #[derive(Debug, Default)] # struct Animal { # pub hungry: bool, @@ -194,7 +195,7 @@ async fn main() { ```gherkin Feature: Animal feature - + Scenario: If we feed a hungry cat it will no longer be hungry Given a hungry cat When I feed the cat diff --git a/codegen/CHANGELOG.md b/codegen/CHANGELOG.md index e697a8a1..d7cf3320 100644 --- a/codegen/CHANGELOG.md +++ b/codegen/CHANGELOG.md @@ -13,11 +13,12 @@ All user visible changes to `cucumber-codegen` crate will be documented in this ### BC Breaks -- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c]) +- Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c], [a4cbd3d2]) [0c7dfc3c]: /../../commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed [4010c1ad]: /../../commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f [9705253b]: /../../commit/9705253bda5caadfe3eea91f50420222158dd944 +[a4cbd3d2]: /../../commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 [b46930c3]: /../../commit/b46930c32ef5ae490df8063905144a45de27eda1 [f1307038]: /../../commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf diff --git a/src/cli.rs b/src/cli.rs index a7c49db9..6e62cb31 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -111,6 +111,7 @@ where short = 't', value_name = "tagexpr", conflicts_with = "name", + env = "CUCUMBER_FILTER_TAGS", global = true )] pub tags_filter: Option, diff --git a/tests/cli.rs b/tests/cli.rs index 0bf10eb5..c760e136 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -1,8 +1,9 @@ -use std::panic::AssertUnwindSafe; +use std::{env, panic::AssertUnwindSafe}; use clap::Parser; use cucumber::{World as _, cli, given}; use futures::FutureExt as _; +use serial_test::{parallel, serial}; #[derive(cli::Args)] struct CustomCli { @@ -32,6 +33,7 @@ fn invalid_step(_world: &mut World) { // This test uses a subcommand with the global option `--tags` to filter on two // failing tests and verifies that the error output contains 2 failing steps. #[tokio::test] +#[parallel] async fn tags_option_filters_all_scenarios_with_subcommand() { let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ "test", @@ -54,6 +56,7 @@ async fn tags_option_filters_all_scenarios_with_subcommand() { // This test uses a subcommand with the global option `--tags` to filter on one // failing test and verifies that the error output contains 1 failing step. #[tokio::test] +#[parallel] async fn tags_option_filters_scenario1_with_subcommand() { let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ "test", @@ -76,6 +79,7 @@ async fn tags_option_filters_scenario1_with_subcommand() { // This test verifies that the global option `--tags` is still available without // subcommands and that the error output contains 1 failing step. #[tokio::test] +#[parallel] async fn tags_option_filters_scenario1_no_subcommand() { let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ "test", @@ -92,3 +96,29 @@ async fn tags_option_filters_scenario1_no_subcommand() { assert_eq!(err, "1 step failed"); } + +// This test verifies that the `CUCUMBER_FILTER_TAGS` env var filters apply and +// that the error output contains 1 failing step. +#[tokio::test] +#[serial] +async fn tags_option_filters_scenario1_via_env() { + unsafe { + env::set_var("CUCUMBER_FILTER_TAGS", "@scenario-1"); + } + + let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&["test"]) + .expect("Invalid command line"); + + let res = + World::cucumber().with_cli(cli).run_and_exit("tests/features/cli"); + + let err = + AssertUnwindSafe(res).catch_unwind().await.expect_err("should err"); + let err = err.downcast_ref::().unwrap(); + + assert_eq!(err, "1 step failed"); + + unsafe { + env::remove_var("CUCUMBER_FILTER_TAGS"); + } +} From d0213e7c6d63bf0172039508190d4788dea5c2fe Mon Sep 17 00:00:00 2001 From: Jonathan Parris Date: Fri, 12 Dec 2025 08:46:47 -0700 Subject: [PATCH 09/16] Document calling `.after()`/`.before()` hooks multiple times (#368, #366) Co-authored-by: Kai Ren --- book/src/writing/hooks.md | 6 ++++++ src/cucumber.rs | 8 ++++++++ src/runner/basic.rs | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/book/src/writing/hooks.md b/book/src/writing/hooks.md index 5e6f6944..a8ee1f38 100644 --- a/book/src/writing/hooks.md +++ b/book/src/writing/hooks.md @@ -35,6 +35,9 @@ World::cucumber() > __NOTE__: [`Before` hook] is enabled globally for all the executed [scenario]s. No exception is possible. +> __NOTE__: __Only one [`Before` hook] can be registered!__ +> If multiple `.before()` calls are made, only the last one will be run. + > __WARNING__: __Think twice before using [`Before` hook]!__ > Whatever happens in a [`Before` hook] is invisible to people reading `.feature`s. You should consider using a [`Background`] keyword as a more explicit alternative, especially if the setup should be readable by non-technical people. Only use a [`Before` hook] for low-level logic such as starting a browser or deleting data from a database. @@ -70,6 +73,9 @@ World::cucumber() > __NOTE__: [`After` hook] is enabled globally for all the executed [scenario]s. No exception is possible. +> __NOTE__: __Only one [`After` hook] can be registered!__ +> If multiple `.after()` calls are made, only the last one will be run. + > __TIP__: [`After` hook] receives an [`event::ScenarioFinished`] as one of its arguments, which indicates why the [scenario] has finished (passed, failed or skipped). This information, for example, may be used to decide whether some external resources (like files) should be cleaned up if the [scenario] passes, or leaved "as is" if it fails, so helping to "freeze" the failure conditions for better investigation. diff --git a/src/cucumber.rs b/src/cucumber.rs index 462f43de..090853ee 100644 --- a/src/cucumber.rs +++ b/src/cucumber.rs @@ -1015,6 +1015,10 @@ where /// Sets a hook, executed on each [`Scenario`] before running all its /// [`Step`]s, including [`Background`] ones. /// + /// > **NOTE**: Only one [`before`] hook can be registered. If multiple + /// > calls are made, only the last one will be run. + /// + /// [`before`]: Self::before() /// [`Background`]: gherkin::Background /// [`Scenario`]: gherkin::Scenario /// [`Step`]: gherkin::Step @@ -1046,9 +1050,13 @@ where /// Sets a hook, executed on each [`Scenario`] after running all its /// [`Step`]s, even after [`Skipped`] of [`Failed`] [`Step`]s. /// + /// > **NOTE**: Only one [`after`] hook can be registered. If multiple + /// > calls are made, only the last one will be run. + /// /// Last `World` argument is supplied to the function, in case it was /// initialized before by running [`before`] hook or any [`Step`]. /// + /// [`after`]: Self::after() /// [`before`]: Self::before() /// [`Failed`]: event::Step::Failed /// [`Scenario`]: gherkin::Scenario diff --git a/src/runner/basic.rs b/src/runner/basic.rs index 70d3ff6d..d2c879a9 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -576,6 +576,11 @@ impl Basic { /// Sets a hook, executed on each [`Scenario`] before running all its /// [`Step`]s, including [`Background`] ones. /// + /// > **NOTE**: Only one [`before`] hook can be registered. If + /// > multiple calls are made, only the last one will be + /// > run. + /// + /// [`before`]: Self::before() /// [`Background`]: gherkin::Background /// [`Scenario`]: gherkin::Scenario /// [`Step`]: gherkin::Step @@ -622,9 +627,14 @@ impl Basic { /// Sets hook, executed on each [`Scenario`] after running all its /// [`Step`]s, even after [`Skipped`] of [`Failed`] ones. /// + /// > **NOTE**: Only one [`after`] hook can be registered. If + /// > multiple calls are made, only the last one will be + /// > run. + /// /// Last `World` argument is supplied to the function, in case it was /// initialized before by running [`before`] hook or any [`Step`]. /// + /// [`after`]: Self::after() /// [`before`]: Self::before() /// [`Failed`]: event::Step::Failed /// [`Scenario`]: gherkin::Scenario From 81acba84697a5b04c45e2c5d5446f1ffbe289632 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 12 Dec 2025 16:59:02 +0100 Subject: [PATCH 10/16] Consider `clippy::trivial_regex` lint in macro expansion (#384) --- codegen/src/attribute.rs | 4 ++++ tests/cli.rs | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/codegen/src/attribute.rs b/codegen/src/attribute.rs index d05922fa..43dfac7f 100644 --- a/codegen/src/attribute.rs +++ b/codegen/src/attribute.rs @@ -112,6 +112,9 @@ impl Step { self.fn_arguments_and_additional_parsing()?; let regex = self.gen_regex()?; + let allow_trivial_regex_attr = + matches!(self.attr_arg, AttributeArgument::Literal(_)) + .then(|| quote! { #[allow(clippy::trivial_regex)] }); let awaiting = func.sig.asyncness.map(|_| quote! { .await }); let unwrapping = (!self.returns_unit()) @@ -135,6 +138,7 @@ impl Step { column: ::std::column!(), }, regex: || { + #allow_trivial_regex_attr static LAZY: ::std::sync::LazyLock< ::cucumber::codegen::Regex > = ::std::sync::LazyLock::new(|| { #regex }); diff --git a/tests/cli.rs b/tests/cli.rs index c760e136..d4e7433c 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -35,7 +35,7 @@ fn invalid_step(_world: &mut World) { #[tokio::test] #[parallel] async fn tags_option_filters_all_scenarios_with_subcommand() { - let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ + let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from([ "test", "smoke", r#"--report-name="smoke.report""#, @@ -58,7 +58,7 @@ async fn tags_option_filters_all_scenarios_with_subcommand() { #[tokio::test] #[parallel] async fn tags_option_filters_scenario1_with_subcommand() { - let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ + let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from([ "test", "smoke", r#"--report-name="smoke.report""#, @@ -81,7 +81,7 @@ async fn tags_option_filters_scenario1_with_subcommand() { #[tokio::test] #[parallel] async fn tags_option_filters_scenario1_no_subcommand() { - let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&[ + let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from([ "test", "--tags=@scenario-1", ]) @@ -106,7 +106,7 @@ async fn tags_option_filters_scenario1_via_env() { env::set_var("CUCUMBER_FILTER_TAGS", "@scenario-1"); } - let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(&["test"]) + let cli = cli::Opts::<_, _, _, CustomCli>::try_parse_from(["test"]) .expect("Invalid command line"); let res = From 525800822c528169f42fe17486ca97f792e431a6 Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 12 Dec 2025 17:15:44 +0100 Subject: [PATCH 11/16] Prepare 0.22.0 release --- CHANGELOG.md | 375 ++++++++++++++++++------------------ Cargo.toml | 4 +- README.md | 6 +- book/src/output/intellij.md | 2 +- book/src/output/json.md | 2 +- book/src/output/junit.md | 2 +- book/src/quickstart.md | 20 +- codegen/CHANGELOG.md | 172 +++++++++-------- codegen/Cargo.toml | 2 +- codegen/README.md | 6 +- 10 files changed, 300 insertions(+), 291 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607baf3e..85e04fe5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,10 @@ All user visible changes to `cucumber` crate will be documented in this file. Th -## [0.22.0] · 2024-??-?? (unreleased) -[0.22.0]: /../../tree/v0.22.0 +## [0.22.0] · 2025-12-12 +[0.22.0]: https://github.com/cucumber-rs/cucumber/tree/v0.22.0 -[Diff](/../../compare/v0.21.1...v0.22.0) | [Milestone](/../../milestone/28) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.21.1...v0.22.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/28) ### BC Breaks @@ -33,40 +33,43 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ### Fixed - Performance degradation on large `.feature` files. ([#352], [#331]) +- `clippy::trivial_regex` lint triggering on `#[given]`/`#[when]`/`#[then]` steps without regular expression. ([81acba84], [#384]) -[#331]: /../../issues/331 -[#352]: /../../pull/352 -[#369]: /../../issues/369 -[#371]: /../../pull/371 -[#372]: /../../pull/372 -[0c7dfc3c]: /../../commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed -[4010c1ad]: /../../commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f -[9705253b]: /../../commit/9705253bda5caadfe3eea91f50420222158dd944 -[a4cbd3d2]: /../../commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 -[b46930c3]: /../../commit/b46930c32ef5ae490df8063905144a45de27eda1 -[f1307038]: /../../commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf +[#331]: https://github.com/cucumber-rs/cucumber/issues/331 +[#352]: https://github.com/cucumber-rs/cucumber/pull/352 +[#369]: https://github.com/cucumber-rs/cucumber/issues/369 +[#371]: https://github.com/cucumber-rs/cucumber/pull/371 +[#372]: https://github.com/cucumber-rs/cucumber/pull/372 +[#384]: https://github.com/cucumber-rs/cucumber/issues/384 +[0c7dfc3c]: https://github.com/cucumber-rs/cucumber/commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed +[4010c1ad]: https://github.com/cucumber-rs/cucumber/commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f +[81acba84]: https://github.com/cucumber-rs/cucumber/commit/81acba84697a5b04c45e2c5d5446f1ffbe289632 +[9705253b]: https://github.com/cucumber-rs/cucumber/commit/9705253bda5caadfe3eea91f50420222158dd944 +[a4cbd3d2]: https://github.com/cucumber-rs/cucumber/commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 +[b46930c3]: https://github.com/cucumber-rs/cucumber/commit/b46930c32ef5ae490df8063905144a45de27eda1 +[f1307038]: https://github.com/cucumber-rs/cucumber/commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf ## [0.21.1] · 2024-06-16 -[0.21.1]: /../../tree/v0.21.1 +[0.21.1]: https://github.com/cucumber-rs/cucumber/tree/v0.21.1 -[Diff](/../../compare/v0.21.0...v0.21.1) | [Milestone](/../../milestone/29) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.21.0...v0.21.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/29) ### Fixed - Wrong case of statuses reported in `writer::Json`. ([#335]) -[#335]: /../../pull/335 +[#335]: https://github.com/cucumber-rs/cucumber/pull/335 ## [0.21.0] · 2024-04-22 -[0.21.0]: /../../tree/v0.21.0 +[0.21.0]: https://github.com/cucumber-rs/cucumber/tree/v0.21.0 -[Diff](/../../compare/v0.20.2...v0.21.0) | [Milestone](/../../milestone/26) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.20.2...v0.21.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/26) ### BC Breaks @@ -77,49 +80,49 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Possible truncation of long output messages. ([#333], [#332]) -[#324]: /../../pull/324 -[#332]: /../../issues/332 -[#333]: /../../pull/333 +[#324]: https://github.com/cucumber-rs/cucumber/pull/324 +[#332]: https://github.com/cucumber-rs/cucumber/issues/332 +[#333]: https://github.com/cucumber-rs/cucumber/pull/333 ## [0.20.2] · 2023-12-04 -[0.20.2]: /../../tree/v0.20.2 +[0.20.2]: https://github.com/cucumber-rs/cucumber/tree/v0.20.2 -[Diff](/../../compare/v0.20.1...v0.20.2) | [Milestone](/../../milestone/27) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.20.1...v0.20.2) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/27) ### Fixed - Ignored verbosity when printing `World` on hook/background step failure. ([#313]) -[#313]: /../../pull/313 +[#313]: https://github.com/cucumber-rs/cucumber/pull/313 ## [0.20.1] · 2023-10-16 -[0.20.1]: /../../tree/v0.20.1 +[0.20.1]: https://github.com/cucumber-rs/cucumber/tree/v0.20.1 -[Diff](/../../compare/v0.20.0...v0.20.1) | [Milestone](/../../milestone/25) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.20.0...v0.20.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/25) ### Fixed - Incorrect terminal width detection when its height is low. ([#298]) - Incorrect terminal lines clearing in interactive mode. ([#300], [#302], [#299]) -[#298]: /../../pull/298 -[#299]: /../../issues/299 -[#300]: /../../pull/300 -[#302]: /../../pull/302 +[#298]: https://github.com/cucumber-rs/cucumber/pull/298 +[#299]: https://github.com/cucumber-rs/cucumber/issues/299 +[#300]: https://github.com/cucumber-rs/cucumber/pull/300 +[#302]: https://github.com/cucumber-rs/cucumber/pull/302 ## [0.20.0] · 2023-07-10 -[0.20.0]: /../../tree/v0.20.0 +[0.20.0]: https://github.com/cucumber-rs/cucumber/tree/v0.20.0 -[Diff](/../../compare/v0.19.1...v0.20.0) | [Milestone](/../../milestone/24) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.19.1...v0.20.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/24) ### BC Breaks @@ -137,36 +140,36 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Clearing lines that are wrapped because of terminal width. ([#272], [#273]) -[#213]: /../../issues/213 -[#258]: /../../pull/258 -[#261]: /../../pull/261 -[#264]: /../../issues/264 -[#265]: /../../pull/265 -[#272]: /../../discussions/272 -[#273]: /../../pull/273 -[#288]: /../../pull/288 +[#213]: https://github.com/cucumber-rs/cucumber/issues/213 +[#258]: https://github.com/cucumber-rs/cucumber/pull/258 +[#261]: https://github.com/cucumber-rs/cucumber/pull/261 +[#264]: https://github.com/cucumber-rs/cucumber/issues/264 +[#265]: https://github.com/cucumber-rs/cucumber/pull/265 +[#272]: https://github.com/cucumber-rs/cucumber/discussions/272 +[#273]: https://github.com/cucumber-rs/cucumber/pull/273 +[#288]: https://github.com/cucumber-rs/cucumber/pull/288 ## [0.19.1] · 2022-12-29 -[0.19.1]: /../../tree/v0.19.1 +[0.19.1]: https://github.com/cucumber-rs/cucumber/tree/v0.19.1 -[Diff](/../../compare/v0.19.0...v0.19.1) | [Milestone](/../../milestone/23) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.19.0...v0.19.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/23) ### Fixed - Using autodetect for colors on `color=always|never` CLI options. ([#253]) -[#253]: /../../pull/253 +[#253]: https://github.com/cucumber-rs/cucumber/pull/253 ## [0.19.0] · 2022-12-16 -[0.19.0]: /../../tree/v0.19.0 +[0.19.0]: https://github.com/cucumber-rs/cucumber/tree/v0.19.0 -[Diff](/../../compare/v0.18.0...v0.19.0) | [Milestone](/../../milestone/22) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.18.0...v0.19.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/22) ### BC Breaks @@ -190,17 +193,17 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - `@serial` `Scenario`s continue running after failure when `--fail-fast()` CLI option is specified. ([#252]) -[#251]: /../../pull/251 -[#252]: /../../pull/252 -[56456e66]: /../../commit/56456e666be41b4190f62fecaf727042ed69c15a +[#251]: https://github.com/cucumber-rs/cucumber/pull/251 +[#252]: https://github.com/cucumber-rs/cucumber/pull/252 +[56456e66]: https://github.com/cucumber-rs/cucumber/commit/56456e666be41b4190f62fecaf727042ed69c15a ## [0.18.0] · 2022-12-07 -[0.18.0]: /../../tree/v0.18.0 +[0.18.0]: https://github.com/cucumber-rs/cucumber/tree/v0.18.0 -[Diff](/../../compare/v0.17.0...v0.18.0) | [Milestone](/../../milestone/21) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.17.0...v0.18.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/21) ### BC Breaks @@ -210,16 +213,16 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Not panicking on `fail_on_skipped()` with retries. ([#250], [#249]) -[#249]: /../../issues/249 -[#250]: /../../pull/250 +[#249]: https://github.com/cucumber-rs/cucumber/issues/249 +[#250]: https://github.com/cucumber-rs/cucumber/pull/250 ## [0.17.0] · 2022-11-23 -[0.17.0]: /../../tree/v0.17.0 +[0.17.0]: https://github.com/cucumber-rs/cucumber/tree/v0.17.0 -[Diff](/../../compare/v0.16.0...v0.17.0) | [Milestone](/../../milestone/20) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.16.0...v0.17.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/20) ### BC Breaks @@ -229,17 +232,17 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Uncaught panics of user code, when they happen before first poll of the returned `Future`s. ([#246]) -[#245]: /../../discussions/245 -[#246]: /../../pull/246 +[#245]: https://github.com/cucumber-rs/cucumber/discussions/245 +[#246]: https://github.com/cucumber-rs/cucumber/pull/246 [0170-1]: https://docs.rs/cucumber/0.17.0/cucumber/struct.Cucumber.html#method.after ## [0.16.0] · 2022-11-09 -[0.16.0]: /../../tree/v0.16.0 +[0.16.0]: https://github.com/cucumber-rs/cucumber/tree/v0.16.0 -[Diff](/../../compare/v0.15.3...v0.16.0) | [Milestone](/../../milestone/19) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.15.3...v0.16.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/19) ### BC Breaks @@ -253,31 +256,31 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - `--fail-fast` CLI option causing execution to hang. ([#242], [#241]) -[#241]: /../../issues/241 -[#242]: /../../pull/242 -[7f52d4a5]: /../../commit/7f52d4a5faa3b69bec6c7fb765b50455cf7802aa +[#241]: https://github.com/cucumber-rs/cucumber/issues/241 +[#242]: https://github.com/cucumber-rs/cucumber/pull/242 +[7f52d4a5]: https://github.com/cucumber-rs/cucumber/commit/7f52d4a5faa3b69bec6c7fb765b50455cf7802aa ## [0.15.3] · 2022-11-01 -[0.15.3]: /../../tree/v0.15.3 +[0.15.3]: https://github.com/cucumber-rs/cucumber/tree/v0.15.3 -[Diff](/../../compare/v0.15.2...v0.15.3) | [Milestone](/../../milestone/18) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.15.2...v0.15.3) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/18) ### Added - `Clone` implementations to all public types where possible. ([#238]) -[#238]: /../../pull/238 +[#238]: https://github.com/cucumber-rs/cucumber/pull/238 ## [0.15.2] · 2022-10-25 -[0.15.2]: /../../tree/v0.15.2 +[0.15.2]: https://github.com/cucumber-rs/cucumber/tree/v0.15.2 -[Diff](/../../compare/v0.15.1...v0.15.2) | [Milestone](/../../milestone/17) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.15.1...v0.15.2) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/17) ### Changed @@ -288,8 +291,8 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Parsing error on a `Feature` having comment and tag simultaneously. ([4cad49f8], [cucumber-rs/gherkin#37], [cucumber-rs/gherkin#35]) - `@retry`, `@serial` and `@allow.skipped` tags semantics inheritance. ([#237]) -[#237]: /../../pull/237 -[4cad49f8]: /../../commit/4cad49f8d8f5d0458dcb538aa044a5fff1e6fa10 +[#237]: https://github.com/cucumber-rs/cucumber/pull/237 +[4cad49f8]: https://github.com/cucumber-rs/cucumber/commit/4cad49f8d8f5d0458dcb538aa044a5fff1e6fa10 [cucumber-rs/gherkin#35]: https://github.com/cucumber-rs/gherkin/issues/35 [cucumber-rs/gherkin#37]: https://github.com/cucumber-rs/gherkin/pull/37 @@ -297,53 +300,53 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.15.1] · 2022-10-12 -[0.15.1]: /../../tree/v0.15.1 +[0.15.1]: https://github.com/cucumber-rs/cucumber/tree/v0.15.1 -[Diff](/../../compare/v0.15.0...v0.15.1) | [Milestone](/../../milestone/16) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.15.0...v0.15.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/16) ### Fixed - Conflicting [`Id`][0151-1]s of CLI options. ([#232], [#231]) -[#231]: /../../issues/231 -[#232]: /../../pull/232 +[#231]: https://github.com/cucumber-rs/cucumber/issues/231 +[#232]: https://github.com/cucumber-rs/cucumber/pull/232 [0151-1]: https://docs.rs/clap/latest/clap/struct.Id.html ## [0.15.0] · 2022-10-05 -[0.15.0]: /../../tree/v0.15.0 +[0.15.0]: https://github.com/cucumber-rs/cucumber/tree/v0.15.0 -[Diff](/../../compare/v0.14.2...v0.15.0) | [Milestone](/../../milestone/15) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.14.2...v0.15.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/15) ### BC Breaks - Upgraded [`clap`] crate to 4.0 version. ([#230]) -[#230]: /../../pull/230 +[#230]: https://github.com/cucumber-rs/cucumber/pull/230 ## [0.14.2] · 2022-09-19 -[0.14.2]: /../../tree/v0.14.2 +[0.14.2]: https://github.com/cucumber-rs/cucumber/tree/v0.14.2 -[Diff](/../../compare/v0.14.1...v0.14.2) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.14.1...v0.14.2) ### Fixed - `#[derive(World)]` macro being unhygienic regarding custom `Result` types. ([186af8b1]) -[186af8b1]: /../../commit/186af8b1de37275b308897e2e30d6982830b0278 +[186af8b1]: https://github.com/cucumber-rs/cucumber/commit/186af8b1de37275b308897e2e30d6982830b0278 ## [0.14.1] · 2022-09-12 -[0.14.1]: /../../tree/v0.14.1 +[0.14.1]: https://github.com/cucumber-rs/cucumber/tree/v0.14.1 -[Diff](/../../compare/v0.14.0...v0.14.1) | [Milestone](/../../milestone/14) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.14.0...v0.14.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/14) ### Changed @@ -357,18 +360,18 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - `junit-report` crate to 0.8 version to fix [RUSTSEC-2022-0048]. ([#229], [#226]) -[#226]: /../../issues/226 -[#229]: /../../pull/229 -[ad0bb22f]: /../../commit/ad0bb22f9234099985cb1966f92ccefbc97060fb +[#226]: https://github.com/cucumber-rs/cucumber/issues/226 +[#229]: https://github.com/cucumber-rs/cucumber/pull/229 +[ad0bb22f]: https://github.com/cucumber-rs/cucumber/commit/ad0bb22f9234099985cb1966f92ccefbc97060fb [RUSTSEC-2022-0048]: https://rustsec.org/advisories/RUSTSEC-2022-0048.html ## [0.14.0] · 2022-09-08 -[0.14.0]: /../../tree/v0.14.0 +[0.14.0]: https://github.com/cucumber-rs/cucumber/tree/v0.14.0 -[Diff](/../../compare/v0.13.0...v0.14.0) | [Milestone](/../../milestone/13) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.13.0...v0.14.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/13) ### BC Breaks @@ -397,56 +400,56 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Provided default CLI options are now global (allowed to be specified after custom subcommands). ([#216], [#215]) - Stripped `CARGO_MANIFEST_DIR` from output paths whenever is possible. ([#221]) -[#212]: /../../issues/212 -[#215]: /../../issues/215 -[#216]: /../../pull/216 -[#217]: /../../issues/217 -[#219]: /../../pull/219 -[#220]: /../../pull/220 -[#221]: /../../pull/221 -[#223]: /../../pull/223 -[8ad5cc86]: /../../commit/8ad5cc866bb9d6b49470790e3b0dd40690f63a09 -[cf055ac0]: /../../commit/cf055ac06c7b72f572882ce15d6a60da92ad60a0 -[fbd08ec2]: /../../commit/fbd08ec24dbd036c89f5f0af4d936b616790a166 +[#212]: https://github.com/cucumber-rs/cucumber/issues/212 +[#215]: https://github.com/cucumber-rs/cucumber/issues/215 +[#216]: https://github.com/cucumber-rs/cucumber/pull/216 +[#217]: https://github.com/cucumber-rs/cucumber/issues/217 +[#219]: https://github.com/cucumber-rs/cucumber/pull/219 +[#220]: https://github.com/cucumber-rs/cucumber/pull/220 +[#221]: https://github.com/cucumber-rs/cucumber/pull/221 +[#223]: https://github.com/cucumber-rs/cucumber/pull/223 +[8ad5cc86]: https://github.com/cucumber-rs/cucumber/commit/8ad5cc866bb9d6b49470790e3b0dd40690f63a09 +[cf055ac0]: https://github.com/cucumber-rs/cucumber/commit/cf055ac06c7b72f572882ce15d6a60da92ad60a0 +[fbd08ec2]: https://github.com/cucumber-rs/cucumber/commit/fbd08ec24dbd036c89f5f0af4d936b616790a166 [0140-1]: book/src/output/intellij.md ## [0.13.0] · 2022-03-29 -[0.13.0]: /../../tree/v0.13.0 +[0.13.0]: https://github.com/cucumber-rs/cucumber/tree/v0.13.0 -[Diff](/../../compare/v0.12.2...v0.13.0) | [Milestone](/../../milestone/12) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.12.2...v0.13.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/12) ### BC Breaks - Upgraded [`gherkin`] crate to 0.12 version. ([#211]) -[#211]: /../../pull/211 +[#211]: https://github.com/cucumber-rs/cucumber/pull/211 ## [0.12.2] · 2022-03-28 -[0.12.2]: /../../tree/v0.12.2 +[0.12.2]: https://github.com/cucumber-rs/cucumber/tree/v0.12.2 -[Diff](/../../compare/v0.12.1...v0.12.2) | [Milestone](/../../milestone/10) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.12.1...v0.12.2) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/10) ### Changed - [`Cucumber::after`][0122-1] now gets the `World` instance even if some `Step` or a `Hook` before it has failed. ([#209], [#207]) -[#207]: /../../issues/207 -[#209]: /../../pull/209 +[#207]: https://github.com/cucumber-rs/cucumber/issues/207 +[#209]: https://github.com/cucumber-rs/cucumber/pull/209 [0122-1]: https://docs.rs/cucumber/0.12.2/cucumber/struct.Cucumber.html#method.after ## [0.12.1] · 2022-03-09 -[0.12.1]: /../../tree/v0.12.1 +[0.12.1]: https://github.com/cucumber-rs/cucumber/tree/v0.12.1 -[Diff](/../../compare/v0.12.0...v0.12.1) | [Milestone](/../../milestone/11) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.12.0...v0.12.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/11) ### Security updated @@ -458,9 +461,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.12.0] · 2022-02-10 -[0.12.0]: /../../tree/v0.12.0 +[0.12.0]: https://github.com/cucumber-rs/cucumber/tree/v0.12.0 -[Diff](/../../compare/v0.11.3...v0.12.0) | [Milestone](/../../milestone/9) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.11.3...v0.12.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/9) ### BC Breaks @@ -475,47 +478,47 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Book examples failing on Windows. ([#202], [#200]) - `{string}` parameter in [Cucumber Expressions] returning its enclosing quotes. ([cucumber-rs/cucumber-expressions#7]) -[#200]: /../../issues/200 -[#202]: /../../pull/202 -[#204]: /../../pull/204 +[#200]: https://github.com/cucumber-rs/cucumber/issues/200 +[#202]: https://github.com/cucumber-rs/cucumber/pull/202 +[#204]: https://github.com/cucumber-rs/cucumber/pull/204 [cucumber-rs/cucumber-expressions#7]: https://github.com/cucumber-rs/cucumber-expressions/issues/7 ## [0.11.3] · 2022-01-31 -[0.11.3]: /../../tree/v0.11.3 +[0.11.3]: https://github.com/cucumber-rs/cucumber/tree/v0.11.3 -[Diff](/../../compare/v0.11.2...v0.11.3) | [Milestone](/../../milestone/8) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.11.2...v0.11.3) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/8) ### Fixed - `parser::Basic` skipping files named `.feature`. ([#201]) -[#201]: /../../pull/201 +[#201]: https://github.com/cucumber-rs/cucumber/pull/201 ## [0.11.2] · 2022-01-19 -[0.11.2]: /../../tree/v0.11.2 +[0.11.2]: https://github.com/cucumber-rs/cucumber/tree/v0.11.2 -[Diff](/../../compare/v0.11.1...v0.11.2) | [Milestone](/../../milestone/7) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.11.1...v0.11.2) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/7) ### Fixed - Skipped `Background` steps not failing in `writer::FailOnSkipped`. ([#199], [#198]) -[#198]: /../../issues/198 -[#199]: /../../pull/199 +[#198]: https://github.com/cucumber-rs/cucumber/issues/198 +[#199]: https://github.com/cucumber-rs/cucumber/pull/199 ## [0.11.1] · 2022-01-07 -[0.11.1]: /../../tree/v0.11.1 +[0.11.1]: https://github.com/cucumber-rs/cucumber/tree/v0.11.1 -[Diff](/../../compare/v0.11.0...v0.11.1) | [Milestone](/../../milestone/6) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.11.0...v0.11.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/6) ### Added @@ -525,16 +528,16 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Optimized `runner::Basic` to not wait the whole batch to complete before executing next `Scenario`s. ([#195]) -[#195]: /../../pull/195 -[#196]: /../../pull/196 +[#195]: https://github.com/cucumber-rs/cucumber/pull/195 +[#196]: https://github.com/cucumber-rs/cucumber/pull/196 ## [0.11.0] · 2022-01-03 -[0.11.0]: /../../tree/v0.11.0 +[0.11.0]: https://github.com/cucumber-rs/cucumber/tree/v0.11.0 -[Diff](/../../compare/v0.10.2...v0.11.0) | [Milestone](/../../milestone/3) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.10.2...v0.11.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/3) ### BC Breaks @@ -576,29 +579,29 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Docstring and name expansion in `Scenario Outline`. ([#178], [#172]) - `writer::Summarized` ignoring `Coloring` options. ([#189], [#186]) -[#147]: /../../pull/147 -[#151]: /../../pull/151 -[#155]: /../../issues/155 -[#157]: /../../pull/157 -[#159]: /../../pull/159 -[#160]: /../../pull/160 -[#162]: /../../pull/162 -[#163]: /../../pull/163 -[#164]: /../../issues/164 -[#165]: /../../pull/165 -[#166]: /../../pull/166 -[#168]: /../../pull/168 -[#172]: /../../issues/172 -[#178]: /../../pull/178 -[#181]: /../../pull/181 -[#182]: /../../pull/182 -[#186]: /../../issues/186 -[#188]: /../../pull/188 -[#189]: /../../pull/189 -[#192]: /../../issues/192 -[#193]: /../../pull/193 -[cef3d480]: /../../commit/cef3d480579190425461ddb04a1248675248351e -[e2a41ab0]: /../../commit/e2a41ab0a4398fe26075f0b066cc67e6e8a19e6c +[#147]: https://github.com/cucumber-rs/cucumber/pull/147 +[#151]: https://github.com/cucumber-rs/cucumber/pull/151 +[#155]: https://github.com/cucumber-rs/cucumber/issues/155 +[#157]: https://github.com/cucumber-rs/cucumber/pull/157 +[#159]: https://github.com/cucumber-rs/cucumber/pull/159 +[#160]: https://github.com/cucumber-rs/cucumber/pull/160 +[#162]: https://github.com/cucumber-rs/cucumber/pull/162 +[#163]: https://github.com/cucumber-rs/cucumber/pull/163 +[#164]: https://github.com/cucumber-rs/cucumber/issues/164 +[#165]: https://github.com/cucumber-rs/cucumber/pull/165 +[#166]: https://github.com/cucumber-rs/cucumber/pull/166 +[#168]: https://github.com/cucumber-rs/cucumber/pull/168 +[#172]: https://github.com/cucumber-rs/cucumber/issues/172 +[#178]: https://github.com/cucumber-rs/cucumber/pull/178 +[#181]: https://github.com/cucumber-rs/cucumber/pull/181 +[#182]: https://github.com/cucumber-rs/cucumber/pull/182 +[#186]: https://github.com/cucumber-rs/cucumber/issues/186 +[#188]: https://github.com/cucumber-rs/cucumber/pull/188 +[#189]: https://github.com/cucumber-rs/cucumber/pull/189 +[#192]: https://github.com/cucumber-rs/cucumber/issues/192 +[#193]: https://github.com/cucumber-rs/cucumber/pull/193 +[cef3d480]: https://github.com/cucumber-rs/cucumber/commit/cef3d480579190425461ddb04a1248675248351e +[e2a41ab0]: https://github.com/cucumber-rs/cucumber/commit/e2a41ab0a4398fe26075f0b066cc67e6e8a19e6c [0110-1]: https://llg.cubic.org/docs/junit [0110-2]: https://github.com/cucumber/cucumber-json-schema @@ -606,37 +609,37 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.10.2] · 2021-11-03 -[0.10.2]: /../../tree/v0.10.2 +[0.10.2]: https://github.com/cucumber-rs/cucumber/tree/v0.10.2 -[Diff](/../../compare/v0.10.1...v0.10.2) | [Milestone](/../../milestone/5) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.10.1...v0.10.2) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/5) ### Fixed - Multiple `WorldInit` derivers conflicting implementations in a single module. ([#150]) -[#150]: /../../pull/150 +[#150]: https://github.com/cucumber-rs/cucumber/pull/150 ## [0.10.1] · 2021-10-29 -[0.10.1]: /../../tree/v0.10.1 +[0.10.1]: https://github.com/cucumber-rs/cucumber/tree/v0.10.1 -[Diff](/../../compare/v0.10.0...v0.10.1) | [Milestone](/../../milestone/4) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.10.0...v0.10.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/4) ### Fixed - Console output hanging because of executing wrong `Concurrent` `Scenario`s. ([#146]) -[#146]: /../../pull/146 +[#146]: https://github.com/cucumber-rs/cucumber/pull/146 ## [0.10.0] · 2021-10-26 -[0.10.0]: /../../tree/v0.10.0 +[0.10.0]: https://github.com/cucumber-rs/cucumber/tree/v0.10.0 -[Diff](/../../compare/v0.9.0...v0.10.0) | [Milestone](/../../milestone/2) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.9.0...v0.10.0) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/2) ### BC Breaks @@ -658,21 +661,21 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Error on a step matching multiple step functions ([#143]). - `timestamps` Cargo feature that enables collecting of timestamps for all the happened events during tests execution (useful for `Writer`s which format requires them) ([#145]). -[#128]: /../../pull/128 -[#136]: /../../pull/136 -[#137]: /../../pull/137 -[#142]: /../../pull/142 -[#143]: /../../pull/143 -[#144]: /../../pull/144 -[#145]: /../../pull/145 +[#128]: https://github.com/cucumber-rs/cucumber/pull/128 +[#136]: https://github.com/cucumber-rs/cucumber/pull/136 +[#137]: https://github.com/cucumber-rs/cucumber/pull/137 +[#142]: https://github.com/cucumber-rs/cucumber/pull/142 +[#143]: https://github.com/cucumber-rs/cucumber/pull/143 +[#144]: https://github.com/cucumber-rs/cucumber/pull/144 +[#145]: https://github.com/cucumber-rs/cucumber/pull/145 ## [0.9.0] · 2021-07-19 -[0.9.0]: /../../tree/v0.9.0 +[0.9.0]: https://github.com/cucumber-rs/cucumber/tree/v0.9.0 -[Diff](/../../compare/v0.8.4...v0.9.0) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.8.4...v0.9.0) ### BC Breaks @@ -691,9 +694,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.8.4] · 2021-02-18 -[0.8.4]: /../../tree/v0.8.4 +[0.8.4]: https://github.com/cucumber-rs/cucumber/tree/v0.8.4 -[Diff](/../../compare/v0.8.3...v0.8.4) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.8.3...v0.8.4) ### Added @@ -704,9 +707,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.8.3] · 2021-02-09 -[0.8.3]: /../../tree/v0.8.3 +[0.8.3]: https://github.com/cucumber-rs/cucumber/tree/v0.8.3 -[Diff](/../../compare/v0.8.2...v0.8.3) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.8.2...v0.8.3) ### Changed @@ -716,9 +719,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.8.2] · 2021-01-30 -[0.8.2]: /../../tree/v0.8.2 +[0.8.2]: https://github.com/cucumber-rs/cucumber/tree/v0.8.2 -[Diff](/../../compare/v0.8.1...v0.8.2) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.8.1...v0.8.2) ### Added @@ -729,9 +732,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.8.1] · 2021-01-30 -[0.8.1]: /../../tree/v0.8.1 +[0.8.1]: https://github.com/cucumber-rs/cucumber/tree/v0.8.1 -[Diff](/../../compare/v0.8.0...v0.8.1) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.8.0...v0.8.1) ### Added @@ -741,9 +744,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.8.0] · 2021-01-18 -[0.8.0]: /../../tree/v0.8.0 +[0.8.0]: https://github.com/cucumber-rs/cucumber/tree/v0.8.0 -[Diff](/../../compare/v0.7.3...v0.8.0) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.7.3...v0.8.0) ### Added @@ -758,31 +761,31 @@ All user visible changes to `cucumber` crate will be documented in this file. Th - Filtering of tests by tag. ([#67]) - Removed unnecessary dependent traits from `World` trait. -[#67]: /../../issues/67 -[#81]: /../../pull/81 -[#91]: /../../issues/91 +[#67]: https://github.com/cucumber-rs/cucumber/issues/67 +[#81]: https://github.com/cucumber-rs/cucumber/pull/81 +[#91]: https://github.com/cucumber-rs/cucumber/issues/91 ## [0.7.3] · 2020-09-20 -[0.7.3]: /../../tree/v0.7.3 +[0.7.3]: https://github.com/cucumber-rs/cucumber/tree/v0.7.3 -[Diff](/../../compare/v0.7.2...v0.7.3) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.7.2...v0.7.3) ### Fixed - Fix missing `mut` in `t!` macro for regexes — thanks [@stefanpieck](https://github.com/stefanpieck)! ([#68]) -[#68]: /../../issues/68 +[#68]: https://github.com/cucumber-rs/cucumber/issues/68 ## [0.7.2] · 2020-09-14 -[0.7.2]: /../../tree/v0.7.2 +[0.7.2]: https://github.com/cucumber-rs/cucumber/tree/v0.7.2 -[Diff](/../../compare/v0.7.1...v0.7.2) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.7.1...v0.7.2) ### Added @@ -792,9 +795,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.7.1] · 2020-09-09 -[0.7.1]: /../../tree/v0.7.1 +[0.7.1]: https://github.com/cucumber-rs/cucumber/tree/v0.7.1 -[Diff](/../../compare/v0.7.0...v0.7.1) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.7.0...v0.7.1) ### Fixed @@ -804,9 +807,9 @@ All user visible changes to `cucumber` crate will be documented in this file. Th ## [0.7.0] · 2020-09-07 -[0.7.0]: /../../tree/v0.7.0 +[0.7.0]: https://github.com/cucumber-rs/cucumber/tree/v0.7.0 -[Diff](/../../compare/v0.6.8...v0.7.0) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.6.8...v0.7.0) ### BC Breaks diff --git a/Cargo.toml b/Cargo.toml index e713b358..1a94b878 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cucumber" -version = "0.21.1" +version = "0.22.0" edition = "2024" rust-version = "1.88" description = """\ @@ -82,7 +82,7 @@ smart-default = "0.7.1" # "macros" feature dependencies. anyhow = { version = "1.0.58", optional = true } -cucumber-codegen = { version = "=0.21.1", path = "./codegen", optional = true } +cucumber-codegen = { version = "=0.22.0", path = "./codegen", optional = true } cucumber-expressions = { version = "0.5", features = ["into-regex"], optional = true } inventory = { version = "0.3", optional = true } diff --git a/README.md b/README.md index d4e7c170..7ec76312 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Cucumber testing framework for Rust An implementation of the [Cucumber] testing framework for Rust. Fully native, no external test runners or dependencies. - Book ([current][1] | [edge][2]) -- [Changelog](https://github.com/cucumber-rs/cucumber/blob/main/CHANGELOG.md) +- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/CHANGELOG.md) @@ -113,8 +113,8 @@ The full gamut of Cucumber's [Gherkin] language is implemented by the [`gherkin` This project is licensed under either of - * Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/main/LICENSE-APACHE) or ) - * MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/main/LICENSE-MIT) or ) + * Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-APACHE) or ) + * MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-MIT) or ) at your option. diff --git a/book/src/output/intellij.md b/book/src/output/intellij.md index 7040d5d7..65b2a025 100644 --- a/book/src/output/intellij.md +++ b/book/src/output/intellij.md @@ -5,7 +5,7 @@ IntelliJ Rust (`libtest`) integration Example below is set up to output with the default [`writer::Basic`] if there is no `--format=json` option, or with [`writer::Libtest`] otherwise. ```toml -cucumber = { version = "0.20", features = ["libtest"] } +cucumber = { version = "0.22", features = ["libtest"] } ``` ```rust # extern crate cucumber; diff --git a/book/src/output/json.md b/book/src/output/json.md index f955e728..d7799870 100644 --- a/book/src/output/json.md +++ b/book/src/output/json.md @@ -5,7 +5,7 @@ Cucumber JSON format This requires `output-json` feature to be enabled in `Cargo.toml`: ```toml -cucumber = { version = "0.20", features = ["output-json"] } +cucumber = { version = "0.22", features = ["output-json"] } ``` And configuring output to [`writer::Json`]: diff --git a/book/src/output/junit.md b/book/src/output/junit.md index da00d6cf..cf6edb4c 100644 --- a/book/src/output/junit.md +++ b/book/src/output/junit.md @@ -5,7 +5,7 @@ JUnit XML report This requires `output-junit` feature to be enabled in `Cargo.toml`: ```toml -cucumber = { version = "0.20", features = ["output-junit"] } +cucumber = { version = "0.22", features = ["output-junit"] } ``` And configuring output to [`writer::JUnit`]: diff --git a/book/src/quickstart.md b/book/src/quickstart.md index 31d93379..1c873d9e 100644 --- a/book/src/quickstart.md +++ b/book/src/quickstart.md @@ -8,7 +8,7 @@ To start, let's create a directory called `tests/` in the root of the project an Add this to `Cargo.toml`: ```toml [dev-dependencies] -cucumber = "0.20" +cucumber = "0.22" futures = "0.3" [[test]] @@ -37,7 +37,7 @@ To enable testing of our `simple.feature`, let's add this code to `example.rs`: # use cucumber::{World, given}; -// These `Cat` definitions would normally be inside your project's code, +// 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 { @@ -51,7 +51,7 @@ impl Cat { } // `World` is your shared, likely mutable state. -// Cucumber constructs it via `Default::default()` for each scenario. +// Cucumber constructs it via `Default::default()` for each scenario. #[derive(Debug, Default, World)] pub struct AnimalWorld { cat: Cat, @@ -88,7 +88,7 @@ fn main() { > # > #[derive(Debug, World)] > // Accepts both sync/async and fallible/infallible functions. -> #[world(init = Self::new)] +> #[world(init = Self::new)] > pub struct AnimalWorld { > cat: Cat, > } @@ -103,7 +103,7 @@ fn main() { > # fn main() {} > ``` -If we run this, we should see an output like this: +If we run this, we should see an output like this: ![record](rec/quickstart_simple_1.gif) A checkmark `✔` next to the `Given a hungry cat` [step] means that it has been matched, executed and passed. @@ -161,7 +161,7 @@ fn feed_cat(world: &mut AnimalWorld) { # } ``` -Once we run the tests again, we see that two lines are green now and the next one is marked as not yet implemented: +Once we run the tests again, we see that two lines are green now and the next one is marked as not yet implemented: ![record](rec/quickstart_simple_2.gif) Finally, how do we check our result? We expect that this will cause some change in the cat and that the cat will no longer be hungry since it has been fed. The `then` [step] matcher follows to assert this, as our [feature] says: @@ -211,7 +211,7 @@ fn cat_is_fed(world: &mut AnimalWorld) { # } ``` -Once we run the tests, now we see all steps being accounted for and the whole [scenario] passing: +Once we run the tests, now we see all steps being accounted for and the whole [scenario] passing: ![record](rec/quickstart_simple_3.gif) > __TIP__: In addition to assertions, we may also return a `Result<()>` from a [step] matching function. Returning `Err` will cause the [step] to fail. This lets using the `?` operator for more concise step implementations just like in [unit tests](https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html#tests-and-). @@ -261,7 +261,7 @@ fn cat_is_fed(world: &mut AnimalWorld) { # } ``` -And see the test failing: +And see the test failing: ![record](rec/quickstart_simple_fail.gif) > __TIP__: By default, unlike [unit tests](https://doc.rust-lang.org/cargo/commands/cargo-test.html#test-options), failed [step]s don't terminate the execution instantly, and the whole test suite is executed regardless of them. Use `--fail-fast` [CLI] option to stop execution on first failure. @@ -332,7 +332,7 @@ fn hungry_cat(world: &mut AnimalWorld, state: String) { > __NOTE__: We surround the regex with `^..$` to ensure an __exact__ match. This is much more useful when adding more and more [step]s, so they won't accidentally interfere with each other. -[Cucumber] will reuse these [step] matchers: +[Cucumber] will reuse these [step] matchers: ![record](rec/quickstart_concurrent_sync.gif) > __NOTE__: Captured values are __bold__ to indicate which part of a [step] is actually captured. @@ -398,7 +398,7 @@ A contrived example, but it demonstrates that [step]s can be reused as long as t Let's switch our runtime to `tokio`: ```toml [dev-dependencies] -cucumber = "0.20" +cucumber = "0.22" tokio = { version = "1.10", features = ["macros", "rt-multi-thread", "time"] } [[test]] diff --git a/codegen/CHANGELOG.md b/codegen/CHANGELOG.md index d7cf3320..fa60e8f6 100644 --- a/codegen/CHANGELOG.md +++ b/codegen/CHANGELOG.md @@ -6,29 +6,35 @@ All user visible changes to `cucumber-codegen` crate will be documented in this -## [0.22.0] · 2024-??-?? (unreleased) -[0.22.0]: /../../tree/v0.22.0/codegen +## [0.22.0] · 2025-12-12 +[0.22.0]: https://github.com/cucumber-rs/cucumber/tree/v0.22.0/codegen -[Milestone](/../../milestone/28) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/28) ### BC Breaks - Bumped up [MSRV] to 1.88 to get rid of `once_cell` crate, for `#[expect]` attribute usage, and because of migration to 2024 edition. ([4010c1ad], [f1307038], [b46930c3], [9705253b], [0c7dfc3c], [a4cbd3d2]) -[0c7dfc3c]: /../../commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed -[4010c1ad]: /../../commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f -[9705253b]: /../../commit/9705253bda5caadfe3eea91f50420222158dd944 -[a4cbd3d2]: /../../commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 -[b46930c3]: /../../commit/b46930c32ef5ae490df8063905144a45de27eda1 -[f1307038]: /../../commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf +### Fixed + +- `clippy::trivial_regex` lint triggering on `#[given]`/`#[when]`/`#[then]` steps without regular expression. ([81acba84], [#384]) + +[#384]: https://github.com/cucumber-rs/cucumber/pull/384 +[0c7dfc3c]: https://github.com/cucumber-rs/cucumber/commit/0c7dfc3c80f0f58ce9a52f252485d1d14e6eb0ed +[4010c1ad]: https://github.com/cucumber-rs/cucumber/commit/4010c1ad6a53d6b7f0b28cefea73c8c13e880e9f +[81acba84]: https://github.com/cucumber-rs/cucumber/commit/81acba84697a5b04c45e2c5d5446f1ffbe289632 +[9705253b]: https://github.com/cucumber-rs/cucumber/commit/9705253bda5caadfe3eea91f50420222158dd944 +[a4cbd3d2]: https://github.com/cucumber-rs/cucumber/commit/a4cbd3d282fe8e01f05609eabea6410c0e2b46a3 +[b46930c3]: https://github.com/cucumber-rs/cucumber/commit/b46930c32ef5ae490df8063905144a45de27eda1 +[f1307038]: https://github.com/cucumber-rs/cucumber/commit/f1307038cb6b1e38c1cc259a0e09fb583033d0cf ## [0.21.1] · 2024-06-16 -[0.21.1]: /../../tree/v0.21.1/codegen +[0.21.1]: https://github.com/cucumber-rs/cucumber/tree/v0.21.1/codegen -[Milestone](/../../milestone/29) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/29) ### Version bump only @@ -38,23 +44,23 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.21.0] · 2024-04-22 -[0.21.0]: /../../tree/v0.21.0/codegen +[0.21.0]: https://github.com/cucumber-rs/cucumber/tree/v0.21.0/codegen -[Milestone](/../../milestone/26) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/26) ### BC Breaks - Bumped up [MSRV] to 1.75 for using `async fn` in traits. ([#324]) -[#324]: /../../pull/324 +[#324]: https://github.com/cucumber-rs/cucumber/pull/324 ## [0.20.2] · 2023-12-04 -[0.20.2]: /../../tree/v0.20.2/codegen +[0.20.2]: https://github.com/cucumber-rs/cucumber/tree/v0.20.2/codegen -[Milestone](/../../milestone/27) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/27) ### Version bump only @@ -64,9 +70,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.20.1] · 2023-10-16 -[0.20.1]: /../../tree/v0.20.1/codegen +[0.20.1]: https://github.com/cucumber-rs/cucumber/tree/v0.20.1/codegen -[Milestone](/../../milestone/25) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/25) ### Version bump only @@ -76,9 +82,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.20.0] · 2023-07-10 -[0.20.0]: /../../tree/v0.20.0/codegen +[0.20.0]: https://github.com/cucumber-rs/cucumber/tree/v0.20.0/codegen -[Milestone](/../../milestone/24) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/24) ### BC Breaks @@ -88,16 +94,16 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 - Switched to 2.0 version of [`syn`]. ([#266]) -[#266]: /../../pull/266 -[#288]: /../../pull/288 +[#266]: https://github.com/cucumber-rs/cucumber/pull/266 +[#288]: https://github.com/cucumber-rs/cucumber/pull/288 ## [0.19.1] · 2022-12-29 -[0.19.1]: /../../tree/v0.19.1/codegen +[0.19.1]: https://github.com/cucumber-rs/cucumber/tree/v0.19.1/codegen -[Milestone](/../../milestone/23) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/23) ### Version bump only @@ -107,9 +113,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.19.0] · 2022-12-07 -[0.19.0]: /../../tree/v0.19.0/codegen +[0.19.0]: https://github.com/cucumber-rs/cucumber/tree/v0.19.0/codegen -[Milestone](/../../milestone/22) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/22) ### Version bump only @@ -119,9 +125,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.18.0] · 2022-12-07 -[0.18.0]: /../../tree/v0.18.0/codegen +[0.18.0]: https://github.com/cucumber-rs/cucumber/tree/v0.18.0/codegen -[Milestone](/../../milestone/21) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/21) ### Version bump only @@ -131,9 +137,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.17.0] · 2022-11-23 -[0.17.0]: /../../tree/v0.17.0/codegen +[0.17.0]: https://github.com/cucumber-rs/cucumber/tree/v0.17.0/codegen -[Milestone](/../../milestone/20) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/20) ### Version bump only @@ -143,23 +149,23 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.16.0] · 2022-11-09 -[0.16.0]: /../../tree/v0.16.0/codegen +[0.16.0]: https://github.com/cucumber-rs/cucumber/tree/v0.16.0/codegen -[Milestone](/../../milestone/19) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/19) ### BC Breaks - Bumped up [MSRV] to 1.65 for using `let`-`else` statements. ([7f52d4a5]) -[7f52d4a5]: /../../commit/7f52d4a5faa3b69bec6c7fb765b50455cf7802aa +[7f52d4a5]: https://github.com/cucumber-rs/cucumber/commit/7f52d4a5faa3b69bec6c7fb765b50455cf7802aa ## [0.15.3] · 2022-11-01 -[0.15.3]: /../../tree/v0.15.3/codegen +[0.15.3]: https://github.com/cucumber-rs/cucumber/tree/v0.15.3/codegen -[Milestone](/../../milestone/18) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/18) ### Version bump only @@ -169,9 +175,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.15.2] · 2022-10-25 -[0.15.2]: /../../tree/v0.15.2/codegen +[0.15.2]: https://github.com/cucumber-rs/cucumber/tree/v0.15.2/codegen -[Milestone](/../../milestone/17) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/17) ### Version bump only @@ -181,9 +187,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.15.1] · 2022-10-12 -[0.15.1]: /../../tree/v0.15.1/codegen +[0.15.1]: https://github.com/cucumber-rs/cucumber/tree/v0.15.1/codegen -[Milestone](/../../milestone/16) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/16) ### Version bump only @@ -193,9 +199,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.15.0] · 2022-10-05 -[0.15.0]: /../../tree/v0.15.0/codegen +[0.15.0]: https://github.com/cucumber-rs/cucumber/tree/v0.15.0/codegen -[Milestone](/../../milestone/15) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/15) ### Version bump only @@ -205,21 +211,21 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.14.2] · 2022-09-19 -[0.14.2]: /../../tree/v0.14.2/codegen +[0.14.2]: https://github.com/cucumber-rs/cucumber/tree/v0.14.2/codegen ### Fixed - `#[derive(World)]` macro being unhygienic regarding custom `Result` types. ([186af8b1]) -[186af8b1]: /../../commit/186af8b1de37275b308897e2e30d6982830b0278 +[186af8b1]: https://github.com/cucumber-rs/cucumber/commit/186af8b1de37275b308897e2e30d6982830b0278 ## [0.14.1] · 2022-09-12 -[0.14.1]: /../../tree/v0.14.1/codegen +[0.14.1]: https://github.com/cucumber-rs/cucumber/tree/v0.14.1/codegen -[Milestone](/../../milestone/14) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/14) ### Version bump only @@ -229,28 +235,28 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.14.0] · 2022-09-08 -[0.14.0]: /../../tree/v0.14.0/codegen +[0.14.0]: https://github.com/cucumber-rs/cucumber/tree/v0.14.0/codegen -[Milestone](/../../milestone/13) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/13) ### BC Breaks - 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]) -[#217]: /../../issues/217 -[#219]: /../../pull/219 -[8ad5cc86]: /../../commit/8ad5cc866bb9d6b49470790e3b0dd40690f63a09 -[cf055ac0]: /../../commit/cf055ac06c7b72f572882ce15d6a60da92ad60a0 -[fbd08ec2]: /../../commit/fbd08ec24dbd036c89f5f0af4d936b616790a166 +[#217]: https://github.com/cucumber-rs/cucumber/issues/217 +[#219]: https://github.com/cucumber-rs/cucumber/pull/219 +[8ad5cc86]: https://github.com/cucumber-rs/cucumber/commit/8ad5cc866bb9d6b49470790e3b0dd40690f63a09 +[cf055ac0]: https://github.com/cucumber-rs/cucumber/commit/cf055ac06c7b72f572882ce15d6a60da92ad60a0 +[fbd08ec2]: https://github.com/cucumber-rs/cucumber/commit/fbd08ec24dbd036c89f5f0af4d936b616790a166 ## [0.13.0] · 2022-03-29 -[0.13.0]: /../../tree/v0.13.0/codegen +[0.13.0]: https://github.com/cucumber-rs/cucumber/tree/v0.13.0/codegen -[Milestone](/../../milestone/12) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/12) ### Version bump only @@ -260,9 +266,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.12.2] · 2022-03-28 -[0.12.2]: /../../tree/v0.12.2/codegen +[0.12.2]: https://github.com/cucumber-rs/cucumber/tree/v0.12.2/codegen -[Milestone](/../../milestone/10) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/10) ### Version bump only @@ -272,9 +278,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.12.1] · 2022-03-09 -[0.12.1]: /../../tree/v0.12.1/codegen +[0.12.1]: https://github.com/cucumber-rs/cucumber/tree/v0.12.1/codegen -[Milestone](/../../milestone/11) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/11) ### Security updated @@ -286,23 +292,23 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.12.0] · 2022-02-10 -[0.12.0]: /../../tree/v0.12.0/codegen +[0.12.0]: https://github.com/cucumber-rs/cucumber/tree/v0.12.0/codegen -[Milestone](/../../milestone/9) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/9) ### Added - Support for multiple capturing groups in `Parameter` regex (previously was forbidden). ([#204]) -[#204]: /../../pull/204 +[#204]: https://github.com/cucumber-rs/cucumber/pull/204 ## [0.11.3] · 2022-01-31 -[0.11.3]: /../../tree/v0.11.3/codegen +[0.11.3]: https://github.com/cucumber-rs/cucumber/tree/v0.11.3/codegen -[Milestone](/../../milestone/8) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/8) ### Version bump only @@ -312,9 +318,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.11.2] · 2022-01-19 -[0.11.2]: /../../tree/v0.11.2/codegen +[0.11.2]: https://github.com/cucumber-rs/cucumber/tree/v0.11.2/codegen -[Milestone](/../../milestone/7) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/7) ### Version bump only @@ -324,9 +330,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.11.1] · 2022-01-07 -[0.11.1]: /../../tree/v0.11.1/codegen +[0.11.1]: https://github.com/cucumber-rs/cucumber/tree/v0.11.1/codegen -[Milestone](/../../milestone/6) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/6) ### Version bump only @@ -336,9 +342,9 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.11.0] · 2022-01-03 -[0.11.0]: /../../tree/v0.11.0/codegen +[0.11.0]: https://github.com/cucumber-rs/cucumber/tree/v0.11.0/codegen -[Milestone](/../../milestone/3) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/3) ### BC Breaks @@ -350,32 +356,32 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 - `expr = ...` argument to `#[given(...)]`, `#[when(...)]` and `#[then(...)]` attributes allowing [Cucumber Expressions]. ([#157]) - `#[derive(Parameter)]` attribute macro for implementing custom parameters of [Cucumber Expressions]. ([#168]) -[#151]: /../../pull/151 -[#157]: /../../pull/157 -[#168]: /../../pull/168 -[cef3d480]: /../../commit/cef3d480579190425461ddb04a1248675248351e +[#151]: https://github.com/cucumber-rs/cucumber/pull/151 +[#157]: https://github.com/cucumber-rs/cucumber/pull/157 +[#168]: https://github.com/cucumber-rs/cucumber/pull/168 +[cef3d480]: https://github.com/cucumber-rs/cucumber/commit/cef3d480579190425461ddb04a1248675248351e ## [0.10.2] · 2021-11-03 -[0.10.2]: /../../tree/v0.10.2/codegen +[0.10.2]: https://github.com/cucumber-rs/cucumber/tree/v0.10.2/codegen -[Milestone](/../../milestone/5) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/5) ### Added - World's type name to the generated `WorldInit` machinery to omit conflicts for different types in the same module. ([#150]) -[#150]: /../../pull/150 +[#150]: https://github.com/cucumber-rs/cucumber/pull/150 ## [0.10.1] · 2021-10-29 -[0.10.1]: /../../tree/v0.10.1/codegen +[0.10.1]: https://github.com/cucumber-rs/cucumber/tree/v0.10.1/codegen -[Milestone](/../../milestone/4) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/4) ### Version bump only @@ -385,22 +391,22 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 ## [0.10.0] · 2021-10-26 -[0.10.0]: /../../tree/v0.10.0/codegen +[0.10.0]: https://github.com/cucumber-rs/cucumber/tree/v0.10.0/codegen -[Milestone](/../../milestone/2) +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/2) ### BC Breaks - Renamed crate to `cucumber-codegen`. - Replaced `#[given(step)]`, `#[when(step)]` and `#[then(step)]` function argument attributes with a single `#[step]`. ([#128]) -[#128]: /../../pull/128 +[#128]: https://github.com/cucumber-rs/cucumber/pull/128 ## [0.1.0] · 2021-01-18 -[0.1.0]: /../../tree/v0.8.0/codegen +[0.1.0]: https://github.com/cucumber-rs/cucumber/tree/v0.8.0/codegen ### Added @@ -409,7 +415,7 @@ See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0 - [`when`](https://docs.rs/cucumber_rust_codegen/0.1.0/cucumber_rust_codegen/attr.when.html); - [`then`](https://docs.rs/cucumber_rust_codegen/0.1.0/cucumber_rust_codegen/attr.then.html). -[#81]: /../../pull/81 +[#81]: https://github.com/cucumber-rs/cucumber/pull/81 diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index e46cf6ac..5d6f915d 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cucumber-codegen" -version = "0.21.1" # should be the same as main crate version +version = "0.22.0" # should be the same as main crate version edition = "2024" rust-version = "1.88" description = "Code generation for `cucumber` crate." diff --git a/codegen/README.md b/codegen/README.md index 18c523cd..a0f0cdbe 100644 --- a/codegen/README.md +++ b/codegen/README.md @@ -7,7 +7,7 @@ [![CI](https://github.com/cucumber-rs/cucumber/actions/workflows/ci.yml/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain) [![Rust docs](https://docs.rs/cucumber-codegen/badge.svg "Rust docs")](https://docs.rs/cucumber-codegen) -- [Changelog](https://github.com/cucumber-rs/cucumber/blob/main/codegen/CHANGELOG.md) +- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/codegen/CHANGELOG.md) Code generation for [`cucumber`] tests auto-wiring. @@ -20,8 +20,8 @@ DO NOT use it directly, use [`cucumber`] crate instead. This project is licensed under either of -* Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/main/LICENSE-APACHE) or ) -* MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/main/LICENSE-MIT) or ) +* Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-APACHE) or ) +* MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-MIT) or ) at your option. From c096f70692b93ed2f7639a227f60b9ec5d44320d Mon Sep 17 00:00:00 2001 From: Simon Schrottner Date: Tue, 23 Dec 2025 14:26:31 +0100 Subject: [PATCH 12/16] Allow spaces in placeholders for `Examples` (#388, #387) Co-authored-by: Kai Ren --- CHANGELOG.md | 14 ++++++++++ src/feature.rs | 10 +++++-- .../background_scenario_outline.feature | 6 ++--- ...kground_scenario_outline.feature.debug.out | 26 +++++++++---------- ...rio_outline_with_spaces_in_headers.feature | 10 +++++++ ...e_with_spaces_in_headers.feature.basic.out | 5 ++++ ...with_spaces_in_headers.feature.colored.out | 8 ++++++ ...e_with_spaces_in_headers.feature.debug.out | 13 ++++++++++ 8 files changed, 74 insertions(+), 18 deletions(-) create mode 100644 tests/features/output/scenario_outline_with_spaces_in_headers.feature create mode 100644 tests/features/output/scenario_outline_with_spaces_in_headers.feature.basic.out create mode 100644 tests/features/output/scenario_outline_with_spaces_in_headers.feature.colored.out create mode 100644 tests/features/output/scenario_outline_with_spaces_in_headers.feature.debug.out diff --git a/CHANGELOG.md b/CHANGELOG.md index 85e04fe5..665b65e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,20 @@ All user visible changes to `cucumber` crate will be documented in this file. Th +## main + +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.22.0...main) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/31) + +### Fixed + +- Incorrectly disallowed spaces inside placeholders for `Examples`. ([#388], [#387]) + +[#387]: https://github.com/cucumber-rs/cucumber/issues/387 +[#388]: https://github.com/cucumber-rs/cucumber/pull/388 + + + + ## [0.22.0] · 2025-12-12 [0.22.0]: https://github.com/cucumber-rs/cucumber/tree/v0.22.0 diff --git a/src/feature.rs b/src/feature.rs index 244447e4..b6a0c3a9 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -142,12 +142,18 @@ fn expand_scenario( ) -> Vec> { /// [`Regex`] matching placeholders [`Examples`] should expand into. /// + /// # Format + /// + /// - Spaces are allowed inside placeholder. + /// - Placeholder cannot start or end with a space. + /// /// [`Examples`]: gherkin::Examples // TODO: Switch back to `lazy-regex::regex!()` once it migrates to `std`: // https://github.com/Canop/lazy-regex/issues/10 #[expect(clippy::unwrap_used, reason = "regex is valid")] - static TEMPLATE_REGEX: LazyLock = - LazyLock::new(|| Regex::new(r"<([^>\s]+)>").unwrap()); + static TEMPLATE_REGEX: LazyLock = LazyLock::new(|| { + Regex::new(r"<([^>\s](?:[^>\s]?|[^>\t\n\r\v\f]*[^>\s]))>").unwrap() + }); if scenario.examples.is_empty() { return vec![Ok(scenario)]; diff --git a/tests/features/output/background_scenario_outline.feature b/tests/features/output/background_scenario_outline.feature index fbff210b..ebaf5c74 100644 --- a/tests/features/output/background_scenario_outline.feature +++ b/tests/features/output/background_scenario_outline.feature @@ -6,8 +6,8 @@ Feature: Outline Scenario Outline: foo Given foo is When foo is - Then foo is + Then foo is Examples: - | bar1 | bar2 | bar3 | - | 1 | 2 | 3 | + | bar1 | bar2 | bar 3 | + | 1 | 2 | 3 | diff --git a/tests/features/output/background_scenario_outline.feature.debug.out b/tests/features/output/background_scenario_outline.feature.debug.out index 14412f5f..b9fc6e2a 100644 --- a/tests/features/output/background_scenario_outline.feature.debug.out +++ b/tests/features/output/background_scenario_outline.feature.debug.out @@ -1,15 +1,15 @@ ParsingFinished { features: 1, rules: 0, scenarios: 1, steps: 3, parser_errors: 0 } Started -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Started) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Started, retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Background(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Started), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Background(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 9, column: 1 }))), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Started), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 9, column: 1 }))), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Started), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 10, column: 1 }))), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }, Started), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 11, column: 1 }))), retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Finished, retries: None })) -Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Finished) -Finished \ No newline at end of file +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Started) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Started, retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Background(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Background(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 9, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 9, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 10, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 11, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }, RetryableScenario { event: Finished, retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: Some(Background { keyword: "Background", name: "", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }], position: LineCol { line: 3 } }), scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 7 } }, Step { keyword: "When ", ty: When, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 8 } }, Step { keyword: "Then ", ty: Then, value: "foo is 3", docstring: None, table: None, position: LineCol { line: 9 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar1", "bar2", "bar 3"], ["1", "2", "3"]], position: LineCol { line: 12 } }), tags: [], position: LineCol { line: 11 } }], tags: [], position: LineCol { line: 13 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Finished) +Finished diff --git a/tests/features/output/scenario_outline_with_spaces_in_headers.feature b/tests/features/output/scenario_outline_with_spaces_in_headers.feature new file mode 100644 index 00000000..40c096d9 --- /dev/null +++ b/tests/features/output/scenario_outline_with_spaces_in_headers.feature @@ -0,0 +1,10 @@ +Feature: Outline + + Scenario Outline: foo + Given foo is + When foo is + Then foo is + + Examples: + | bar 1 | bar two | bar three | + | 0 | 1 | 2 | diff --git a/tests/features/output/scenario_outline_with_spaces_in_headers.feature.basic.out b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.basic.out new file mode 100644 index 00000000..1ff670a4 --- /dev/null +++ b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.basic.out @@ -0,0 +1,5 @@ +Feature: Outline + Scenario Outline: foo + ✔ Given foo is 0 + ✔ When foo is 1 + ✔ Then foo is 2 diff --git a/tests/features/output/scenario_outline_with_spaces_in_headers.feature.colored.out b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.colored.out new file mode 100644 index 00000000..34f5df45 --- /dev/null +++ b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.colored.out @@ -0,0 +1,8 @@ +Feature: Outline + Scenario Outline: foo + Given foo is 0 +  ✔ Given foo is 0 + When foo is 1 +  ✔ When foo is 1 + Then foo is 2 +  ✔ Then foo is 2 diff --git a/tests/features/output/scenario_outline_with_spaces_in_headers.feature.debug.out b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.debug.out new file mode 100644 index 00000000..2973be30 --- /dev/null +++ b/tests/features/output/scenario_outline_with_spaces_in_headers.feature.debug.out @@ -0,0 +1,13 @@ +ParsingFinished { features: 1, rules: 0, scenarios: 1, steps: 3, parser_errors: 0 } +Started +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Started) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Started, retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 9, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 10, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }, Started), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Step(Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }, Passed(CaptureLocations(Captures { pid: Some(PatternID(0)), spans: {0: 0..8, 1: 7..8} }), Some(Location { line: 11, column: 1 }))), retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Scenario(Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }, RetryableScenario { event: Finished, retries: None })) +Feature(Feature { keyword: "Feature", name: "Outline", description: None, background: None, scenarios: [Scenario { keyword: "Scenario Outline", name: "foo", description: None, steps: [Step { keyword: "Given ", ty: Given, value: "foo is 0", docstring: None, table: None, position: LineCol { line: 4 } }, Step { keyword: "When ", ty: When, value: "foo is 1", docstring: None, table: None, position: LineCol { line: 5 } }, Step { keyword: "Then ", ty: Then, value: "foo is 2", docstring: None, table: None, position: LineCol { line: 6 } }], examples: [Examples { keyword: "Examples", name: None, description: None, table: Some(Table { rows: [["bar 1", "bar two", "bar three"], ["0", "1", "2"]], position: LineCol { line: 9 } }), tags: [], position: LineCol { line: 8 } }], tags: [], position: LineCol { line: 10 } }], rules: [], tags: [], position: LineCol { line: 1 }, }, Finished) +Finished From 12500e7a1aebce5fb393bdcb5f23b3acc6989dd9 Mon Sep 17 00:00:00 2001 From: tyranron Date: Tue, 23 Dec 2025 14:30:24 +0100 Subject: [PATCH 13/16] Prepare 0.22.1 release --- CHANGELOG.md | 5 +++-- Cargo.toml | 4 ++-- README.md | 6 +++--- codegen/CHANGELOG.md | 12 ++++++++++++ codegen/Cargo.toml | 2 +- codegen/README.md | 6 +++--- 6 files changed, 24 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 665b65e6..cc889a6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,10 @@ All user visible changes to `cucumber` crate will be documented in this file. Th -## main +## [0.22.1] · 2025-12-23 +[0.22.1]: https://github.com/cucumber-rs/cucumber/tree/v0.22.1 -[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.22.0...main) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/31) +[Diff](https://github.com/cucumber-rs/cucumber/compare/v0.22.0...v0.22.1) | [Milestone](https://github.com/cucumber-rs/cucumber/milestone/31) ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 1a94b878..3e979272 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cucumber" -version = "0.22.0" +version = "0.22.1" edition = "2024" rust-version = "1.88" description = """\ @@ -82,7 +82,7 @@ smart-default = "0.7.1" # "macros" feature dependencies. anyhow = { version = "1.0.58", optional = true } -cucumber-codegen = { version = "=0.22.0", path = "./codegen", optional = true } +cucumber-codegen = { version = "=0.22.1", path = "./codegen", optional = true } cucumber-expressions = { version = "0.5", features = ["into-regex"], optional = true } inventory = { version = "0.3", optional = true } diff --git a/README.md b/README.md index 7ec76312..2dfab280 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Cucumber testing framework for Rust An implementation of the [Cucumber] testing framework for Rust. Fully native, no external test runners or dependencies. - Book ([current][1] | [edge][2]) -- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/CHANGELOG.md) +- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/CHANGELOG.md) @@ -113,8 +113,8 @@ The full gamut of Cucumber's [Gherkin] language is implemented by the [`gherkin` This project is licensed under either of - * Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-APACHE) or ) - * MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-MIT) or ) + * Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/LICENSE-APACHE) or ) + * MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/LICENSE-MIT) or ) at your option. diff --git a/codegen/CHANGELOG.md b/codegen/CHANGELOG.md index fa60e8f6..4b9c4d55 100644 --- a/codegen/CHANGELOG.md +++ b/codegen/CHANGELOG.md @@ -6,6 +6,18 @@ All user visible changes to `cucumber-codegen` crate will be documented in this +## [0.22.1] · 2025-12-23 +[0.22.1]: https://github.com/cucumber-rs/cucumber/tree/v0.22.1/codegen + +[Milestone](https://github.com/cucumber-rs/cucumber/milestone/31) + +### Version bump only + +See `cucumber` crate [changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/CHANGELOG.md). + + + + ## [0.22.0] · 2025-12-12 [0.22.0]: https://github.com/cucumber-rs/cucumber/tree/v0.22.0/codegen diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index 5d6f915d..25977eef 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cucumber-codegen" -version = "0.22.0" # should be the same as main crate version +version = "0.22.1" # should be the same as main crate version edition = "2024" rust-version = "1.88" description = "Code generation for `cucumber` crate." diff --git a/codegen/README.md b/codegen/README.md index a0f0cdbe..ded97a80 100644 --- a/codegen/README.md +++ b/codegen/README.md @@ -7,7 +7,7 @@ [![CI](https://github.com/cucumber-rs/cucumber/actions/workflows/ci.yml/badge.svg?branch=main "CI")](https://github.com/cucumber-rs/cucumber/actions?query=workflow%3ACI+branch%3Amain) [![Rust docs](https://docs.rs/cucumber-codegen/badge.svg "Rust docs")](https://docs.rs/cucumber-codegen) -- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/codegen/CHANGELOG.md) +- [Changelog](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/codegen/CHANGELOG.md) Code generation for [`cucumber`] tests auto-wiring. @@ -20,8 +20,8 @@ DO NOT use it directly, use [`cucumber`] crate instead. This project is licensed under either of -* Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-APACHE) or ) -* MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.0/LICENSE-MIT) or ) +* Apache License, Version 2.0 ([LICENSE-APACHE](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/LICENSE-APACHE) or ) +* MIT license ([LICENSE-MIT](https://github.com/cucumber-rs/cucumber/blob/v0.22.1/LICENSE-MIT) or ) at your option. From 6087a4d48eca3817e5ad6dd623563a819cb810a4 Mon Sep 17 00:00:00 2001 From: tyranron Date: Mon, 5 Jan 2026 15:48:38 +0100 Subject: [PATCH 14/16] Update copyright notices to 2026 year --- LICENSE-MIT | 2 +- codegen/src/attribute.rs | 2 +- codegen/src/lib.rs | 2 +- codegen/src/parameter.rs | 2 +- codegen/src/world.rs | 2 +- src/cli.rs | 2 +- src/codegen.rs | 2 +- src/cucumber.rs | 2 +- src/event.rs | 2 +- src/feature.rs | 2 +- src/lib.rs | 2 +- src/parser/basic.rs | 2 +- src/parser/mod.rs | 2 +- src/runner/basic.rs | 2 +- src/runner/mod.rs | 2 +- src/step.rs | 2 +- src/tag.rs | 2 +- src/writer/basic.rs | 2 +- src/writer/discard.rs | 2 +- src/writer/fail_on_skipped.rs | 2 +- src/writer/json.rs | 2 +- src/writer/junit.rs | 2 +- src/writer/libtest.rs | 2 +- src/writer/mod.rs | 2 +- src/writer/normalize.rs | 2 +- src/writer/or.rs | 2 +- src/writer/out.rs | 2 +- src/writer/repeat.rs | 2 +- src/writer/summarize.rs | 2 +- src/writer/tee.rs | 2 +- 30 files changed, 30 insertions(+), 30 deletions(-) diff --git a/LICENSE-MIT b/LICENSE-MIT index ff40298e..3cabd022 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,4 @@ -Copyright (c) 2018-2025 Brendan Molloy , +Copyright (c) 2018-2026 Brendan Molloy , Ilya Solovyiov , Kai Ren diff --git a/codegen/src/attribute.rs b/codegen/src/attribute.rs index 43dfac7f..02b4cb2b 100644 --- a/codegen/src/attribute.rs +++ b/codegen/src/attribute.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2025 Brendan Molloy , +// Copyright (c) 2020-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 27014d48..6c37a041 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2025 Brendan Molloy , +// Copyright (c) 2020-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/codegen/src/parameter.rs b/codegen/src/parameter.rs index a1677391..e1b564bb 100644 --- a/codegen/src/parameter.rs +++ b/codegen/src/parameter.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2025 Brendan Molloy , +// Copyright (c) 2020-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/codegen/src/world.rs b/codegen/src/world.rs index 15a75c09..2f614aeb 100644 --- a/codegen/src/world.rs +++ b/codegen/src/world.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2020-2025 Brendan Molloy , +// Copyright (c) 2020-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/cli.rs b/src/cli.rs index 6e62cb31..f016e6d7 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/codegen.rs b/src/codegen.rs index b049c15f..71e6b3c7 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/cucumber.rs b/src/cucumber.rs index 090853ee..c5c6e1eb 100644 --- a/src/cucumber.rs +++ b/src/cucumber.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/event.rs b/src/event.rs index 39f3aed1..5c7e6b89 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/feature.rs b/src/feature.rs index b6a0c3a9..1c9bd132 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/lib.rs b/src/lib.rs index f1b8bbbb..e25c3a45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/parser/basic.rs b/src/parser/basic.rs index 5eeae695..3c26d6f2 100644 --- a/src/parser/basic.rs +++ b/src/parser/basic.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 58674b0e..4c2608f2 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/runner/basic.rs b/src/runner/basic.rs index d2c879a9..9cadde2b 100644 --- a/src/runner/basic.rs +++ b/src/runner/basic.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/runner/mod.rs b/src/runner/mod.rs index 7b3763c7..dc917fb2 100644 --- a/src/runner/mod.rs +++ b/src/runner/mod.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/step.rs b/src/step.rs index 41c6cfbd..56325fc5 100644 --- a/src/step.rs +++ b/src/step.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/tag.rs b/src/tag.rs index abeed083..56fc7a99 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/basic.rs b/src/writer/basic.rs index 2c80772e..da8741cc 100644 --- a/src/writer/basic.rs +++ b/src/writer/basic.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/discard.rs b/src/writer/discard.rs index f8f4513b..0f1a8148 100644 --- a/src/writer/discard.rs +++ b/src/writer/discard.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/fail_on_skipped.rs b/src/writer/fail_on_skipped.rs index a992d5b7..30774725 100644 --- a/src/writer/fail_on_skipped.rs +++ b/src/writer/fail_on_skipped.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/json.rs b/src/writer/json.rs index b13ecc7e..5cd30e1a 100644 --- a/src/writer/json.rs +++ b/src/writer/json.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/junit.rs b/src/writer/junit.rs index 13aff4be..f6aa8d8f 100644 --- a/src/writer/junit.rs +++ b/src/writer/junit.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/libtest.rs b/src/writer/libtest.rs index d02800fd..83218d8d 100644 --- a/src/writer/libtest.rs +++ b/src/writer/libtest.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/mod.rs b/src/writer/mod.rs index 611e79f0..ac7a4a6f 100644 --- a/src/writer/mod.rs +++ b/src/writer/mod.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/normalize.rs b/src/writer/normalize.rs index 77712691..90970c7f 100644 --- a/src/writer/normalize.rs +++ b/src/writer/normalize.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/or.rs b/src/writer/or.rs index fc5c7304..b6457d90 100644 --- a/src/writer/or.rs +++ b/src/writer/or.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/out.rs b/src/writer/out.rs index 76d6e207..b8041cb1 100644 --- a/src/writer/out.rs +++ b/src/writer/out.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/repeat.rs b/src/writer/repeat.rs index 5ca5a137..eae80947 100644 --- a/src/writer/repeat.rs +++ b/src/writer/repeat.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/summarize.rs b/src/writer/summarize.rs index 39f94564..bbdc7313 100644 --- a/src/writer/summarize.rs +++ b/src/writer/summarize.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // diff --git a/src/writer/tee.rs b/src/writer/tee.rs index 33ecb165..bd69e639 100644 --- a/src/writer/tee.rs +++ b/src/writer/tee.rs @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2025 Brendan Molloy , +// Copyright (c) 2018-2026 Brendan Molloy , // Ilya Solovyiov , // Kai Ren // From 4af7e34c50f2190fad4215b7e6803eb9e17c4ada Mon Sep 17 00:00:00 2001 From: tyranron Date: Fri, 23 Jan 2026 01:31:58 +0100 Subject: [PATCH 15/16] Tune lints for 1.93 Rust --- codegen/src/lib.rs | 1 + src/lib.rs | 1 + src/parser/mod.rs | 2 +- src/tracing.rs | 3 +-- src/writer/libtest.rs | 4 ++-- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/codegen/src/lib.rs b/codegen/src/lib.rs index 6c37a041..7b6eab3c 100644 --- a/codegen/src/lib.rs +++ b/codegen/src/lib.rs @@ -37,6 +37,7 @@ clippy::default_union_representation, clippy::derive_partial_eq_without_eq, clippy::doc_include_without_cfg, + clippy::doc_paragraphs_missing_punctuation, clippy::empty_drop, clippy::empty_structs_with_brackets, clippy::equatable_if_let, diff --git a/src/lib.rs b/src/lib.rs index e25c3a45..e9e681aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,6 +38,7 @@ clippy::default_union_representation, clippy::derive_partial_eq_without_eq, clippy::doc_include_without_cfg, + clippy::doc_paragraphs_missing_punctuation, clippy::empty_drop, clippy::empty_structs_with_brackets, clippy::equatable_if_let, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 4c2608f2..5c3ebf6c 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -64,7 +64,7 @@ pub enum Error { #[display("Failed to parse feature: {_0}")] Parsing(Arc), - /// Failed to expand [`Examples`] + /// Failed to expand [`Examples`]. /// /// [`Examples`]: gherkin::Examples #[display("Failed to expand examples: {_0}")] diff --git a/src/tracing.rs b/src/tracing.rs index b7c98f42..700896be 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -519,8 +519,7 @@ mod suffix { //! [`str`]ings appending [`tracing::Event`]s to separate them later. //! //! Every [`tracing::Event`] ends with: - //! - //! ([`BEFORE_SCENARIO_ID`][`ScenarioId`][`END`]|[`NO_SCENARIO_ID`][`END`]) + //! ([`BEFORE_SCENARIO_ID`][`ScenarioId`][`END`]|[`NO_SCENARIO_ID`][`END`]). //! //! [`ScenarioId`]: super::ScenarioId diff --git a/src/writer/libtest.rs b/src/writer/libtest.rs index 83218d8d..14c76dba 100644 --- a/src/writer/libtest.rs +++ b/src/writer/libtest.rs @@ -827,14 +827,14 @@ where enum LibTestJsonEvent { /// Event of test suite. Suite { - /// [`SuiteEvent`] + /// [`SuiteEvent`]. #[serde(flatten)] event: SuiteEvent, }, /// Event of the test case. Test { - /// [`TestEvent`] + /// [`TestEvent`]. #[serde(flatten)] event: TestEvent, }, From 3ddd94f0c41bf1360b05f06e312f17bc1778351e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Feb 2026 14:28:49 +0100 Subject: [PATCH 16/16] Upgrade `rand` crate from 0.9 to 0.10 version (#392) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Kai Ren --- Cargo.toml | 2 +- book/src/writing/retries.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3e979272..81facd3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,7 +103,7 @@ tracing = { version = "0.1", optional = true } tracing-subscriber = { version = "0.3.16", optional = true } [dev-dependencies] -rand = "0.9" +rand = "0.10" serial_test = "3.0" tempfile = "3.2" tokio = { version = "1.40", features = ["macros", "rt-multi-thread", "sync", "time"] } diff --git a/book/src/writing/retries.md b/book/src/writing/retries.md index 0e973fec..852a305d 100644 --- a/book/src/writing/retries.md +++ b/book/src/writing/retries.md @@ -1,7 +1,7 @@ Retrying failed scenarios ========================= -Often, it's nearly impossible to create fully-deterministic test case, especially when you are relying on environments like external services, browsers, file system, networking etc. That's why there is an ability to retry failed [scenario]s. +Often, it's nearly impossible to create fully-deterministic test case, especially when you are relying on environments like external services, browsers, file system, networking etc. That's why there is an ability to retry failed [scenario]s. > __WARNING__: Although this feature is supported, we highly recommend to use it as the _last resort only_. First, consider implementing in-[step] retries with your own needs (like [exponential backoff]). Other ways of dealing with flaky tests include, but not limited to: reducing number of concurrently executed scenarios (maybe even using `@serial` [tag]), mocking external environment, [controlling time in tests] or even [simulation testing]. It's always better to move towards tests determinism, rather than trying to tame their flakiness. @@ -20,7 +20,7 @@ Feature: Heads and tails Given a coin When I flip the coin Then I see tails - + # Attempts a single retry in 1 second. @retry.after(1s) Scenario: Heads @@ -50,7 +50,7 @@ Feature: Heads and tails # use std::time::Duration; # # use cucumber::{World, given, then, when}; -# use rand::Rng as _; +# use rand::RngExt as _; # use tokio::time::sleep; # # #[derive(Debug, Default, World)] @@ -67,7 +67,7 @@ async fn coin(_: &mut FlipWorld) { async fn flip(world: &mut FlipWorld) { sleep(Duration::from_secs(2)).await; - world.flipped = match rand::thread_rng().gen_range(0.0..1.0) { + world.flipped = match rand::rng().random_range(0.0..1.0) { p if p < 0.2 => "edge", p if p < 0.5 => "heads", _ => "tails", @@ -98,7 +98,7 @@ async fn never_lands(_: &mut FlipWorld) { ``` ![record](../rec/writing_retries.gif) -> __NOTE__: On failure, the whole [scenario] is re-executed with a new fresh [`World`] instance. +> __NOTE__: On failure, the whole [scenario] is re-executed with a new fresh [`World`] instance. @@ -112,7 +112,7 @@ The following [CLI option]s are related to the [scenario] retries: --retry-after Delay between each scenario retry attempt. - + Duration is represented in a human-readable format like `12min5s`. Supported suffixes: - `nsec`, `ns` — nanoseconds.