-
-
Notifications
You must be signed in to change notification settings - Fork 8
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
[DRAFT]Handling error response when a comma is present in the operand name of tags #107
Open
shivam-sehgal
wants to merge
10
commits into
cucumber:main
Choose a base branch
from
shivam-sehgal:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 6 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
ffda0cd
to handle tags cases like @step1,@step2
04af03e
review comments regarding method naming and messages
d54c62e
review comments regarding adding unit tests
09819cf
testing ruby and some unit test changes
2486b55
testing ruby and some unit test changes
1183630
changing for ruby
2665a56
javascript changes
78b460d
perl changes
e7198f0
go changes
fae80c3
python changes
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,59 @@ | ||
- expression: 'not x' | ||
- expression: 'not @x' | ||
tests: | ||
- variables: ['x'] | ||
- variables: ['@x'] | ||
result: false | ||
- variables: ['y'] | ||
- variables: ['@y'] | ||
result: true | ||
- expression: 'x and y' | ||
- expression: '@x and @y' | ||
tests: | ||
- variables: ['x', 'y'] | ||
- variables: ['@x', '@y'] | ||
result: true | ||
- variables: ['x'] | ||
- variables: ['@x'] | ||
result: false | ||
- variables: ['y'] | ||
- variables: ['@y'] | ||
result: false | ||
|
||
- expression: 'x or y' | ||
- expression: '@x or @y' | ||
tests: | ||
- variables: [] | ||
result: false | ||
- variables: ['x', 'y'] | ||
- variables: ['@x', '@y'] | ||
result: true | ||
- variables: ['x'] | ||
- variables: ['@x'] | ||
result: true | ||
- variables: ['y'] | ||
- variables: ['@y'] | ||
result: true | ||
- expression: 'x\(1\) or y\(2\)' | ||
- expression: '@x\(1\) or @y\(2\)' | ||
tests: | ||
- variables: ['x(1)'] | ||
- variables: ['@x(1)'] | ||
result: true | ||
- variables: ['y(2)'] | ||
- variables: ['@y(2)'] | ||
result: true | ||
- expression: 'x\\ or y\\\) or z\\' | ||
- expression: '@x\\ or @y\\\) or @z\\' | ||
tests: | ||
- variables: ['x\'] | ||
- variables: ['@x\'] | ||
result: true | ||
- variables: ['y\)'] | ||
- variables: ['@y\)'] | ||
result: true | ||
- variables: ['z\'] | ||
- variables: ['@z\'] | ||
result: true | ||
- variables: ['x'] | ||
- variables: ['@x'] | ||
result: false | ||
- variables: ['y)'] | ||
- variables: ['@y)'] | ||
result: false | ||
- variables: ['z'] | ||
- variables: ['@z'] | ||
result: false | ||
- expression: '\\x or y\\ or z\\' | ||
- expression: '@\\x or @y\\ or @z\\' | ||
tests: | ||
- variables: ['\x'] | ||
- variables: ['@\x'] | ||
result: true | ||
- variables: ['y\'] | ||
- variables: ['@y\'] | ||
result: true | ||
- variables: ['z\'] | ||
- variables: ['@z\'] | ||
result: true | ||
- variables: ['x'] | ||
- variables: ['@x'] | ||
result: false | ||
- variables: ['y'] | ||
- variables: ['@y'] | ||
result: false | ||
- variables: ['z'] | ||
- variables: ['@z'] | ||
result: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,46 @@ | ||
- expression: '' | ||
formatted: 'true' | ||
- expression: 'a and b' | ||
formatted: '( a and b )' | ||
- expression: 'a or b' | ||
formatted: '( a or b )' | ||
- expression: 'not a' | ||
formatted: 'not ( a )' | ||
- expression: 'a and b and c' | ||
formatted: '( ( a and b ) and c )' | ||
- expression: '( a and b ) or ( c and d )' | ||
formatted: '( ( a and b ) or ( c and d ) )' | ||
- expression: 'not a or b and not c or not d or e and f' | ||
formatted: '( ( ( not ( a ) or ( b and not ( c ) ) ) or not ( d ) ) or ( e and f ) )' | ||
- expression: 'not a\(\) or b and not c or not d or e and f' | ||
formatted: '( ( ( not ( a\(\) ) or ( b and not ( c ) ) ) or not ( d ) ) or ( e and f ) )' | ||
- expression: '@a and @b' | ||
formatted: '( @a and @b )' | ||
- expression: '@a or @b' | ||
formatted: '( @a or @b )' | ||
- expression: 'not @a' | ||
formatted: 'not ( @a )' | ||
- expression: '@a and @b and @c' | ||
formatted: '( ( @a and @b ) and @c )' | ||
- expression: '( @a and @b ) or ( @c and @d )' | ||
formatted: '( ( @a and @b ) or ( @c and @d ) )' | ||
- expression: 'not @a or @b and not @c or not @d or @e and @f' | ||
formatted: '( ( ( not ( @a ) or ( @b and not ( @c ) ) ) or not ( @d ) ) or ( @e and @f ) )' | ||
- expression: 'not @a\(\) or @b and not @c or not @d or @e and @f' | ||
formatted: '( ( ( not ( @a\(\) ) or ( @b and not ( @c ) ) ) or not ( @d ) ) or ( @e and @f ) )' | ||
|
||
- expression: 'not (a and b)' | ||
formatted: 'not ( a and b )' | ||
- expression: 'not (a or b)' | ||
formatted: 'not ( a or b )' | ||
- expression: 'not (a and b) and c or not (d or f)' | ||
formatted: '( ( not ( a and b ) and c ) or not ( d or f ) )' | ||
- expression: 'not (@a and @b)' | ||
formatted: 'not ( @a and @b )' | ||
- expression: 'not (@a or @b)' | ||
formatted: 'not ( @a or @b )' | ||
- expression: 'not (@a and @b) and @c or not (@d or @f)' | ||
formatted: '( ( not ( @a and @b ) and @c ) or not ( @d or @f ) )' | ||
|
||
- expression: 'a\\ and b' | ||
formatted: '( a\\ and b )' | ||
- expression: '\\a and b' | ||
formatted: '( \\a and b )' | ||
- expression: 'a\\ and b' | ||
formatted: '( a\\ and b )' | ||
- expression: 'a and b\\' | ||
formatted: '( a and b\\ )' | ||
- expression: '( a and b\\\\)' | ||
formatted: '( a and b\\\\ )' | ||
- expression: 'a\\\( and b\\\)' | ||
formatted: '( a\\\( and b\\\) )' | ||
- expression: '(a and \\b)' | ||
formatted: '( a and \\b )' | ||
- expression: 'x or(y) ' | ||
formatted: '( x or y )' | ||
- expression: 'x\(1\) or(y\(2\))' | ||
formatted: '( x\(1\) or y\(2\) )' | ||
- expression: '\\x or y\\ or z\\' | ||
formatted: '( ( \\x or y\\ ) or z\\ )' | ||
- expression: 'x\\ or(y\\\)) or(z\\)' | ||
formatted: '( ( x\\ or y\\\) ) or z\\ )' | ||
- expression: 'x\ or y' | ||
formatted: '( x\ or y )' | ||
- expression: '@a\\ and @b' | ||
formatted: '( @a\\ and @b )' | ||
- expression: '@\\a and @b' | ||
formatted: '( @\\a and @b )' | ||
- expression: '@a\\ and @b' | ||
formatted: '( @a\\ and @b )' | ||
- expression: '@a and @b\\' | ||
formatted: '( @a and @b\\ )' | ||
- expression: '( @a and @b\\\\)' | ||
formatted: '( @a and @b\\\\ )' | ||
- expression: '@a\\\( and @b\\\)' | ||
formatted: '( @a\\\( and @b\\\) )' | ||
- expression: '(@a and @\\b)' | ||
formatted: '( @a and @\\b )' | ||
- expression: '@x or(@y) ' | ||
formatted: '( @x or @y )' | ||
- expression: '@x\(1\) or(@y\(2\))' | ||
formatted: '( @x\(1\) or @y\(2\) )' | ||
- expression: '@\\x or @y\\ or @z\\' | ||
formatted: '( ( @\\x or @y\\ ) or @z\\ )' | ||
- expression: '@x\\ or(@y\\\)) or(@z\\)' | ||
formatted: '( ( @x\\ or @y\\\) ) or @z\\ )' | ||
- expression: '@x\ or @y' | ||
formatted: '( @x\ or @y )' |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By trying to validate all tokens rather than the litterals you are making this more complex than needed. Considering that this implementation will have to be repeated for a few languages, perhaps a review in the middle of just the Java implementation can save some duplication of effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @mpkorstanje, for your reply
I assume that a tag expression consists of operands and operators. When splitting the expression, there are two possibilities. The current token or string could be an operator, which includes "(", ")", "and", "or", and "not". Alternatively, it could be an operand, which should adhere to the Gherkin standard of starting with "@" and not containing "@" anywhere else.
To handle this, I have used a regex pattern to ensure that only valid tokens, which form the expression, are evaluated. By considering both operands and operators, it simplifies the code and eliminates the need for additional checks to determine the token type.
I believed this approach reduces complexity and improves the readability of the code, but maybe I might be missing someting, I would appreciate your opinion on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, actually the situation is slightly different (as you can see from the tests / testdata):
@foo
(with-leading-atsign) orfoo
(without-leading-atsign)@
(atsign) should not occur in a tag (after the first char) in a tag-expression@
(atsign) from tags for Features/Rules/Scenarios/… . Therefore,@foo
becomes“foo“
internallySEE ALSO:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenisys are you sure about that? Or is that true only for some Gherkin parsers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shivam-sehgal without repeating myself that will be a bit difficult.
But do consider validating only the litterals. In essence, do not put the validation in the middle of tokenizer but rather after tokenization, just prior to litteral creation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpkorstanje cucumber-jvm basically calls this library to parse the tag expression as well as to validate if the tag expression is valid or not so the flow is like this in cucmberOptions annotation user provides the tags expression shown in the below code
this annotation is parsed by CucumberOptionsAnnotationParser.class.
addTags method in this class is called which then calls this repo to validate the tag expression, now the intent of this PR was users by mistake put tag expressions like @tag1,@tag2 in the tags section in the CucumberOptions, and they don't get any error message, to avoid that we need to validate the tag expression not having any tags or literals like
@tag,@againInTag
to prevent this confusion and give users a valid error response so they can understand that they need to use logical operator, instead of commas, I can put this tag validation for the provided tag expression in addTags method of the CucumberOptionsAnnotationParser clas i.e in cucumber jvm, but my mind says it's better to keep validation logic inside this tag expression validation repo only to follow the single responsibility principle of oops,to address this concern with the least impacting change, for now, I see if there is an expression having a tag starting with
@
that tag shouldn't have@
after first, it will prevent this confusion with a proper error message letting user understand that they are doing mistake and cucumber is reading their expression as a single tag, and also won't affect any case where we allow the literals that are not starting with@
In short, cucumber-jvm calls this repo to validate the tag expression passed by the user and uses a message from
TagExpressionException
to let the user know with a message what is wrong with the expression, the message should be coming from here i.e from this repo's java directory, else the responsibility of this code we have to handle separately in cucumber-jvm.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One solution approach could be:
CucumberOptions
had an optional parameter, liketag_expression_validator
,tag_expression_parser
or antag-expression preprocess hook
you could perform a pre-process checktag-expression
string value into words and check ifcomma
(s) are contained in any wordcomma
is contained, you issue a log-warning or raise an exception (whatever the „right“ consequent action is), …This approach would have the following advantages:
tag-expressions
, you can plug-in the functionalityHINT:
By looking at the current implementation of the
CucumberOptions
class, this neededparameter
would need to be added to support such a kind of solution.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jenisys, I find the approach of using an optional flag for literal validation quite appealing. However, I have some doubts about the term "strict checking." If libraries using this repository are enforcing Gherkins rules, then it seems reasonable for this library to do the same. However, if we believe and would like to continue supporting users who define literals not starting with
@
in new versions, then the optional parameter approach makes sense.One potential concern raised by @mpkorstanje is that checking for commas alone may cause issues. To differentiate between v1 and v2, perhaps we should consider checking for
^@[^@]+
which he mentioned if the optional strict validation flag is passed inCucumberOptions
.I would appreciate hearing both of your opinions on this matter. Let's collaborate and I can begin working on it.
cc: @mpkorstanje
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the cost of the complexity is starting to exceed the value of the solution.
Perhaps a simpler solution such as improving the documentation in Cucumber JVM might help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @mpkorstanje for your advice, have opened a pull request to update the doc a little bit, to add info for users to avoid the confusion of separating tags using
,
, attaching the screenshot of the doc changes belowwould like to request your review of this PR .
Thanks in advance