Skip to content

Support (groovy) method names with spaces #1936

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

Closed
mojo2012 opened this issue Apr 4, 2020 · 10 comments
Closed

Support (groovy) method names with spaces #1936

mojo2012 opened this issue Apr 4, 2020 · 10 comments
Labels
⌛ stale Will soon be closed by stalebot unless there is activity ⚡ enhancement Request for new functionality

Comments

@mojo2012
Copy link

mojo2012 commented Apr 4, 2020

Groovy allows method names with spaces and other special chars, like this here:

@Given("")
void "ein Benutzer ist als Admin mit dem Benutzernamen {string} angemeldet"(String userMail) {
	final def adminEmail = getProperty(userMail);
}

This would allow us to use the actual step definition string as the method name, instead of artificial/weird method names.

This could easily be supported by adding this "fix" to the JavaStepDefinition class. Instead of failing if the annotation value is empty, it could do this:

if (expression != null && !"".intern().equals(expression)) {
	this.expression = requireNonNull(expression, "cucumber-expression may not be null");
} else {
	// groovy methods can be strings, so in case the expression is empty, we just use the method name
	this.expression = method.getName();
}

Possibly combined with a check if the class implements GroovyObject.

Additionally it would be nice to set the annotation default values to an empty string, so that @Given("") could be further reduced to @Given.

With such a small code change groovy support could be drastically improved (even without a separate backend!).

I tried this myself (created a new groovy backend) but failed because both the java and my groovy backend matched the same step definitions leading to duplication exceptions.

Hope you guys are open for such improvements :-)

@mojo2012 mojo2012 added the ⚡ enhancement Request for new functionality label Apr 4, 2020
@mpkorstanje
Copy link
Contributor

mpkorstanje commented Apr 4, 2020

There is an existing implementation of a groovy back end at cucumber-jvm-groovy but it is not developed in sync with cucumber-jvm. We simply lack the capacity and the number of users was quite low.

It does make use of a quite a few nice Groovy features. You can find an example here; CalculatorSteps.groovy. If you want and can spare the time you can submit a pull request to upgrade it to version 5.x.

@mojo2012
Copy link
Author

mojo2012 commented Apr 7, 2020

it would be a total overkill and maintenance burden to create a separate groovy backend, especially, as it would conflict with the java backend.
The existing groovy backend uses top-level closures btw, that‘s not what I want.

@mpkorstanje
Copy link
Contributor

I'm not really interested in maintaining an exception and associated tests for Groovy.

it would conflict with the java backend.

Each backend should use its own annotations/methods and through the ObjectFactory each backend also has access to the same test context. There should be very little conflict.

@mojo2012
Copy link
Author

Each backend should use its own annotations/methods and through the ObjectFactory each backend also has access to the same test context. There should be very little conflict.

Duplicating all annotations? hmm well, the point actually was to reuse almost all of the java-backend without duplicating code. ...

@mpkorstanje
Copy link
Contributor

The most important reason is to keep everything in its own package/jar so the API is clear and language specific. Each language tends to brings its own problems and features. Mixing these tends to be detrimental to both implementations.

Most of the the annotations are generated so the duplication there is not a big deal. We can repeat that trick for the annotations that currently aren't generated. But I can see how the other classes might be annoying to duplicate. So lets suppose we did just that....

The current java backend provides a snippet generator and discovers glue code. Discovery would mostly be the same but snippet generation wouldn't be. So that would have to have to be extracted to a separate service discoverable via SPI.

Discovery would mostly be the same but the current code isn't extensible:

https://github.com/cucumber/cucumber-jvm/blob/master/java/src/main/java/io/cucumber/java/MethodScanner.java#L59
https://github.com/cucumber/cucumber-jvm/blob/master/java/src/main/java/io/cucumber/java/GlueAdaptor.java

As you can see there is some really annoying hardcoded repetition going on here. It would be better if all hook and and step definition annotations had a meta annotation with the information required to instantiate these.

For example:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@API(status = API.Status.INTERNAL)
@Creator(JavaStepDefinitionCreator.class)
public @interface StepDefinitionAnnotation {
}
public class JavaStepDefinitionCreator implements GlueAdaptor<JavaStepDefinition> {
        JavaStepDefinition create(Method method, Annotation annotation, Lookup lookup) {
            Class<? extends Annotation> annotationType = annotation.annotationType();
            String expression = expression(annotation);
            return new JavaStepDefinition(method, expression, lookup);
        }
} 

With this it would only be a matter of generating more annotations. This would also be a nice way to support annotations for Kotlin. #1829

@mpkorstanje
Copy link
Contributor

I'll reopen this for now, should anybody be interested in doing the refactoring work.

@mpkorstanje mpkorstanje reopened this Apr 18, 2020
@mlvandijk
Copy link
Member

I might be interested if this would also work for Kotlin.

@mpkorstanje
Copy link
Contributor

Kotlin only allow spaces, it doesn't allow curly braces or other characters. This makes defining steps rather hard.

@stale
Copy link

stale bot commented May 20, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in two months if no further activity occurs.

@stale stale bot added the ⌛ stale Will soon be closed by stalebot unless there is activity label May 20, 2021
@stale
Copy link

stale bot commented Sep 21, 2021

This issue has been automatically closed because of inactivity. You can support the Cucumber core team on opencollective.

@stale stale bot closed this as completed Sep 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⌛ stale Will soon be closed by stalebot unless there is activity ⚡ enhancement Request for new functionality
Projects
None yet
Development

No branches or pull requests

3 participants