diff --git a/core/build.gradle b/core/build.gradle
index 28551f0..b4a6eb3 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -1,5 +1,6 @@
dependencies {
testImplementation dependency.junit_jupiter_api
+ testImplementation dependency.lombok
testRuntimeOnly dependency.junit_jupiter_engine
}
diff --git a/core/src/main/java/com/tngtech/valueprovider/ValueProvider.java b/core/src/main/java/com/tngtech/valueprovider/ValueProvider.java
index 51187c4..eb59e71 100644
--- a/core/src/main/java/com/tngtech/valueprovider/ValueProvider.java
+++ b/core/src/main/java/com/tngtech/valueprovider/ValueProvider.java
@@ -12,6 +12,7 @@
import java.time.LocalTime;
import java.time.Month;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
@@ -735,7 +736,8 @@ public > Set someOf(Class enumClass, int numberOfElement
* @param elements the elements to draw from.
* @return the drawn elements (none / some / all).
*/
- @SafeVarargs final public Collection someOf(T... elements) {
+ @SafeVarargs
+ final public Collection someOf(T... elements) {
return someOf(asList(elements));
}
@@ -829,6 +831,136 @@ public final T oneOfExcluding(Iterable elements, T... elementsToExclude)
return oneOf(allElements);
}
+ /**
+ * Generates a {@link List} of <T> (by means of {@code generator}) and includes {@code containedElements} in the {@link List}.
+ *
+ * Example:
+ *
+ * static class MyBeanTestData {
+ * public static MyBean myBean(ValueProvider valueProvider) {
+ * // builds and returns your bean
+ * }
+ * }
+ *
+ * ValueProvider vp = ValueProviderFactory.createRandomValueProvider();
+ * vp.listOfContaining(MyBeanTestData::myBean, myBean(), myBean(), myBean()); // -> List[myBean_1, myBean_2, myBean_random, myBean_3, myBean_random]
+ *
+ *
+ *
+ * @param generator a generator {@link Function} to generate T given a {@link ValueProvider}.
+ * @param containedElements elements that should be contained in the generated list.
+ *
+ * @return the generated {@link List}.
+ *
+ * @see #listOf(Function)
+ */
+ @SafeVarargs
+ public final List listOfContaining(Function generator, T... containedElements) {
+ return listOfContaining(generator, Arrays.asList(containedElements));
+ }
+
+ /**
+ * see {@link #listOfContaining(Function, Object[])}
+ */
+ public final List listOfContaining(Function generator, Collection containedElements) {
+ int maxNumberOfRandomElements = maxNumberOfRandomElements(containedElements);
+
+ List generatedElements = new ArrayList<>();
+ for (T containedValue : containedElements) {
+ generatedElements.addAll(listOf(intNumber(0, maxNumberOfRandomElements), generator));
+ generatedElements.add(containedValue);
+ }
+ generatedElements.addAll(listOf(intNumber(0, maxNumberOfRandomElements), generator));
+ return generatedElements;
+ }
+
+ private int maxNumberOfRandomElements(Collection containedElements) {
+ if (containedElements.size() == 0) {
+ return 5;
+ }
+ if (containedElements.size() == 1) {
+ return 2;
+ }
+ return 1;
+ }
+
+ /**
+ * Generates a {@link List} of <T> (by means of {@code generator}). Ensures that the {@link List} contains at least one element.
+ *
+ * Example:
+ *
+ * static class MyBeanTestData {
+ * public static MyBean myBean(ValueProvider valueProvider) {
+ * // builds and returns your bean
+ * }
+ * }
+ *
+ * ValueProvider vp = ValueProviderFactory.createRandomValueProvider();
+ * vp.nonEmptyListOf(MyBeanTestData::myBean); // -> List[myBean_generated_1, myBean_generated_2]
+ *
+ *
+ *
+ * @param generator a generator {@link Function} to generate T given a {@link ValueProvider}.
+ *
+ * @return the generated {@link List}.
+ */
+ public List nonEmptyListOf(Function generator) {
+ return listOf(intNumber(1, 5), generator);
+ }
+
+ /**
+ * Generates a {@link List} of <T> (by means of {@code generator}). Might return the empty list.
+ *
+ * Example:
+ *
+ * static class MyBeanTestData {
+ * public static MyBean myBean(ValueProvider valueProvider) {
+ * // builds and returns your bean
+ * }
+ * }
+ *
+ * ValueProvider vp = ValueProviderFactory.createRandomValueProvider();
+ * vp.listOf(MyBeanTestData::myBean); // -> List[myBean_generated_1, myBean_generated_2]
+ * vp.listOf(MyBeanTestData::myBean); // -> List[]
+ *
+ *
+ *
+ * @param generator a generator {@link Function} to generate T given a {@link ValueProvider}.
+ *
+ * @return the generated {@link List}.
+ */
+ public List listOf(Function generator) {
+ return listOf(intNumber(0, 5), generator);
+ }
+
+ /**
+ * Generates a {@link List} of <T> (by means of {@code generator}). Containing exactly {@code numberOfElements} elements.
+ *
+ * Example:
+ *
+ * static class MyBeanTestData {
+ * public static MyBean myBean(ValueProvider valueProvider) {
+ * // builds and returns your bean
+ * }
+ * }
+ *
+ * ValueProvider vp = ValueProviderFactory.createRandomValueProvider();
+ * vp.listOf(4, MyBeanTestData::myBean); // -> List[myBean_generated_1, myBean_generated_2, myBean_generated_3, myBean_generated_4]
+ *
+ *
+ *
+ * @param generator a generator {@link Function} to generate T given a {@link ValueProvider}.
+ *
+ * @return the generated {@link List}.
+ */
+ public List listOf(int numberOfElements, Function generator) {
+ List generatedElements = new ArrayList<>();
+ for (int i = 0; i < numberOfElements; i++) {
+ generatedElements.add(generator.apply((V) this));
+ }
+ return generatedElements;
+ }
+
/**
* Randomly draws true or false.
*
diff --git a/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java b/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
index 90f2340..f9a7cee 100644
--- a/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
+++ b/core/src/test/java/com/tngtech/valueprovider/ValueProviderTest.java
@@ -20,6 +20,9 @@
import java.util.stream.LongStream;
import java.util.stream.Stream;
+import lombok.Data;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
@@ -32,6 +35,7 @@
import static com.tngtech.valueprovider.ValueProviderTest.MethodInvocation.assertDifferentResultAsFarAsPossible;
import static com.tngtech.valueprovider.ValueProviderTest.MethodInvocation.assertEqualResult;
import static com.tngtech.valueprovider.ValueProviderTest.MethodInvocation.invoke;
+import static com.tngtech.valueprovider.ValueProviderTest.MyBeanTestData.myBeanContained;
import static com.tngtech.valueprovider.ValueProviderTest.TestEnum.EIGHT;
import static com.tngtech.valueprovider.ValueProviderTest.TestEnum.ELEVEN;
import static com.tngtech.valueprovider.ValueProviderTest.TestEnum.FIVE;
@@ -573,6 +577,44 @@ void someOf_should_return_duplicates_if_input_contains_duplicates() {
.hasSize(valueList.size());
}
+ @Test
+ void listOf_should_return_a_sensible_number_of_elements() {
+ // given
+ ValueProvider random = withRandomValues();
+
+ // when
+ List myBeans = random.listOf(MyBeanTestData::myBean);
+
+ // then
+ assertThat(myBeans).size().isLessThanOrEqualTo(5); // 5 is the default
+ }
+
+ @Test
+ void nonEmptyListOf_should_return_at_least_one_element() {
+ // given
+ ValueProvider random = withRandomValues();
+
+ // when
+ List myBeans = random.nonEmptyListOf(MyBeanTestData::myBean);
+
+ // then
+ assertThat(myBeans).size().isGreaterThanOrEqualTo(1);
+ assertThat(myBeans).size().isLessThanOrEqualTo(5); // 5 is the default
+ }
+
+ @Test
+ void listOfContaining_should_return_the_provided_elements_plus_some_randomly_generated_elements() {
+ // given
+ ValueProvider random = withRandomValues();
+
+ // when
+ List myBeans = random.listOfContaining(MyBeanTestData::myBean, myBeanContained(1), myBeanContained(2), myBeanContained(3));
+
+ // then
+ assertThat(myBeans).size().isLessThanOrEqualTo(7); // 3 contained beans + max. 1 random 'spacing' bean between each + max. 1 random bean at the beginning/end
+ assertThat(myBeans).contains(myBeanContained(1), myBeanContained(2), myBeanContained(3));
+ }
+
@Test
void ipV6Address_should_return_valid_IPv6_address() throws UnknownHostException {
ValueProvider random = withRandomValues();
@@ -673,4 +715,33 @@ private void assertBigDecimalNumberWithScale2(ValueProvider provider, Number min
.isGreaterThanOrEqualTo(new BigDecimal(min.doubleValue() - 0.01))
.isLessThanOrEqualTo(new BigDecimal(max.doubleValue() + 0.01));
}
+
+ static class MyBeanTestData {
+ public static MyBean myBean(ValueProvider valueProvider) {
+ return new MyBean("randomly generated");
+ }
+
+ public static MyBean myBeanContained(int counter) {
+ return new MyBean("contained" + counter);
+ }
+ }
+
+ @Data
+ static class MyBean {
+ String value;
+
+ public MyBean(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return EqualsBuilder.reflectionEquals(this, o, true);
+ }
+
+ @Override
+ public int hashCode() {
+ return HashCodeBuilder.reflectionHashCode(this, true);
+ }
+ }
}