Skip to content

Commit

Permalink
Add RandomDurationBuilde
Browse files Browse the repository at this point in the history
  • Loading branch information
mkutz committed Aug 19, 2024
1 parent a2fb664 commit ab7e8c1
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 0 deletions.
67 changes: 67 additions & 0 deletions modules/random/src/main/java/org/stubit/random/RandomDuration.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,80 @@
package org.stubit.random;

import java.security.SecureRandom;
import java.time.Duration;

/** Generates random {@link Duration}s. */
public class RandomDuration {

private RandomDuration() {}

/**
* @param minInclusive the minimum value (inclusive)
* @param maxInclusive the maximum value (inclusive)
* @return a random {@link Duration} between {@code minInclusive} and {@code maxInclusive}
*/
public static Duration aDurationBetween(Duration minInclusive, Duration maxInclusive) {
return Duration.ofSeconds(
RandomLong.aLongBetween(minInclusive.toSeconds(), maxInclusive.toSeconds()));
}

/**
* @return a {@link Duration} between {@link Duration#ZERO} and {@link Long#MAX_VALUE} seconds
*/
public static RandomDurationBuilder aDuration() {
return new RandomDurationBuilder(Duration.ZERO, Duration.ofSeconds(Long.MAX_VALUE));
}

/** Builds a random {@link Duration} within a specified range. */
public static class RandomDurationBuilder {

private final SecureRandom secureRandom = new SecureRandom();
private Duration minInclusive;
private Duration maxInclusive;

private RandomDurationBuilder(Duration min, Duration max) {
this.minInclusive = min;
this.maxInclusive = max;
}

/**
* @param minInclusive the minimum value (inclusive)
* @return this
* @throws IllegalArgumentException if {@code minInclusive} is greater than or equal to {@link
* #maxInclusive}
*/
public RandomDurationBuilder min(Duration minInclusive) {
this.minInclusive = minInclusive;
if (minInclusive.compareTo(maxInclusive) > 0) {
throw new IllegalArgumentException(
"Can't set min to %s, as it must not be greater than max (%s)"
.formatted(minInclusive, maxInclusive));
}
return this;
}

/**
* @param maxInclusive the maximum value (inclusive)
* @return this
* @throws IllegalArgumentException if {@code maxInclusive} is less than or equal to {@link
* #minInclusive}
*/
public RandomDurationBuilder max(Duration maxInclusive) {
if (minInclusive.compareTo(maxInclusive) > 0) {
throw new IllegalArgumentException(
"Can't set max to %s, as it must not be less than min (%s)"
.formatted(maxInclusive, minInclusive));
}
this.maxInclusive = maxInclusive;
return this;
}

/**
* @return a random {@link Duration} between {@link #minInclusive} and {@link #maxInclusive}
*/
public Duration build() {
return Duration.ofSeconds(
secureRandom.nextLong(minInclusive.toSeconds(), maxInclusive.toSeconds()));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.stubit.random;

import static java.lang.Long.MAX_VALUE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.stubit.random.RandomInt.aPositiveInt;

import java.time.Duration;
import org.junit.jupiter.api.Test;

class RandomDurationBuilderTest {

@Test
void aDuration() {
assertThat(RandomDuration.aDuration().build()).isPositive();
}

@Test
void min() {
Duration min = Duration.ofDays(aPositiveInt());
assertThat(RandomDuration.aDuration().min(min).build()).isGreaterThanOrEqualTo(min);
}

@Test
void max() {
Duration max = Duration.ofDays(aPositiveInt());
assertThat(RandomDuration.aDuration().max(max).build()).isLessThanOrEqualTo(max);
}

@Test
void max_less_than_min() {
Duration min = Duration.ofDays(aPositiveInt());
Duration max = min.minus(Duration.ofSeconds(1));
assertThatIllegalArgumentException()
.isThrownBy(() -> RandomDuration.aDuration().min(min).max(max))
.withMessage("Can't set max to %s, as it must not be less than min (%s)", max, min);
}

@Test
void min_greater_than_max() {
Duration max = Duration.ofDays(aPositiveInt());
Duration min = max.plusSeconds(1);
assertThatIllegalArgumentException()
.isThrownBy(() -> RandomDuration.aDuration().max(max).min(min))
.withMessage("Can't set min to %s, as it must not be greater than max (%s)", min, max);
}

@Test
void maximum() {
Duration max = Duration.ofSeconds(MAX_VALUE);
assertThat(max).isPositive();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.stubit.random;

import static java.lang.Long.MAX_VALUE;
import static java.lang.Long.MIN_VALUE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;

import org.junit.jupiter.api.Test;

class RandomLongBuilderTest {

@Test
void aLong() {
assertThat(RandomLong.aLong().build()).isBetween(MIN_VALUE, MAX_VALUE);
}

@Test
void min() {
long min = 10L;
assertThat(RandomLong.aLong().min(min).build()).isGreaterThanOrEqualTo(min);
}

@Test
void min_MAX_VALUE_minus_1() {
long min = MAX_VALUE - 1;
assertThat(RandomLong.aLong().min(min).build()).isEqualTo(min);
}

@Test
void max() {
long max = 10L;
assertThat(RandomLong.aLong().max(max).build()).isLessThanOrEqualTo(max);
}

@Test
void max_MIN_VALUE() {
long max = MIN_VALUE;
assertThat(RandomLong.aLong().max(max).build()).isEqualTo(max);
}

@Test
void max_less_than_min() {
long min = 42L;
assertThatIllegalArgumentException()
.isThrownBy(() -> RandomLong.aLong().min(min).max(min - 1))
.withMessage("Can't set max to 41, as it must not be less than min (42)");
}

@Test
void min_greater_than_max() {
long max = 42L;
assertThatIllegalArgumentException()
.isThrownBy(() -> RandomLong.aLong().max(max).min(max + 1))
.withMessage("Can't set min to 43, as it must not be greater than max (42)");
}

@Test
void max_MAX_VALUE() {
assertThatIllegalArgumentException()
.isThrownBy(() -> RandomLong.aLong().max(MAX_VALUE))
.withMessage("Can't set max to 9223372036854775807 (Long.MAX_VALUE)");
}
}

0 comments on commit ab7e8c1

Please sign in to comment.