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

Expand Docstrings and names in Scenario Outline (#172) #178

Merged
merged 4 commits into from
Dec 7, 2021
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ All user visible changes to `cucumber` crate will be documented in this file. Th

- Template regex in `Scenario Outline` expansion from `<(\S+)>` to `<([^>\s]+)>`. ([#163])
- Multiple `Examples` in `Scenario Outline`. ([#165], [#164])
- Docstring and name expansion in `Scenario Outline`. ([#178], [#172])

[#147]: /../../pull/147
[#151]: /../../pull/151
Expand All @@ -51,6 +52,8 @@ All user visible changes to `cucumber` crate will be documented in this file. Th
[#165]: /../../pull/165
[#166]: /../../pull/166
[#168]: /../../pull/168
[#172]: /../../pull/172
[#178]: /../../pull/178
[cef3d480]: /../../commit/cef3d480579190425461ddb04a1248675248351e
[rev]: /../../commit/rev-full
[0110-1]: https://llg.cubic.org/docs/junit
Expand Down
7 changes: 3 additions & 4 deletions codegen/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,8 @@ impl<'p> Parameters<'p> {
// In case we encounter default parameter, we should
// assert that corresponding argument's type __doesn't__
// implement a `Parameter` trait.
// TODO: try to use autoderef-based specialization with
// readable assertion message.
#[automatically_derived]
const _: fn() = || {
// Generic trait with a blanket impl over `()` for
Expand Down Expand Up @@ -589,10 +591,7 @@ impl<'p> Parameters<'p> {
// In case we encounter a custom parameter, we should
// assert that the corresponding type implements
// `Parameter` and has correct `Parameter::NAME`.
// TODO: Panic here, once `const_panic` is stabilized.
// https://github.com/rust-lang/rust/pull/89508
#[automatically_derived]
const _: () = ::std::assert!(
Copy link
Member

@tyranron tyranron Dec 7, 2021

Choose a reason for hiding this comment

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

@ilslv by removing const context, don't we move this assertion to runtime?

The whole regex is used insize Lazy. I'd opt for having explicit const context here for avoiding possible accidentials.

Copy link
Member Author

Choose a reason for hiding this comment

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

@tyranron nice point, const should be left 👍

::std::assert!(
::cucumber::codegen::str_eq(
<#ty as ::cucumber::Parameter>::NAME,
#name,
Expand Down
51 changes: 28 additions & 23 deletions src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ fn expand_scenario(
.zip(iter::repeat((example.position, example.tags.iter())))
})
.map(|((id, row), (position, tags))| {
let replace = |str: &str, pos| {
let mut err = None;
let replaced = TEMPLATE_REGEX
.replace_all(str, |cap: &regex::Captures<'_>| {
let name = cap.get(1).unwrap().as_str();

row.clone()
.find_map(|(k, v)| (name == k).then(|| v.as_str()))
.unwrap_or_else(|| {
err = Some(ExpandExamplesError {
pos,
name: name.to_owned(),
path: path.cloned(),
});
""
})
})
.into_owned();

err.map_or_else(|| Ok(replaced), Err)
};

let mut modified = scenario.clone();

// This is done to differentiate `Hash`es of
Expand All @@ -152,8 +174,12 @@ fn expand_scenario(

modified.tags.extend(tags.cloned());

modified.name = replace(&modified.name, modified.position)?;

for s in &mut modified.steps {
let mut err = None;
if let Some(docstring) = &mut s.docstring {
*docstring = replace(docstring, s.position)?;
}

let to_replace = iter::once(&mut s.value).chain(
s.table.iter_mut().flat_map(|t| {
Expand All @@ -162,28 +188,7 @@ fn expand_scenario(
);

for value in to_replace {
*value = TEMPLATE_REGEX
.replace_all(value, |c: &regex::Captures<'_>| {
let name = c.get(1).unwrap().as_str();

row.clone()
.find_map(|(k, v)| {
(name == k).then(|| v.as_str())
})
.unwrap_or_else(|| {
err = Some(ExpandExamplesError {
pos: s.position,
name: name.to_owned(),
path: path.cloned(),
});
""
})
})
.into_owned();
}

if let Some(e) = err {
return Err(e);
*value = replace(value, s.position)?;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Feature: Outline
Background:
Given foo is 1

Scenario Outline: foo
Scenario Outline: foo <bar1>
Given foo is <bar1>
When foo is <bar2>
Then foo is <bar3>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Feature: Outline

Scenario Outline: foo
Given foo is <bar1>
When foo is <bar2>
"""
Nothing to replace here
"""
Then foo is <bar3>

Examples:
| bar1 | bar2 | bar3 |
| 0 | 1 | 2 |
Loading