-
Notifications
You must be signed in to change notification settings - Fork 46
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
Fix for 81 - Cucumber Expression using Enums errors when two enums exist with the same short name #100
Fix for 81 - Cucumber Expression using Enums errors when two enums exist with the same short name #100
Conversation
…th the same short name exist as parameters to cucumber expressions. This fix causes the CucumberExpressionParameterTypeRegistry to use the FQN of the enum Types used as Cucumber Expression parameters.
@gasparnagy , this is regarding #81 . We discussed two possible sub-scenarios. This fix addresses the most immediate one (two enums that have the same short name but exist in different namespaces). |
@gasparnagy Argh. NM. Already see where this breaks everything. I'll rethink this. |
@clrudolphi Yes, unfortunately the problem is conceptual here. When I did the first version of CukeEx support, I had to solve somehow that enums work. Finally the workaround was to go through all possible parameter types and register them. But obviously this is not working if there is a name duplication... Maybe what we could do is the following: when we realize that there is a duplication (we are about to add one with a name, but the dictionary already has sg with the same name), we could replace the existing value with a "proxy". This proxy would "remember" (have a list) of all ambiguous types and if (and only if) someone would try to use it actually (i.e. use a placeholder like "... {Color} ...") we would throw an error, suggesting that this is ambiguous (write out the type names from its list) and if you want to use this enum, you need to create two StepArgumentTransformations and give them unique name (names are case sensitive). Note that @kipusoep was not actually using the registered name in #81, so in his case the "proxy" would never be actually used, so he would not see this error, but could just use the enums as he planned to. What do you think? |
Creating some kind of "aggregate" transformer is an interesting idea. How would we detect when a transform is actually ambiguous? It feels like a really clever result if Reqnroll can slip around the problem when it's just theoretical and only throw an exception when there is a practical problem. 👍 |
There is a point where we would register the name to a dictionary. Is somebody is already in it is ambiguous. |
Identifying colliding Enum shortnames at the time of discovery is difficult as the Dictionary is built Lazily. Instead, please review the latest change(cba2383). At execution time, if there is no match in the Dictionary based upon the name given, then I attempt to match enums just on short name (assuming that the Dict key values are FullNames of enum types). Then, if 1 match is found, return that; if more than 1, then we have an ambiguous situation. |
@clrudolphi good idea. I will check it. |
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!!! This is a good idea.
I also like the test. You can add another one that checks if the exception is thrown in case of ambiguity.
And the good thing is, that if you still want to use the enum by short name (for one of the types), you can create a [StepArgumentTransformation]
and that will register the trafo with the short name and therefore it will not run into the ambiguous lookup exception. So this will also fix your case as well, I think. We can maybe even add this hint to the exception message: [...] Use the enum's full name in the cucumber expression or define a [StepArgumentTransformation] with the chosen type and the short name.
Can you make a quick manual check in a sample project to verify if it really works with this the two cases?
Reqnroll/Bindings/CucumberExpressions/CucumberExpressionParameterTypeRegistry.cs
Outdated
Show resolved
Hide resolved
if (matchingEnums.Length == 1) { return matchingEnums[0].Value; } | ||
if (matchingEnums.Length > 1) | ||
{ | ||
throw new ApplicationException($"Ambigous Enum Parameters share the same short name '{name}'. Use the Enum's FullName in the Cucumber Expression."); |
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.
- throw
ReqnrollException
instead - I would make the error message more sounding like a normal text (there was also a typo in the
Ambiguous
word!):$"Ambiguous enum parameters share the same short name '{name}'. Use the enum's full name in the cucumber expression."
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.
done
public void Should_not_error_on_multiple_enums_of_the_same_name() | ||
{ | ||
var sut = CreateSut(); | ||
Reqnroll.Bindings.Reflection.IBindingMethod enumUsingBindingMethod1 = new RuntimeBindingMethod(typeof(SampleEnumUsingClass).GetMethod("MethodUsingSampleColorEnum1")); |
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 "MethodUsingSampleColorEnum1"
you can use nameof(SampleEnumUsingClass.MethodUsingSampleColorEnum1)
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.
done
var sut = CreateSut(); | ||
Reqnroll.Bindings.Reflection.IBindingMethod enumUsingBindingMethod1 = new RuntimeBindingMethod(typeof(SampleEnumUsingClass).GetMethod("MethodUsingSampleColorEnum1")); | ||
sut.OnBindingMethodProcessed(enumUsingBindingMethod1); | ||
Reqnroll.Bindings.Reflection.IBindingMethod enumUsingBindingMethod2 = new RuntimeBindingMethod(typeof(CucumberAddtionalExpressions.EnumCucumberExpressions).GetMethod("MethodUsingSampleColorEnum2")); |
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.
Use nameof
also here
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.
done
Please take a look at this repo with a set of projects that demonstrate behavior. |
@clrudolphi could you paste the new stack trace of the errors? |
BTW, I think this is the usual behavior if there is any binding error. Like an invalid regex. So it is not that horrible. |
In the VisualStudio Output window, the VS RnR Extension will output:
In the Test Explorer View of VS, the Test Detail Summary is:
|
I think this is OK. Could you please check if you get the same behavior if you add an attribute like |
|
@clrudolphi ok. so that works the same way. i think this is good. So I think what is missing is:
|
…nd BindingRegistry in InValid state when ambiguous enum cucumber parameter expressions are present. Modified Error message for formatting.
@gasparnagy |
@clrudolphi yes, this is fine. Is it ready to merge once the CI is green then? |
Yes. I'm not aware of any other remaining action items. |
Thx! |
* origin/main: Fix for 81 - Cucumber Expression using Enums errors when two enums exist with the same short name (#100)
…ons-dependencyinjection-plugin * origin/main: (21 commits) Fix #56 autofac ambiguous stepdef and hook required #127 issue (#139) Reduce target framework of Reqnroll to netstandard2.0 (#130) Fix StackOverflowException when using [StepArgumentTransformation] with same input and output type (#136) MsTest: Replace DelayedFixtureTearDown special case with ClassCleanupBehavior.EndOfClass (#128) Temporarily disabled tests until #132 is resolved Add NUnit & xUnit core tests to portability suite Capture ExecutionContext after every binding invoke (#126) small improvement in CodeDomHelper to be able to chain async calls fix method name sources in UnitTestFeatureGenerator External data plugin, support for JSON files (#118) UnitTests: Check if SDK version is installed and if not ignore the test (#109) Fix 111 ignore attr not inherited from rule (#113) Update README.md (#110) Fix 81 - modified CucumberExpressionParameterTypeRegistry to handle multiple custom types used as cucumber expressions when those types share the same short name. (#104) Update index.md Simplify test project targets (#105) Make SystemTests temp folder configurable and use NUGET_PACKAGES env var to override global NuGet folder Fleshing out Generation System Tests (2) (#99) Fix for 81 - Cucumber Expression using Enums errors when two enums exist with the same short name (#100) Include BoDi to Reqnroll package (#91) (#95) ... # Conflicts: # Reqnroll.sln # Tests/Reqnroll.PluginTests/Reqnroll.PluginTests.csproj
This fix causes the CucumberExpressionParameterTypeRegistry to use the FQN of the enum Types used as Cucumber Expression parameters.
Types of changes
[X ] Bug fix (non-breaking change which fixes an issue).
New feature (non-breaking change which adds functionality).
Breaking change (fix or feature that would cause existing functionality to not work as expected).
Performance improvement
Refactoring (so no functional change)
Other (docs, build config, etc)
[X ] I've added tests for my code. (most of the time mandatory)
[X ] I have added an entry to the changelog. (mandatory)
My change requires a change to the documentation.
I have updated the documentation accordingly.