Skip to content
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

Sealed classes and interface support #47

Merged
merged 12 commits into from
Oct 23, 2024
2 changes: 1 addition & 1 deletion easy-random-bean-validation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.github.dvgaba</groupId>
<artifactId>easy-random</artifactId>
<version>7.0.0</version>
<version>7.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easy-random-bean-validation</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion easy-random-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.github.dvgaba</groupId>
<artifactId>easy-random</artifactId>
<version>7.0.0</version>
<version>7.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easy-random-core</artifactId>
Expand Down
10 changes: 10 additions & 0 deletions easy-random-core/src/main/java/org/jeasy/random/EasyRandom.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ private <T> boolean isRecord(final Class<T> 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.
*
Expand Down Expand Up @@ -145,6 +149,12 @@ <T> T doPopulateBean(final Class<T> 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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<NestedRecordWithSealedInterface> nestedRecordWithSealedInterfaces) {
}

record NestedRecordWithSealedInterface(SealedInterfaceData sealedInterfaceData) {
}
2 changes: 1 addition & 1 deletion easy-random-protobuf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.github.dvgaba</groupId>
<artifactId>easy-random</artifactId>
<version>7.0.0</version>
<version>7.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easy-random-protobuf</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion easy-random-randomizers/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>io.github.dvgaba</groupId>
<artifactId>easy-random</artifactId>
<version>7.0.0</version>
<version>7.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>easy-random-randomizers</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.dvgaba</groupId>
<artifactId>easy-random</artifactId>
<version>7.0.0</version>
<version>7.0.1-SNAPSHOT</version>
<packaging>pom</packaging>

<build>
Expand Down
Loading