Skip to content

Conversation

@tom025
Copy link
Member

@tom025 tom025 commented Jan 17, 2014

Closes #50.

This adds a TagCounter that counts the tags associated with a test step and
the location of the test step.

TagLimits can be constructed from a list of filter expressions then used to
enforce the limits defined in the filter expressiont by passing a TagCounter
to TagLimits#enforce.

A TagExcess will be raised if any breaches of the limts are found.

Closes #50.

This adds a `TagCounter` that counts the tags associated with a test step and
the location of the test step.

`TagLimits` can be constructed from a list of filter expressions then used to
enforce the limits defined in the filter expressiont by passing a `TagCounter`
to `TagLimits#enforce`.

A `TagExcess` will be raised if any breaches of the limts are found.
tom025 added a commit to cucumber/cucumber-ruby that referenced this pull request Jan 17, 2014
Copy link
Member

Choose a reason for hiding this comment

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

limit_breaches.any? would read better here, IMO

Copy link
Member

Choose a reason for hiding this comment

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

Is filter_expression we use in initializer is Gherkin teg expression? If so it aleady has both tags and limits and we do not have to re-perse it here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the feedback @os97673!

I was unaware of the Gherkin::TagExpression class.

I will update this to use the Gherkin::TagExpression. While I am at it, is it worthwhile putting the code for enforcing the tag limits into the Gherkin::TagExpression?

Copy link
Member

Choose a reason for hiding this comment

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

As far as I understand Gherkin::TagExpression is not supposed to be used to keep runtime information :(
So, it can not enforce tag limits itself.
Also it would be a pain to release one more version of gherkin :)

Copy link
Member

Choose a reason for hiding this comment

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

Please bear in mind #20. I'd like to add as few couplings to Gherkin as possible from cucumber-core as it's likely to be changed significantly in the future. The Gherkin::TagExpression class is useful for evaluating complex boolean expressions, but do we do that in tag filters? Seems like a not operator is about as complex as it gets. Might not be worth adding the dependency.

Copy link
Member

Choose a reason for hiding this comment

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

I agree that we should avoid dependency on Gherkin, but either Gherkin or bool will always have something to represent tag expression and I se no point to duplicate parsing code here. Perhaps we should just pass all necessary information instead of parsing text again.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that Gherkin::TagExpression has too many responsibilities. As far as I can tell it

  1. Parses raw tag expressions into a collection representing a boolean expression

  2. Evaluates the expression for tags passed in. (Used for deciding if a test case should be run or not)

  3. Parses raw tag expressions into a list of tag names with limits. (Used for enforcing limits).

I think the tags with limits are a separate concern from evaluating a boolean expression and we should not mix those concepts, even if we are parsing the filter expressions twice.

It looks like we want to use bool for the evaluation of boolean expressions anyway so we may want to deprecate Gherkin::TagExpression all together as it is not used in cucumber anymore and only used in one place for cucumber-ruby-core.

Copy link
Member

Choose a reason for hiding this comment

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

On 19 Jan 2014, at 19:44, Thomas Brand notifications@github.com wrote:

I think the tags with limits are a separate concern from evaluating a boolean expression and we should not mix those concepts, even if we are parsing the filter expressions twice.

I agree.

@aslakhellesoy
Copy link
Contributor

I don't think tag limits should be added to Cucumber core. I asked on the list a few months ago[1], and it seems very few people are using it. It makes much more sense to be a plugin.

I also think we should start using bool[2] to parse boolean expressions. That would allow us to get rid of the ridiculous mechanism we have now for logical and/or, which nobody seems to understand. It's released as a gem[3].

[1] https://groups.google.com/d/msg/cukes/9mRU6N88XUg/-cuI4i38qFYJ
[2] https://github.com/cucumber/bool
[3] http://rubygems.org/gems/bool

@tom025
Copy link
Member Author

tom025 commented Jan 20, 2014

As we are trying to be compatible with cucumber 1.3 we need to support tag limits somewhere in the various codebases and the easiest place is in cucumber-core IMO. I think it makes sense to support tag limits in cucumber core as a stop gap then get rid of it for cucumber 3.0 and maybe develop a plugin for backwards compatibility if there is a pressing need for it.

@mattwynne
Copy link
Member

Agreed Tom. Let's minimise the noise and disruption for 2.0, but let's keep the code clearly separated so we're ready to ditch tag limits and switch to bool ASAP.

@tom025
Copy link
Member Author

tom025 commented Jan 20, 2014

BTW going through the various pieces of code that were historically involved in tag limits I think this PR is not 100% compatible with cucumber 1.3 as it doesn't take into account expressions like --tags '@one:1,@two:2' so I don't think this PR should be merged just yet.

There are also some names that I don't think make sense like TagCounter actually accumulates TestCases. I think this should be renamed to TestCases or TestCaseList.

I think I know enough about bool and test case matching to have a go at integrating bool into cucumber-core. I can do that as the next thing I work on.

@tom025
Copy link
Member Author

tom025 commented Jan 20, 2014

I think that this now ready to merge if everyone else agrees?

@os97673
Copy link
Member

os97673 commented Jan 21, 2014

Looks fine for me.

@aslakhellesoy
Copy link
Contributor

FWIW, Bool will also have to be integrated into Gherkin itself, since Gherkin uses tags for filtering features/scenarios. (Cucumber uses tags to match hooks).

Copy link
Member

Choose a reason for hiding this comment

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

I think it would be better style to use update inside the reduce block, or each_with_object instead of reduce here, so we don't have the bare limit_list returned from the block.

e.g.

reduce({}) do |limit_list, matchdata|
  limit_list.update(matchdata[:tag_name] => Integer(matchdata[:limit]))
end

or

each_with_object({}) do |limit_list, matchdata|
  limit_list[matchdata[:tag_name]] = Integer(matchdata[:limit])
end

/picky

@mattwynne
Copy link
Member

On 21 Jan 2014, at 05:20, Aslak Hellesøy notifications@github.com wrote:

FWIW, Bool will also have to be integrated into Gherkin itself, since Gherkin uses tags for filtering features/scenarios. (Cucumber uses tags to match hooks).

At the moment, we're no longer using Gherkin for that in 2.0. We're parsing everything, compiling it all into test-cases and then filtering the test-cases. This may turn out to be a mistake from a performance point of view, but I wanted to try and reduce the coupling to Gherkin. We can easily switch back to using parser-based filtering if it turns out to be slow.

Used `each_with_object` to keep the `[]=` semantics.
tooky added a commit that referenced this pull request Jan 27, 2014
Implement tag filtering with limits
@tooky tooky merged commit 26c57a4 into master Jan 27, 2014
@tooky tooky deleted the 50-tag-limits branch January 27, 2014 09:07
Copy link
Contributor

Choose a reason for hiding this comment

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

This will raise the TagExcess exception only after running all the scenarios. The current version of cucumber raises the exception before running any scenarios which I think is the desired behavior?

Since parsing, compilation, and execution are part of the same chain, replicating the existing behavior seems a bit complex at least to a cucumber codebase n00b. Also possible I'm completely missing something.

When I was looking into it I contemplated an extra parsing pass outside of core but that seemed a bit gnarly.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for bringing this up @pdswan!

You are correct that the current version of cucumber will raise an error before it starts running the scenarios. @mattwynne and I found this bug last night when pairing on this.

A issue needs to be raised for this. I am not sure how to fix this issue at the moment as I don't have a complete understanding of the new execution model. Perhaps @mattwynne and @tooky can provide some guidance for this issue.

It is also worth noting that @mattwynne and I have decided to move all of the code that parses to raw filter expressions to the main cucumber code base and pass in the tag limits and tag filters into cucumber-core at execution time. See #53.

Copy link
Member Author

Choose a reason for hiding this comment

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

See #54.

@lock
Copy link

lock bot commented Oct 25, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Oct 25, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tag limits

6 participants