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

Add methods for more customizable Date and DateTime sampling ISSUE#5 #34

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 100 additions & 10 deletions core/src/main/java/com/tngtech/valueprovider/AbstractValueProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
Expand Down Expand Up @@ -585,18 +584,57 @@ public LocalDate fixedLocalDate() {
}

/**
* Draws a {@link LocalDate} in [1st of January of {@code begin} ; 31st of December of {@code end}].

* Draws a {@link LocalDate} in [1st of January of {@code startYear} ; 31st of December of {@code endYear}].
*
* @param startYear the earliest year to draw from.
* @param endYear the latest year to draw from.
* @return the drawn {@link LocalDate}.
* @throws IllegalArgumentException if {@code endYear} < {@code startYear}.
*/
public LocalDate localDateBetweenYears(int startYear, int endYear) {
LocalDate start = LocalDate.ofYearDay(startYear, 1);
LocalDate end = LocalDate.of(endYear, 12, 31);
return localDateBetween(start, end);
}

/**
* Draws a {@link LocalDate} in [{@code start} ; {@code end}].
*
* @param start the earliest date to draw from.
* @param end the latest date to draw from.
* @return the drawn {@link LocalDate}.
* @throws IllegalArgumentException if {@code start} > {@code end}.
*/
public LocalDate localDateBetween(LocalDate start, LocalDate end) {
checkArgument(beforeOrEqual(start, end), "start %s must be before or equal end %s", start, end);
return start.plusDays(longNumber(0, DAYS.between(start, end)));
}

private boolean beforeOrEqual(LocalDate start, LocalDate end) {
return start.isBefore(end) || start.isEqual(end);
}

/**
* Draws a {@link LocalDate} in [{@code today-pastDuration} ; {@code today}].
*
* @param begin minimum year to draw from.
* @param end maximum year to draw from.
* @param pastDuration the maximum duration in the past to consider drawing from.
* @return the drawn {@link LocalDate}.
* @throws IllegalArgumentException if {@code end} < {@code begin}.
*/
public LocalDate localDateBetweenYears(int begin, int end) {
checkArgument(begin <= end, "begin %s must be before end %s", begin, end);
LocalDate lower = LocalDate.of(begin, Month.JANUARY, 1);
LocalDate upper = LocalDate.of(end, Month.DECEMBER, 31);
return lower.plusDays(longNumber(0, DAYS.between(lower, upper)));
public LocalDate localDateInPast(Duration pastDuration) {
LocalDate start = fixedLocalDate().minusDays(pastDuration.toDays());
return localDateBetween(start, fixedLocalDate());
}

/**
* Draws a {@link LocalDate} in [{@code today} ; {@code today+futureDuration}].
*
* @param futureDuration the maximum duration in the future to consider drawing from.
* @return the drawn {@link LocalDate}.
*/
public LocalDate localDateInFuture(Duration futureDuration) {
LocalDate end = fixedLocalDate().plusDays(futureDuration.toDays());
return localDateBetween(fixedLocalDate(), end);
}

/**
Expand All @@ -609,6 +647,58 @@ public LocalTime localTime() {
return LocalTime.ofSecondOfDay(longNumber(0, secondsPerDay - 1));
}

/**
* Draws a {@link LocalDateTime} in [{@code start} ; {@code end}].
*
* @param start the earliest date time to draw from.
* @param end the latest date time to draw from.
* @return the drawn {@link LocalDateTime}.
* @throws IllegalArgumentException if {@code start} &gt; {@code end}.
*/
public LocalDateTime localDateTimeBetween(LocalDateTime start, LocalDateTime end) {
checkArgument(beforeOrEqual(start, end), "start %s must be before or equal end %s", start, end);
return start.plusSeconds(longNumber(0, SECONDS.between(start, end)));
}

private boolean beforeOrEqual(LocalDateTime start, LocalDateTime end) {
return start.isBefore(end) || start.isEqual(end);
}

/**
* Draws a {@link LocalDateTime} in [{@code start} T00:00:00 ; {@code end} T23:59:59].
*
* @param start the earliest date to draw from.
* @param end the latest date to draw from.
* @return the drawn {@link LocalDateTime}.
* @throws IllegalArgumentException if {@code start} &gt; {@code end}.
*/
public LocalDateTime localDateTimeBetween(LocalDate start, LocalDate end) {
return localDateTimeBetween(start.atStartOfDay(), end.atTime(23, 59, 59));
}

/**
* Generates a {@link Duration} in [0 ; {@code max}].
*
* @param max the upper bound of the generated {@link Duration}.
* @return the generated {@link Duration}.
*/
public Duration duration(Duration max) {
return Duration.ofMillis(longNumber(0, max.toMillis()));
}

/**
* Generates a {@link Duration} in [{@code min} ; {@code max}].
*
* @param min the lower bound of the generated {@link Duration}.
* @param max the upper bound of the generated {@link Duration}.
* @return the generated {@link Duration}.
* @throws IllegalArgumentException if {@code min} &gt; {@code max}.
*/
public Duration duration(Duration min, Duration max) {
checkArgument(min.compareTo(max) <= 0, "min %s must be less than or equal max %s", min, max);
return Duration.ofMillis(longNumber(min.toMillis(), max.toMillis()));
}

/**
* Draws one element from the elements of an Enum class.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.Duration;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
Expand All @@ -21,6 +27,7 @@
import java.util.stream.Stream;

import lombok.Data;

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
Expand Down Expand Up @@ -94,7 +101,16 @@ private static Collection<MethodInvocation> allMethodInvocations() {
String address = random.lowercaseString(stringLength);
int min = random.intNumber(100, 1000);
int max = random.intNumber(1001, 2000);
LocalDate start = random.localDateBetweenYears(min, max);
LocalDate end = random.localDateBetweenYears(
random.intNumber(3000, 4000),
random.intNumber(4001, 10000)
);
Duration duration = Duration.ofDays(Long.valueOf(min));
LocalTime time = random.localTime();
int numLines = random.intNumber(2, 10);
Duration minDuration = Duration.ofHours(1);
Duration maxDuration = Duration.ofDays(1);

return newArrayList(
invoke("booleanValue"),
Expand Down Expand Up @@ -123,7 +139,14 @@ private static Collection<MethodInvocation> allMethodInvocations() {
invoke("fixedLocalDate"),
invoke("localDateBetweenYears", min, max),
invoke("localTime"),
invoke("duration", maxDuration),
invoke("duration", minDuration, maxDuration),
invoke("fixedLocalDateTime"),
invoke("localDateBetween", start, end),
invoke("localDateInPast", duration),
invoke("localDateInFuture", duration),
invoke("localDateTimeBetween", LocalDateTime.of(start, time), LocalDateTime.of(end, time)),
invoke("localDateTimeBetween", start, end),
invoke("fixedDecoratedStrings", numLines),
invoke("fixedDecoratedStrings", numLines, random.randomString(stringLength))
);
Expand Down Expand Up @@ -538,6 +561,74 @@ void numericString_should_reject_too_small_length_wrt_min() {
assertThat(thrown.getMessage()).contains("" + tooSmallLength, "" + min);
}

@Test
void localDateInBetween_should_generate_value_in_between() {
LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.of(2040, 12, 31);
assertThat(withRandomValues().localDateBetween(start, end)).isAfterOrEqualTo(start)
.isBeforeOrEqualTo(end);
}

@Test
void localDateInBetween_should_reject_temporal_inconsistency() {
LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.of(2040, 12, 31);
Throwable thrown = assertThrows(IllegalArgumentException.class,
() -> withRandomValues().localDateBetween(end, start));
assertThat(thrown.getMessage()).contains("must be before or equal end ");
}

@Test
void localDateInPast_should_return_value_in_allowed_range() {
LocalDate today = LocalDate.now();
Duration duration = Duration.ofDays(300);
LocalDate pastDate = today.minusDays(duration.toDays());
assertThat(withRandomValues().localDateInPast(duration)).isAfterOrEqualTo(pastDate)
.isBeforeOrEqualTo(today);
}

@Test
void localDateInFuture_should_return_value_in_allowed_range() {
LocalDate today = LocalDate.now();
Duration duration = Duration.ofDays(300);
LocalDate futureDate = today.plusDays(duration.toDays());
assertThat(withRandomValues().localDateInFuture(duration)).isAfterOrEqualTo(today)
.isBeforeOrEqualTo(futureDate);
}

@Test
void localDateTimeInBetween_should_generate_value_in_between() {
LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.of(2040, 12, 31);
assertThat(withRandomValues().localDateTimeBetween(start, end))
.isAfterOrEqualTo(LocalDateTime.of(start, LocalTime.MIN))
.isBeforeOrEqualTo(LocalDateTime.of(end, LocalTime.MAX));
}

@Test
void localDateTimeInBetween_should_reject_temporal_inconsistency() {
LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.of(2040, 12, 31);
Throwable thrown = assertThrows(IllegalArgumentException.class,
() -> withRandomValues().localDateTimeBetween(end, start));
assertThat(thrown.getMessage()).contains("must be before or equal end ");
}

@Test
void duration_should_be_smaller_than_max_duration() {
ValueProvider random = withRandomValues();
assertThat(random.duration(Duration.ofDays(1)))
.isLessThanOrEqualTo(Duration.ofDays(1));
}

@Test
void duration_should_be_bigger_than_min_and_smaller_than_max_duration() {
ValueProvider random = withRandomValues();
assertThat(random.duration(Duration.ofMinutes(1), Duration.ofDays(1)))
.isGreaterThanOrEqualTo(Duration.ofMinutes(1))
.isLessThanOrEqualTo(Duration.ofDays(1));
}

@Test
void oneOf_should_return_single_value() {
ValueProvider random = withRandomValues();
Expand Down