diff --git a/easy-random-bean-validation/pom.xml b/easy-random-bean-validation/pom.xml index cce35bbc..61c2ed32 100644 --- a/easy-random-bean-validation/pom.xml +++ b/easy-random-bean-validation/pom.xml @@ -4,7 +4,7 @@ io.github.dvgaba easy-random - 7.0.0 + 7.0.1-SNAPSHOT 4.0.0 easy-random-bean-validation diff --git a/easy-random-core/pom.xml b/easy-random-core/pom.xml index 0aa4781f..4448540a 100644 --- a/easy-random-core/pom.xml +++ b/easy-random-core/pom.xml @@ -4,7 +4,7 @@ io.github.dvgaba easy-random - 7.0.0 + 7.0.1-SNAPSHOT 4.0.0 easy-random-core diff --git a/easy-random-core/src/main/java/org/jeasy/random/EasyRandom.java b/easy-random-core/src/main/java/org/jeasy/random/EasyRandom.java index 292723a7..060ef1d8 100644 --- a/easy-random-core/src/main/java/org/jeasy/random/EasyRandom.java +++ b/easy-random-core/src/main/java/org/jeasy/random/EasyRandom.java @@ -113,6 +113,10 @@ private boolean isRecord(final Class type) { return type.isRecord(); } + private static boolean isSealedInterface(Class type) { + return type.isSealed() && type.isInterface(); + } + /** * Generate a stream of random instances of the given type. * @@ -145,6 +149,12 @@ T doPopulateBean(final Class type, final RandomizationContext context) { return (T) randomizer.getRandomValue(); } + if (isSealedInterface(type)) { + Class[] subclasses = type.getPermittedSubclasses(); + Class subclass = subclasses[nextInt(subclasses.length)]; + return (T) nextObject(subclass); + } + if (isRecord(type)) { return recordFactory.createInstance(type, context); } diff --git a/easy-random-core/src/test/java/org/jeasy/random/SealedInterfaceTest.java b/easy-random-core/src/test/java/org/jeasy/random/SealedInterfaceTest.java new file mode 100644 index 00000000..b051ffe6 --- /dev/null +++ b/easy-random-core/src/test/java/org/jeasy/random/SealedInterfaceTest.java @@ -0,0 +1,91 @@ +package org.jeasy.random; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +public class SealedInterfaceTest { + EasyRandomParameters parameters = new EasyRandomParameters(); + EasyRandom easyRandom = new EasyRandom(parameters); + + @Test + void should_arrangeSealedInterface() { + //when + SealedInterfaceData actual = easyRandom.nextObject(SealedInterfaceData.class); + + //then + assertThat(actual).isInstanceOfAny(ConcreteData1.class, ConcreteData2.class); + } + + @Test + void should_arrangeDataWithNestedSealedInterfaceField() { + //when + NestedSealedInterfaceData actual = easyRandom.nextObject(NestedSealedInterfaceData.class); + + //then + assertThat(actual).isInstanceOf(ConcreteNested1.class); + assertThat((ConcreteNested1) actual) + .extracting(ConcreteNested1::sealedInterfaceData) + .isInstanceOfAny(ConcreteData1.class, ConcreteData2.class); + + } + + @Test + void should_arrangeRecordWithListWithSealedInterfaceField() { + //when + RootRecordWithNestedList actual = easyRandom.nextObject(RootRecordWithNestedList.class); + + //then + assertThat(actual.nestedRecordWithSealedInterfaces().get(0)) + .extracting(NestedRecordWithSealedInterface::sealedInterfaceData) + .isInstanceOfAny(ConcreteData1.class, ConcreteData2.class); + } +} + +record DataWithAbstract(Integer value, + SealedInterfaceData sealedInterfaceData, + ExcludedSealedInterface excludedSealedInterface, + NonSealedInterface nonSealedInterface) { + DataWithAbstract { + } + + DataWithAbstract(String name) { + this(0, new ConcreteData1(""), new ExcludedData1(), new NonSealedInterface() { + }); + } +} + +sealed interface SealedInterfaceData permits ConcreteData1, ConcreteData2 { +} + +record ConcreteData1(String value) implements SealedInterfaceData { +} + +final class ConcreteData2 implements SealedInterfaceData { + + Integer value; + +} + +sealed interface ExcludedSealedInterface permits ExcludedData1 { +} + +record ExcludedData1() implements ExcludedSealedInterface { +} + +interface NonSealedInterface { +} + +sealed interface NestedSealedInterfaceData permits ConcreteNested1 { +} + +record ConcreteNested1(SealedInterfaceData sealedInterfaceData) implements NestedSealedInterfaceData { +} + +record RootRecordWithNestedList(List nestedRecordWithSealedInterfaces) { +} + +record NestedRecordWithSealedInterface(SealedInterfaceData sealedInterfaceData) { +} diff --git a/easy-random-protobuf/pom.xml b/easy-random-protobuf/pom.xml index f974afd5..02270be2 100644 --- a/easy-random-protobuf/pom.xml +++ b/easy-random-protobuf/pom.xml @@ -4,7 +4,7 @@ io.github.dvgaba easy-random - 7.0.0 + 7.0.1-SNAPSHOT 4.0.0 easy-random-protobuf diff --git a/easy-random-randomizers/pom.xml b/easy-random-randomizers/pom.xml index eba896e6..4f1b6269 100644 --- a/easy-random-randomizers/pom.xml +++ b/easy-random-randomizers/pom.xml @@ -4,7 +4,7 @@ io.github.dvgaba easy-random - 7.0.0 + 7.0.1-SNAPSHOT 4.0.0 easy-random-randomizers diff --git a/pom.xml b/pom.xml index 80c11953..d9407048 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 io.github.dvgaba easy-random - 7.0.0 + 7.0.1-SNAPSHOT pom