Cucumber converting TypeRegistryConfiguration to ParameterType annotation JAVA - cucumber

Since TypeRegistry io.cucumber.core.api.TypeRegistry is #Deprecated I have troubles declaring my parameter annotations, I have now idea how to transform them to the #ParameterType
I tried this
#ParameterType(value = ".*", name = "foo")
public String foo(String foo) {
return "foobar";
}
#ParameterType("foo")
#When("I type {foo}")
public void iType(String string) {
System.out.println(string);
}
the step recognises this parameter and it compiles but I get following error:
io.cucumber.java.InvalidMethodSignatureException: A #ParameterType annotated method must have one of these signatures:
* public Author parameterName(String all)
* public Author parameterName(String captureGroup1, String captureGroup2, ...ect )
* public Author parameterName(String... captureGroups)
at com.dsm.steps.RequestAccessSteps.withTheInformationIconContaining(java.lang.String)
Note: Author is an example of the class you want to convert captureGroups to
but honestly I dont understand what they are trying to say

The fault is I put the #Parametertype("foo") above the step but thats not necessary and thus throwing the error. It works perfectly fine otherwise.
So this works:
public String foo(String foo) {
return "foobar";
}
#When("I type {foo}")
public void iType(String string) {
System.out.println(string);
}

Related

Unexpected behaviour for Groovy 'with' method - variable assignment silently failed

I have the following code:
import groovy.transform.ToString
#ToString(includeNames = true)
class Simple {
String creditPoints
}
Simple simple = new Simple()
simple.with {
creditPoints : "288"
}
println simple
Clearly, I made a mistake here with creditPoints : "288". It should have been creditPoints = "288".
I expected Groovy to fail at the runtime saying that I made a mistake and I should have used creditPoints = "288"but clearly it did not.
Since it did not fail then what did Groovy do with the closure I created?
From the Groovy compiler perspective, there is no mistake in your closure code. The compiler sees creditPoints : "288" as labeled statement which is a legal construction in the Groovy programming language. As the documentation says, label statement does not add anything to the resulting bytecode, but it can be used for instance by AST transformations (Spock Framework uses it heavily).
It becomes more clear and easy to understand if you format code more accurately to the label statement use case, e.g
class Simple {
String creditPoints
static void main(String[] args) {
Simple simple = new Simple()
simple.with {
creditPoints:
"288"
}
println simple
}
}
(NOTE: I put your script inside the main method body to show you its bytecode representation in the next section.)
Now when we know how compiler sees this construction, let's take a look and see what does the final bytecode look like. To do this we will decompile the .class file (I use IntelliJ IDEA for that - you simply open .class file in IDEA and it decompiles it for you):
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import groovy.lang.Closure;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.transform.ToString;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.GeneratedClosure;
import org.codehaus.groovy.runtime.InvokerHelper;
#ToString
public class Simple implements GroovyObject {
private String creditPoints;
public Simple() {
MetaClass var1 = this.$getStaticMetaClass();
this.metaClass = var1;
}
public static void main(String... args) {
Simple simple = new Simple();
class _main_closure1 extends Closure implements GeneratedClosure {
public _main_closure1(Object _outerInstance, Object _thisObject) {
super(_outerInstance, _thisObject);
}
public Object doCall(Object it) {
return "288";
}
public Object call(Object args) {
return this.doCall(args);
}
public Object call() {
return this.doCall((Object)null);
}
public Object doCall() {
return this.doCall((Object)null);
}
}
DefaultGroovyMethods.with(simple, new _main_closure1(Simple.class, Simple.class));
DefaultGroovyMethods.println(Simple.class, simple);
Object var10000 = null;
}
public String toString() {
StringBuilder _result = new StringBuilder();
Boolean $toStringFirst = Boolean.TRUE;
_result.append("Simple(");
if ($toStringFirst == null ? false : $toStringFirst) {
Boolean var3 = Boolean.FALSE;
} else {
_result.append(", ");
}
if (this.getCreditPoints() == this) {
_result.append("(this)");
} else {
_result.append(InvokerHelper.toString(this.getCreditPoints()));
}
_result.append(")");
return _result.toString();
}
public String getCreditPoints() {
return this.creditPoints;
}
public void setCreditPoints(String var1) {
this.creditPoints = var1;
}
}
As you can see, your closure used with the with method is represented as an inner _main_closure1 class. This class extends Closure class, and it implements GeneratedClosure interface. The body of the closure is encapsulated in public Object doCall(Object it) method. This method only returns "288" string, which is expected - the last statement of the closure becomes a return statement by default. There is no label statement in the generated bytecode, which is also expected as labels get stripped at the CANONICALIZATION Groovy compiler phase.

Is the #Repeatable annotation not supported by Groovy?

I'm coding in Groovy and am having trouble with the Java 8 #Repeatable meta-annotation. I think I'm doing everything right, but it appears that Groovy is not recognizing #Repeatable. Here's my sample code; I'm expecting the information from both annotations to get stored in MyAnnotationArray:
import java.lang.annotation.*
class MyClass
{
#MyAnnotation(value = "val1")
#MyAnnotation(value = "val2")
void annotatedMethod()
{
println("annotated method called")
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
public #interface MyAnnotationArray
{
MyAnnotation[] MyAnnotationArray()
}
What happens is that I get this error:
Caught: java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
java.lang.annotation.AnnotationFormatError: Duplicate annotation for class: interface MyAnnotation: #MyAnnotation(value=val2)
Which is exactly what I get if I leave out the #Repeatable meta-annotation.
The code works fine if I leave out one of the duplicate MyAnnotations; then there is no error, and I then can read the annotation value as expected.
Is it possible that Groovy doesn't support the #Repeatable meta-annotation? I couldn't find any documentation that states this outright, though this page hints that maybe this is the case (scroll down to item 88).
seems to be not supported
i used java 1.8 and groovy 2.4.11
after compiling and de-compilig the same code i got this:
java:
#MyAnnotationArray({#MyAnnotation("val1"), #MyAnnotation("val2")})
public void annotatedMethod()
{
System.out.println("annotated method called");
}
groovy:
#MyAnnotation("val1")
#MyAnnotation("val2")
public void annotatedMethod()
{
System.out.println("annotated method called");null;
}
so, as workaround in groovy use
//note the square brackets
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
full script (because there were some errors in annotation declaration)
import java.lang.annotation.*
class MyClass
{
//#MyAnnotation(value = "val1")
//#MyAnnotation(value = "val2")
#MyAnnotationArray( [#MyAnnotation("val1"), #MyAnnotation("val2")] )
public void annotatedMethod()
{
System.out.println("annotated method called");
}
public static void main(String... args)
{
MyClass ob = new MyClass()
ob.annotatedMethod()
java.lang.reflect.Method m = ob.getClass().getMethod("annotatedMethod")
List annos = m.getAnnotations()
println("annos = $annos")
}
}
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
#Repeatable(MyAnnotationArray)
public #interface MyAnnotation
{
String value() default "val0";
}
#Retention(RetentionPolicy.RUNTIME)
public #interface MyAnnotationArray
{
MyAnnotation[] value()
}
also tried against groovy 3.0.0-SNAPSHOT - the result is the same as for 2.4.11
Yes, Groovy has supported "repeatable" annotations for a long time even in Java 5 so long as retention policy was only SOURCE. This is what allows multiple #Grab statements for instance without the outer #Grapes container annotation. Being only retained in SOURCE makes them useful for AST transformations and within the Groovy compiler itself (and other source processors) but not really useful anywhere else. We don't currently support #Repeatable at all but plan to in a future version.

AutoMapper ConstructServicesUsing is ignored

I have a Person and a PersonViewModel. I created a map from Person => PersonViewModel. The problem is that PersonViewModel's only constructor needs an argument (it has a dependency that I want to be injected) and AutoMapper is complaining because it says it needs a parameterless constructor.
To fix it, I used the ConstructServicesUsing method, but I haven't been successful with it :(
To illustrate the case, I created a test for you to see what I'm doing. It's pretty simple:
[TestMethod]
public void TestConstructServicesUsing()
{
Mapper.Initialize(configuration =>
{
configuration.ConstructServicesUsing(FactoryMethod);
configuration.CreateMap<Person, PersonViewModel>();
});
Mapper.AssertConfigurationIsValid();
var person = new Person();
var personViewModel = Mapper.Map<Person, PersonViewModel>(person);
}
private object FactoryMethod(Type type)
{
throw new NotImplementedException();
}
}
The rest of the code is the classes and interface definitions. They are almost empty.
public class SomeyDependency : ISomeDependency
{
}
public class PersonViewModel
{
private readonly ISomeDependency service;
public PersonViewModel(ISomeDependency service)
{
this.service = service;
}
public string Name { get; set; }
}
public class Person
{
public string Name { get; set; }
}
public interface ISomeDependency
{
}
As you see, I provide AutoMapper with a FactoryMethod, but it never get called.
When it reaches the last line of the test (Mapper.Map<...>()) it throws an excepton saying:
AutoMapper.AutoMapperMappingException:
Mapping types:
Person -> PersonViewModel
MappingWithContainerTests.Person -> MappingWithContainerTests.PersonViewModel
Destination path:
PersonViewModel
Source value:
MappingWithContainerTests.Person ---> System.ArgumentException: Type needs to have a constructor with 0 args or only optional args
Parameter name: type
What's the problem?
Why isn't the FactoryMethod being called?
As #khorvat mention where is missing .ConstructUsingServiceLocator(), for concrete mapping.
Also you can set constructor directly by
.ConstructUsing(source => Method(source.anySourceOptions))
Or as exception said:
PersonViewModel, must have a constructor with 0 args or only optional
args. You have only one constructor with 1 not optional argument
you may create one more constructor without args:
public PersonViewModel()
{
this.service = new SomeDependency();
}
I'm using .NET Core 3.1 and Automapper.Extensions.Microsoft.DependencyInjection.
This does not work for me (Same error as yours):
public class AutoMapping : Profile
{
public AutoMapping()
{
CreateMap<Context, MainViewModel>()
.ReverseMap()
.ConstructUsingServiceLocator();
}
}
But this does work:
public class AutoMapping : Profile
{
public AutoMapping()
{
CreateMap<Context, MainViewModel>()
.ConstructUsingServiceLocator()
.ReverseMap();
}
}
I still do not fully understand the cause.

C#: is it possible to create an object that has a value of its "default property" when referenced?

Is it possible to create an object with a constructor parameter which returns a property value when referenced, without using dot notation? Here's a few examples:
public class myObject
{
public string myObject {get; private set;}
public myObject( string tempstring)
{
this.myObject = tempstring.ToUpper();
}
}
var a = new myObject("somevalue");
Console.WriteLine( myObject ); // outputs the string "SOMEVALUE"
Here's another attempt:
public class myInt
{
public int myInt {get; private set;}
public myInt(string tempInt)
{ this.myInt = Convert.ToInt32(tempInt);
}
}
var a = new myInt("3");
var b = a + a; // ends up being an int datatype value of 6
I know I could always do var b = a.myInt + a.myInt. I guess I could create a static class with a static function that converts a parameter each time to a result, but it wouldn't maintain state.
Just curious. It would make what I am actually trying to do much less difficult.
In the first case, yes. Override the ToString method.
public class myObject
{
public string myValue {get; private set;}
public myObject( string tempstring)
{
this.myValue = tempstring.ToUpper();
}
public override string ToString()
{
return myValue;
}
}
In the second case, sort of. You shouldn't try to overload operators to offer unexpected behavior. Create a method to perform behavior that wouldn't make sense when reading the code. What you are suggesting (returning an int) would definitely not be expected by me to return an int (mostly because of the var rather than a strictly defined type). Using the + operator to return a new myInt object would make sense. Using the + operator return an int would not.
You could overload the + operator to return a new myInt object, and then also add an implicit cast to int. Just make sure it makes sense, and that it is readable.
Within the class, you could use:
public static implicit operator int(myInt m)
{
return myValue;
}
public static myInt operator +(myInt left, myInt right)
{
// requires constructor that takes int
return new myInt(left.myValue + right.myValue);
}
Of course, you could go the direct route, but again only use it when it makes it more readable and not less (note, just like methods operators cannot be overloaded simply by return type, so you'd have to pick between the two).
public static int operator +(myInt left, myInt right)
{
return left.myValue + right.myValue;
}
How about implicit conversions. See http://msdn.microsoft.com/en-us/library/z5z9kes2(VS.71).aspx

Can extension methods modify extended class values?

I was just trying to code the following extension method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace _4Testing
{
static class ExtensionMethods
{
public static void AssignMe(this int me, int value)
{
me = value;
}
}
}
But it is not working, i mean, can I use an extension method to alter values from extended classes? I don't want to change void return type to int, just changing extended class value. Thanks in advance
Your example uses int, which is a value type. Classes are reference types and behaves a bit differently in this case.
While you could make a method that takes another reference like AssignMe(this MyClass me, MyClass other), the method would work on a copy of the reference, so if you assign other to me it would only affect the local copy of the reference.
Also, keep in mind that extension methods are just static methods in disguise. I.e. they can only access public members of the extended types.
public sealed class Foo {
public int PublicValue;
private int PrivateValue;
}
public static class FooExtensions {
public static void Bar(this Foo f) {
f.PublicValue = 42;
// Doesn't compile as the extension method doesn't have access to Foo's internals
f.PrivateValue = 42;
}
}
// a work around for extension to a wrapping reference type is following ....
using System;
static class Program
{
static void Main(string[] args)
{
var me = new Integer { value = 5 };
int y = 2;
me.AssignMe(y);
Console.WriteLine(me); // prints 2
Console.ReadLine();
}
public static void AssignMe(this Integer me, int value)
{
me.value = value;
}
}
class Integer
{
public int value { get; set; }
public Integer()
{
value = 0;
}
public override string ToString()
{
return value.ToString();
}
}
Ramon what you really need is a ref modifier on the first (i.e. int me ) parameter of the extension method, but C# does not allow ref modifier on parameters having 'this' modifiers.
[Update]
No workaround should be possible for your particular case of an extension method for a value type. Here is the "reductio ad absurdum" that you are asking for if you are allowed to do what you want to do; consider the C# statement:
5.AssignMe(10);
... now what on earth do you think its suppose to do ? Are you trying to assign 10 to 5 ??
Operator overloading cannot help you either.
This is an old post but I ran into a similar problem trying to implement an extender for the String class.
My original code was this:
public static void Revert(this string s)
{
char[] xc = s.ToCharArray();
s = new string(xc.Reverse());
}
By using the new keyword I am creating a new object and since s is not passed by reference it will not be modified.
I changed it to the following which provides a solution to Ramon's problem:
public static string Reverse(this string s)
{
char[] xc = s.ToCharArray();
Array.Reverse(xc);
return new string(xc);
}
In which case the calling code will be:
s = s.Reverse();
To manipulate integers you can do something like:
public static int Increment(this int i)
{
return i++;
}
i = i.Increment();

Resources