fails to generate collection for kotlin pojo with default parameters
Closed this issue · 6 comments
Example:
data class Pojo(
val listValue: List<String>,
val intValue: Int = 0
)
class PojoTest {
var factory = PodamFactoryImpl()
@Test
fun pojo2() {
val pojo = factory.manufacturePojoWithFullData(Pojo::class.java)
Assert.assertEquals(String::class.java, pojo.listValue[0].javaClass)
}
}
Kotlin compiler creates new constructor for instantiating objects with default parameters and erases generic info for such constructor so constructor. genericParameterTypes
returns only Class
and not ParameterizedType
.
As work around i used special ordering in DataProviderStrategy that prefers constructors with specified ParameterizedType
Hi,
But if Kotlin erases generic type information, what can Podam do about it?
Thanks, Daniil
As work around i used special ordering in DataProviderStrategy that prefers constructors with specified ParameterizedType
private class FixedDataProviderStrategy(private val strategy: DataProviderStrategy) : DataProviderStrategy by strategy {
override fun sort(constructors: Array<out Constructor<*>>, order: DataProviderStrategy.Order) {
strategy.sort(constructors, order)
// https://github.com/mtedone/podam/issues/296
Arrays.sort(constructors) { a, b ->
val aHasTypeInfo = a.genericParameterTypes.find { it is ParameterizedType } != null
val bHasTypeInfo = b.genericParameterTypes.find { it is ParameterizedType } != null
bHasTypeInfo.compareTo(aHasTypeInfo)
}
}
}
Yes, I understood workaround, but no one should randomly shuffle constructors to get desired result. This is not generic and sustainable approach. The main question here is "genericParameterTypes returns only Class and not ParameterizedType" is this is a bug in Kotlin compiler stripping generics away or it is somewhere else.
Thanks, Daniil
This is what Kotlin compiler generates
public final class Pojo {
@NotNull
private final List < String > listValue;
public Pojo(@NotNull List listValue, int intValue) {
this.listValue = listValue;
this.intValue = intValue;
}
private final int intValue;
@NotNull public final List < String > getListValue() {
return this.listValue;
}
public final int getIntValue() {
return this.intValue;
}
@NotNull
public final List < String > component1() {
return this.listValue;
}
public final int component2() {
return this.intValue;
}
@NotNull
public final Pojo copy(@NotNull List listValue, int intValue) {
Intrinsics.checkNotNullParameter(listValue, "listValue");
return new Pojo(listValue, intValue);
}
@NotNull
public String toString() {
return "Pojo(listValue=" + this.listValue + ", intValue=" + this.intValue + ')';
}
public int hashCode() {
result = this.listValue.hashCode();
return result * 31 + Integer.hashCode(this.intValue);
}
public boolean equals(@Nullable Object other) {
if (this == other)
return true;
if (!(other instanceof Pojo))
return false;
Pojo pojo = (Pojo) other;
return !Intrinsics.areEqual(this.listValue, pojo.listValue) ? false : (!(this.intValue != pojo.intValue));
}
}
It was able to keep generics in accessors, but not in the constructor. And there is just one constructor.
Thanks, Daniil
You should report this issue to Kotlin compiler.
Thanks, Daniil