-
Notifications
You must be signed in to change notification settings - Fork 233
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
Support type variables #425
Comments
See [issue](j-easy#425) Pass the actual type along with a field that will be used to pick correct randomizer. Consider the following example: ``` abstract class Base<T> { T t; } class Concrete extends Base<String> {} ``` If we only rely on `Field.getType()`, property `Concrete.t` would be randomized as `Object` and then cause a runtime exception when used. Java reflection API provides a way to get the actual type, in this case `String`. This information is passed in `GenericField` so that the correct randomizer can be picked later.
Hello! What are the deadline for closing this issue? |
Duplicate/Similar to #375 , #242 and #386. @ollik1 I would like to get your feedback on #426 (comment) before closing this as duplicate. |
@benas if you have time you can check the intermediate state. |
The implementation: https://github.com/seregamorph/easy-random/compare/generic-base-class...seregamorph:generic-base-class-spring-core-no-spring?expand=1 (it's too early to raise the PR, so the delta link) |
One more implementation based on fasterxml-classmate dependency https://github.com/seregamorph/easy-random/compare/generic-base-class...seregamorph:generic-base-class-classmate?expand=1 |
@seregamorph Thank you for this effort! However, I'm not in favor of copying code from Spring Framework (and that's a lot of code already). Moreover, those changes are based on #426 for which I already explained my concerns here. I believe #439 is a middle ground that covers common use cases (it covers all tests suggested in #426 and more), so in my opinion, this is a good start for v4.3 which we can improve in subsequent iterations. Wdyt? EDIT: I didn't see you previous message when I posted this message. I don't think we need a new dependency for this. We should aim at starting small and keeping it simple for now. We can always iterate on this and improve things in subsequent releases. |
Well, I missed message about raised #439, sorry. It covers some cases, that's true, but I have failures on my model. Please check these test cases - a bit more complicated inheritance and cross-references with generic types. All three fail on your implementation (passes on both mine implementations ;) ) import static org.assertj.core.api.Assertions.assertThat;
import java.io.Serializable;
import org.junit.jupiter.api.Test;
public class GenericTest {
@Test
void genericFirstTypeShouldBeCorrectlyPopulated() {
// given
EasyRandom easyRandom = new EasyRandom();
// when
LongResourceFirstType longResource = easyRandom.nextObject(LongResourceFirstType.class);
// then
assertThat(longResource.getId())
.isInstanceOf(Long.class);
assertThat(longResource.stringResource.getId())
.isInstanceOf(String.class);
}
@Test
void genericSubShouldBeCorrectlyPopulated() {
// given
EasyRandom easyRandom = new EasyRandom();
class Sub extends LongResourceFirstType {
}
// when
Sub sub = easyRandom.nextObject(Sub.class);
// then
assertThat(sub.getId())
.isInstanceOf(Long.class);
}
@Test
void genericSecondTypeShouldBeCorrectlyPopulated() {
// given
EasyRandom easyRandom = new EasyRandom();
// when
StringResourceSecondType stringResource = easyRandom.nextObject(StringResourceSecondType.class);
// then
assertThat(stringResource.getId())
.isInstanceOf(String.class);
assertThat(stringResource.longResource.getId())
.isInstanceOf(Long.class);
}
private static abstract class IdResourceFirstType<K, T extends IdResourceFirstType<K, ?>> {
private K id;
@SuppressWarnings("unchecked")
public T setId(K id) {
this.id = id;
return (T) this;
}
public K getId() {
return id;
}
}
private static abstract class IdResourceSecondType<T extends IdResourceSecondType<?, K>, K extends Serializable> {
private K id;
@SuppressWarnings("unchecked")
public T setId(K id) {
this.id = id;
return (T) this;
}
public K getId() {
return id;
}
}
private static abstract class IntermediateParent<K extends Serializable, T extends IntermediateParent<K, ?>>
extends IdResourceFirstType<K, T> {
}
private static class LongResourceFirstType extends IntermediateParent<Long, LongResourceFirstType> {
private StringResourceSecondType stringResource;
}
private static class StringResourceSecondType extends IdResourceSecondType<StringResourceSecondType, String> {
private LongResourceFirstType longResource;
}
} If you are fine with these failures - it's up to you do decide. P.S. still confused why you don't like to include code made by @vmware fellas ;) |
I'm not expecting Easy Random to support types like: class IdResourceSecondType<T extends IdResourceSecondType<?, K>, K extends Serializable>` {}
//and
class IntermediateParent<K extends Serializable, T extends IntermediateParent<K, ?>> extends IdResourceFirstType<K, T> {} out-of-the-box. That's not the goal in the first place. The goal is to cover basic use cases and give users the necessary extension points to customize/extend the base functionality. This is already the case in Easy Random with custom randomizers,
Let me clarify this confusion. It's not about the quality or whatever, it is because the amount of code you are suggesting to copy (ResolvableType, SerializableTypeWrapper, SpringReflectionUtils, ObjectUtils) is really significant for the added value (which is covering 20% of use cases that the average user might not need and which should not be handled by the library by design, those should be left to the user with custom extension points). So the cost/benefit ratio here is really high. Moreover, I'm not in favor of copying code in general because copies can quickly diverge, and the copy will immediately become a maintenance burden on our side. |
Consider the following example:
Currently
easyRandom.nextObject(Concrete.class)
would generatet
asjava.lang.Object
which will then cause a runtime exception when used. The actual types are preserved in classes so that could be used to pick the correct randomizer instead.The text was updated successfully, but these errors were encountered: