Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor housekeeping work #310

Merged
merged 7 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 44 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@ repository = "https://github.com/cucumber-rs/cucumber"
readme = "README.md"
categories = ["asynchronous", "development-tools::testing"]
keywords = ["cucumber", "testing", "bdd", "atdd", "async"]
include = ["/src/", "/tests/json.rs", "/tests/junit.rs", "/tests/libtest.rs", "/tests/tracing.rs", "/tests/wait.rs", "/LICENSE-*", "/README.md", "/CHANGELOG.md"]
include = [
"/src/",
"/tests/json.rs",
"/tests/junit.rs",
"/tests/libtest.rs",
"/tests/tracing.rs",
"/tests/wait.rs",
"/LICENSE-*",
"/README.md",
"/CHANGELOG.md",
]

[package.metadata.docs.rs]
all-features = true
Expand All @@ -30,9 +40,21 @@ default = ["macros"]
# Enables compatibility with Rust libtest (like outputting in its JSON format).
libtest = ["dep:serde", "dep:serde_json", "timestamps"]
# Enables step attributes and auto-wiring.
macros = ["dep:anyhow", "dep:cucumber-codegen", "dep:cucumber-expressions", "dep:inventory"]
macros = [
"dep:anyhow",
"dep:cucumber-codegen",
"dep:cucumber-expressions",
"dep:inventory",
]
# Enables support for outputting in Cucumber JSON format.
output-json = ["dep:base64", "dep:Inflector", "dep:mime", "dep:serde", "dep:serde_json", "timestamps"]
output-json = [
"dep:base64",
"dep:Inflector",
"dep:mime",
"dep:serde",
"dep:serde_json",
"timestamps",
]
# Enables support for outputting JUnit XML report.
output-junit = ["dep:junit-report", "timestamps"]
# Enables timestamps collecting for all events.
Expand All @@ -44,7 +66,16 @@ tracing = ["dep:crossbeam-utils", "dep:tracing", "dep:tracing-subscriber"]
async-trait = "0.1.43"
clap = { version = "4.3.2", features = ["derive", "wrap_help"] }
console = "0.15"
derive_more = { version = "0.99.17", features = ["as_ref", "deref", "deref_mut", "display", "error", "from", "from_str", "into"], default_features = false }
derive_more = { version = "0.99.17", features = [
"as_ref",
"deref",
"deref_mut",
"display",
"error",
"from",
"from_str",
"into",
], default_features = false }
drain_filter_polyfill = "0.1.2"
either = "1.6"
futures = "0.3.17"
Expand All @@ -63,7 +94,9 @@ smart-default = "0.7.1"
# "macros" feature dependencies.
anyhow = { version = "1.0.58", optional = true }
cucumber-codegen = { version = "0.20.1", path = "./codegen", optional = true }
cucumber-expressions = { version = "0.3", features = ["into-regex"], optional = true }
cucumber-expressions = { version = "0.3", features = [
"into-regex",
], optional = true }
inventory = { version = "0.3", optional = true }

# "output-json" and/or "libtest" features dependencies.
Expand All @@ -85,7 +118,12 @@ tracing-subscriber = { version = "0.3.16", optional = true }
derive_more = "0.99.17"
rand = "0.8"
tempfile = "3.2"
tokio = { version = "1.12", features = ["macros", "rt-multi-thread", "sync", "time"] }
tokio = { version = "1.12", features = [
"macros",
"rt-multi-thread",
"sync",
"time",
] }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barafael I've found it more comfortable to keep each dependency as a single line in [dependencies] section.


[[test]]
name = "json"
Expand Down
12 changes: 6 additions & 6 deletions codegen/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct Step {
/// reference.
///
/// [`gherkin::Step`]: https://bit.ly/3j42hcd
step_arg_name: Option<syn::Ident>,
arg_name: Option<syn::Ident>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barafael step_ prefix was referring to a gherkin::Step here, rather than this struct itself.

}

impl Step {
Expand Down Expand Up @@ -97,7 +97,7 @@ impl Step {
attr_name,
attr_arg,
func,
step_arg_name,
arg_name: step_arg_name,
})
}

Expand Down Expand Up @@ -274,7 +274,7 @@ impl Step {

Ok((func_args, addon_parsing))
}
} else if self.step_arg_name.is_some() {
} else if self.arg_name.is_some() {
Ok((
quote! { ::std::borrow::Borrow::borrow(&__cucumber_ctx.step), },
None,
Expand Down Expand Up @@ -304,7 +304,7 @@ impl Step {
let (ident, ty) = parse_fn_arg(arg)?;

let is_ctx_arg =
self.step_arg_name.as_ref().map(|i| *i == *ident) == Some(true);
self.arg_name.as_ref().map(|i| *i == *ident) == Some(true);

let decl = if is_ctx_arg {
quote! {
Expand Down Expand Up @@ -385,7 +385,7 @@ impl Step {
&self,
arg: &syn::FnArg,
) -> syn::Result<TokenStream> {
if let Some(name) = &self.step_arg_name {
if let Some(name) = &self.arg_name {
let (ident, _) = parse_fn_arg(arg)?;
if name == ident {
return Ok(quote! {
Expand Down Expand Up @@ -444,7 +444,7 @@ impl Step {
) -> syn::Result<TokenStream> {
let expr = expr.value();
let params =
Parameters::new(&expr, &self.func, self.step_arg_name.as_ref())?;
Parameters::new(&expr, &self.func, self.arg_name.as_ref())?;

let provider_impl =
params.gen_provider_impl(&parse_quote! { Provider });
Expand Down
2 changes: 1 addition & 1 deletion src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub struct Event<T: ?Sized> {
impl<T> Event<T> {
/// Creates a new [`Event`] out of the given `value`.
#[must_use]
pub fn new(value: T) -> Self {
pub const fn new(value: T) -> Self {
Self {
#[cfg(feature = "timestamps")]
at: SystemTime::now(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barafael this won't compile with --feature timestamps:

error[E0015]: cannot call non-const fn `std::time::SystemTime::now` in constant functions
  --> src/event.rs:60:17
   |
60 |             at: SystemTime::now(),
   |                 ^^^^^^^^^^^^^^^^^
   |
   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

Expand Down
8 changes: 4 additions & 4 deletions src/runner/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ async fn execute<W, Before, After>(
}
}
#[cfg(not(feature = "tracing"))]
let _ = id;
let _: ScenarioId = id;

if fail_fast && scenario_failed && !retried {
started_scenarios = ControlFlow::Break(());
Expand Down Expand Up @@ -1485,7 +1485,7 @@ where
(fut, span_id)
};
#[cfg(not(feature = "tracing"))]
let _ = scenario_id;
let _: ScenarioId = scenario_id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barafael I would prefer _ = scenario_id;, but yes:

error[E0658]: attributes on expressions are experimental
    --> src/runner/basic.rs:1076:13
     |
1076 |             #[cfg(not(feature = "tracing"))]
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information


let result = fut.then_yield().await;

Expand Down Expand Up @@ -1606,7 +1606,7 @@ where
waiter.wait_for_span_close(id).then_yield().await;
}
#[cfg(not(feature = "tracing"))]
let _ = scenario_id;
let _: ScenarioId = scenario_id;

match result {
Ok((Some(captures), loc, Some(world))) => {
Expand Down Expand Up @@ -1762,7 +1762,7 @@ where
(fut, span_id)
};
#[cfg(not(feature = "tracing"))]
let _ = scenario_id;
let _: ScenarioId = scenario_id;

let res = fut.then_yield().await;

Expand Down
32 changes: 16 additions & 16 deletions src/writer/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl<Writer> Normalized for AssertNormalized<Writer> {}
#[derive(Clone, Debug)]
struct Queue<K: Eq + Hash, V> {
/// Underlying FIFO queue of values.
queue: LinkedHashMap<K, V>,
fifo: LinkedHashMap<K, V>,

/// Initial [`Metadata`] of this [`Queue`] creation.
///
Expand All @@ -363,7 +363,7 @@ impl<K: Eq + Hash, V> Queue<K, V> {
/// Creates a new normalization [`Queue`] with an initial metadata.
fn new(initial: Metadata) -> Self {
Self {
queue: LinkedHashMap::new(),
fifo: LinkedHashMap::new(),
initial: Some(initial),
state: FinishedState::NotFinished,
}
Expand All @@ -385,7 +385,7 @@ impl<K: Eq + Hash, V> Queue<K, V> {

/// Removes the given `key` from this [`Queue`].
fn remove(&mut self, key: &K) {
drop(self.queue.remove(key));
drop(self.fifo.remove(key));
}
}

Expand Down Expand Up @@ -489,7 +489,7 @@ impl<World> CucumberQueue<World> {
/// [`Feature`]: gherkin::Feature
fn new_feature(&mut self, feat: Event<Arc<gherkin::Feature>>) {
let (feat, meta) = feat.split();
drop(self.queue.insert(feat, FeatureQueue::new(meta)));
drop(self.fifo.insert(feat, FeatureQueue::new(meta)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@barafael not a fan of this particular change. It's more meaningful to emphasize we're queuing something here, rather than bothering reader with exact semantics of the queue, which is "implementation detail".

}

/// Marks a [`Feature`] as finished on [`event::Feature::Finished`].
Expand All @@ -500,7 +500,7 @@ impl<World> CucumberQueue<World> {
/// [`Feature`]: gherkin::Feature
fn feature_finished(&mut self, feat: Event<&gherkin::Feature>) {
let (feat, meta) = feat.split();
self.queue
self.fifo
.get_mut(feat)
.unwrap_or_else(|| panic!("No Feature {}", feat.name))
.finished(meta);
Expand All @@ -514,7 +514,7 @@ impl<World> CucumberQueue<World> {
feat: &gherkin::Feature,
rule: Event<Arc<gherkin::Rule>>,
) {
self.queue
self.fifo
.get_mut(feat)
.unwrap_or_else(|| panic!("No Feature {}", feat.name))
.new_rule(rule);
Expand All @@ -531,7 +531,7 @@ impl<World> CucumberQueue<World> {
feat: &gherkin::Feature,
rule: Event<Arc<gherkin::Rule>>,
) {
self.queue
self.fifo
.get_mut(feat)
.unwrap_or_else(|| panic!("No Feature {}", feat.name))
.rule_finished(rule);
Expand All @@ -545,7 +545,7 @@ impl<World> CucumberQueue<World> {
scenario: Arc<gherkin::Scenario>,
event: Event<event::RetryableScenario<World>>,
) {
self.queue
self.fifo
.get_mut(feat)
.unwrap_or_else(|| panic!("No Feature {}", feat.name))
.insert_scenario_event(rule, scenario, event.retries, event);
Expand All @@ -559,7 +559,7 @@ impl<'me, World> Emitter<World> for &'me mut CucumberQueue<World> {
type EmittedPath = ();

fn current_item(self) -> Option<Self::Current> {
self.queue
self.fifo
.iter_mut()
.next()
.map(|(f, ev)| (Arc::clone(f), ev))
Expand Down Expand Up @@ -641,7 +641,7 @@ impl<World> FeatureQueue<World> {
fn new_rule(&mut self, rule: Event<Arc<gherkin::Rule>>) {
let (rule, meta) = rule.split();
drop(
self.queue.insert(
self.fifo.insert(
Either::Left(rule),
Either::Left(RulesQueue::new(meta)),
),
Expand All @@ -653,7 +653,7 @@ impl<World> FeatureQueue<World> {
/// [`Rule`]: gherkin::Rule
fn rule_finished(&mut self, rule: Event<Arc<gherkin::Rule>>) {
let (rule, meta) = rule.split();
match self.queue.get_mut(&Either::Left(rule)) {
match self.fifo.get_mut(&Either::Left(rule)) {
Some(Either::Left(ev)) => {
ev.finished(meta);
}
Expand All @@ -673,12 +673,12 @@ impl<World> FeatureQueue<World> {
) {
if let Some(r) = rule {
match self
.queue
.fifo
.get_mut(&Either::Left(Arc::clone(&r)))
.unwrap_or_else(|| panic!("No Rule {}", r.name))
{
Either::Left(rules) => rules
.queue
.fifo
.entry((scenario, retries))
.or_insert_with(ScenariosQueue::new)
.0
Expand All @@ -687,7 +687,7 @@ impl<World> FeatureQueue<World> {
}
} else {
match self
.queue
.fifo
.entry(Either::Right((scenario, retries)))
.or_insert_with(|| Either::Right(ScenariosQueue::new()))
{
Expand All @@ -705,7 +705,7 @@ impl<'me, World> Emitter<World> for &'me mut FeatureQueue<World> {
type EmittedPath = Arc<gherkin::Feature>;

fn current_item(self) -> Option<Self::Current> {
Some(match self.queue.iter_mut().next()? {
Some(match self.fifo.iter_mut().next()? {
(Either::Left(rule), Either::Left(events)) => {
Either::Left((Arc::clone(rule), events))
}
Expand Down Expand Up @@ -748,7 +748,7 @@ impl<'me, World> Emitter<World> for &'me mut RulesQueue<World> {
type EmittedPath = (Arc<gherkin::Feature>, Arc<gherkin::Rule>);

fn current_item(self) -> Option<Self::Current> {
self.queue
self.fifo
.iter_mut()
.next()
.map(|((sc, _), ev)| (Arc::clone(sc), ev))
Expand Down
2 changes: 1 addition & 1 deletion src/writer/summarize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ impl<Writer> Summarize<Writer> {
/// // `Writer`s pipeline is constructed in a reversed order.
/// writer::Basic::stdout() // And, finally, print them.
/// .summarized() // Only then, count summary for them.
/// .fail_on_skipped() // First, transform skipped steps to failed.
/// .fail_on_skipped(), // First, transform skipped steps to failed.
/// )
/// .run_and_exit("tests/features/readme")
/// .await;
Expand Down