-
-
Notifications
You must be signed in to change notification settings - Fork 616
Add possibility to use attributes for Context snippets #1549
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
Add possibility to use attributes for Context snippets #1549
Conversation
|
PR is in draft since I need to fix certain tests yet. But you can already review the code and let me know :) |
|
I would rather migrate to attributes directly, to avoid adding a new CLI flag and configuration setting that must then be covered by backward compatibility |
|
Okay, I'm agree with that. I was very conservative on this point, I see the problem with potentials BCs after. So I can switch to attributes by default of course, and update tests accordingly. |
8b3ad91 to
86929fb
Compare
|
@fmatsos yes, as we commented on the issue you linked, we prefer to just move to generating attributes directly. In the next days I plan to work on updating our documentation to use attributes and just mention annotations as an option that will be deprecated and dropped in the future |
86929fb to
33849c0
Compare
carlos-granados
left a comment
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.
Many thanks for this work @fmatsos There are a few changes needed, please see my comments
src/Behat/Behat/Context/Snippet/Generator/ContextSnippetGenerator.php
Outdated
Show resolved
Hide resolved
acoulton
left a comment
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.
As you will need to work on the feature files anyway to address @carlos-granados feedback, could I also please ask you to split your final commit test: update tests to check features in place of annotations into two:
- A first one that only updates the features / expectations that are to do with generating snippets, where the output has changed because of the code changes in this branch.
- A separate one (if you wish) to convert existing features to use attributes instead of annotations - these aren't strictly required for this PR and it would be easier to see the diff for the feature itself, and to see why the tests are now failing, if they were kept in a separate commit.
Thanks!
33849c0 to
26b5126
Compare
|
I've processed your feedbacks, and I've also made a few additional changes to add required uses for attributes. I've rollback the test updates to separate them into two commits as suggested by @acoulton. The next commit for tests, which will replace all annotations with attributes, will come when I've solved two remaining problems. I have two scenarios that no longer work (locally):. I'm looking why I get these errors now. Thanks again for your review! |
I finally found the problem. On some regex patterns, like |
acoulton
left a comment
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.
This is taking shape well.
How hard would it be to output the additional use statements when displaying the "define them with these snippets" message to the user? Or to generate (or convert) snippets for display as FQCN.
If not, could we add a generic "You may also need to add use statements for the Behat\Step\(Given/When/Then) attributes" that always appears?
I'm just thinking for things like PendingException/TableNode they will get a runtime error if the class isn't imported. But by design if an attribute is undefined/not imported it will just be ignored, which could cause confusion if the user copies and pastes the snippet without realising.
Tell me if I understand correctly @acoulton: you ask if it'll not be better to remove the use statements from snippets for attributes, and just display their FQCN (or generic message) to user instead? |
|
@fmatsos there are two cases where we use the snippets:
In the first case, the ideal would be that the use statements were added directly without user intervention. In the second case it would be good if we could print the use statements as part of the snippet output so that the user could also copy them I think that what @acoulton meant was that if these two options were not possible, we should look into using the FQN in the snippets, but only if we could not add the use statements as that is a better solution. @acoulton please confirm |
|
@fmatsos sorry that I wasn't clear. Yes, exactly as @carlos-granados says, in the second case where we display snippets for the user to add I think in order of preference:
|
|
Hi! I'm always stuck with this error: Occurred in files: I did some research, set-by-step debugging, and still not find how to fix it... |
|
I'll try to debug this later today |
|
I added a fix, you need to convert the |
|
Thanks a lot @carlos-granados! I began to be crazy about this lol |
|
One thing I've found that can be helpful with |
Nice to know this trick! FIY I'm on your request about use statements messages. Once it's done, this PR will be okay for final review. I'll do another PR to update the rest features from annotations to attributes (I think it'll be better for review and better to have two separate PRs for that) :) |
|
@fmatsos perfect, that sounds like a good plan. |
1541d9d to
8afa651
Compare
acoulton
left a comment
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 tiny fix, but otherwise this is looking great thank you 🎉
8afa651 to
010ba08
Compare
acoulton
left a comment
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.
Brilliant, thanks @fmatsos
|
Congratulations @fmatsos ;) This will be really great to use. |
carlos-granados
left a comment
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.
Great job overall @fmatsos, just a few small comments
src/Behat/Behat/Context/Snippet/Generator/FixedContextIdentifier.php
Outdated
Show resolved
Hide resolved
src/Behat/Behat/Context/Snippet/Generator/FixedPatternIdentifier.php
Outdated
Show resolved
Hide resolved
carlos-granados
left a comment
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.
All good now @fmatsos Do you think you might rebase it to the latest master? Also you may want to squash some of the commits
9479620 to
232d6c0
Compare
Signed-off-by: Franck Matsos <franck.matsos@akawaka.fr>
Signed-off-by: Franck Matsos <franck.matsos@akawaka.fr>
Signed-off-by: Franck Matsos <franck.matsos@akawaka.fr>
232d6c0 to
2fe75e8
Compare
|
Hi @carlos-granados! Have a good evening! |
| private function preparePattern(string $pattern): string | ||
| { | ||
| $pattern = str_replace('%', '%%', $pattern); | ||
| $pattern = str_replace('\\\\', '\\\\\\\\', $pattern); |
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.
instead of those replacements, I suggest removing the quotes from the template and using var_export() to make PHP generate the proper literal representation of the string with any needed escaping.
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.
You suggest something like that?
$pattern = str_replace('%', '%%', $pattern);
return var_export($pattern, true);4 tests from snippets.feature fail with this change, since some \ are now escaped too. I presume it's normal and expected.
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.
@fmatsos I'm guessing that is what @stof meant, it looks ok to me. Could you clarify about the tests - is it that snippets.feature is currently valid and using var_export gives the wrong result? Or is it that the current expectations in snippets.feature are not correctly escaped and using var_export fixes that? Thanks
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.
Of course! I'll test the final regex to check if new pattern is valid or not.
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.
Hi @stof
I deeply check your suggestion, but it seems I can't use var_export in this case. If I use it, I have \ from regex keywords that are escaped too. So the pattern is not valid anymore.
Example:
- expected:
#[Then('/^do something undefined with \\(\d+)$/')] - result:
#[Then('/^do something undefined with \\\\(\\d+)$/')]
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.
@fmatsos @stof I've finally had a chance to look at this (I wanted to make sure it wasn't masking a bigger issue about \ escaping) and I see the problem.
A \ only needs to be escaped before certain other characters (e.g. \n would need to be \\n) - if the following character is "safe" then a single \ is treated as a literal \.
So these two step definitions parse exactly the same (I've checked) and either would be valid:
#[Then('/I should have (\d+) apple(s)/')]
#[Then('/I should have (\\d+) apple(s)/')]Historically we have generated the first version - which I think is easier for the user to read, certainly once patterns get more complex.
But var_export plays it safe and always escapes a \ rather than checking the following character to see if that is strictly necessary.
I would usually prefer var_export for safety, but in this case I favour the current implementation (not using var_export) to generate simpler strings. These are only suggestions, and they're to be applied by developers : in the very rare edge case that we suggest an improperly-escaped snippet definition, the user can / will fix it when they add it to their Context.
| * @param string $contextClass | ||
| * | ||
| * @return string[] | ||
| * @return array<string, array<string, string> |
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.
This type is wrong. It does not return an array of arrays as it returns the proposed methods for a single context class. the proper return type is array<string, string>
Btw, the current annotation is even totally broken because it misses a > to be a valid type.
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.
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.
Yes, I already have the fix on a new branch with the next proposal ;)
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.
Since the var_export question is resolved, I've just pushed a fix for this in #1569
Fixes a typo that slipped in with Behat#1549 as per Behat#1549 (comment)
Description
An old issue (cf. #1379) proposed to generate snippets with attributes in place of annotations.
I worked on it last days and finally came up with a working solution.
Proposal
For now, I didn't switch all annotations to attributes.
I add a new CLI option to use attributes if we want, and an associated config key also.
So you can now do:
behat -f progress --no-colors --snippets-for=FeatureContext --snippets-use-attributesfor example.or add the new config key in
behat.ymlto use attributes by default:Although attributes are now widely supported, I think it's better to act in two phases: first, this PR, to implement attributes as an option. And later to invert and use attributes by default.