Feature/randomutils secure() and insecure() (#1250)
* Add testLang1641() * Rename some test methods * Refactor RandomUtils and RandomStringUtils with secure() and insecure() instances
This commit is contained in:
parent
12c71a019f
commit
c95ee37dff
File diff suppressed because it is too large
Load Diff
|
@ -16,23 +16,78 @@
|
|||
*/
|
||||
package org.apache.commons.lang3;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Security;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.apache.commons.lang3.exception.UncheckedException;
|
||||
|
||||
/**
|
||||
* Utility library that supplements the standard {@link Random} class.
|
||||
* Supplements the standard {@link Random} class.
|
||||
* <p>
|
||||
* Use {@link #secure()} to get the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an
|
||||
* algorithms/providers specified in the {@code securerandom.strongAlgorithms} {@link Security} property.
|
||||
* </p>
|
||||
* <p>
|
||||
* Use {@link #insecure()} to get the singleton instance based on {@link ThreadLocalRandom#current()}; <b>which is not
|
||||
* cryptographically secure</b>.
|
||||
* </p>
|
||||
* <p>
|
||||
* Starting in version 3.15.0, this class uses {@link SecureRandom#getInstanceStrong()} for static methods.
|
||||
* </p>
|
||||
* <p>
|
||||
* Starting in version 3.16.0, this class uses {@link #secure()} for static methods and adds {@link #insecure()}.
|
||||
* </p>
|
||||
* <p>
|
||||
* Before version 3.15.0, this class used {@link ThreadLocalRandom#current()} for static methods, which is not
|
||||
* cryptographically secure.
|
||||
* </p>
|
||||
* <p>
|
||||
* Please note that the Apache Commons project provides a component dedicated to pseudo-random number generation, namely
|
||||
* <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a>, that may be a better choice for
|
||||
* applications with more stringent requirements (performance and/or correctness).
|
||||
* </p>
|
||||
*
|
||||
* <p>Please note that the Apache Commons project provides a component
|
||||
* dedicated to pseudo-random number generation, namely
|
||||
* <a href="https://commons.apache.org/proper/commons-rng/">Commons RNG</a>, that may be
|
||||
* a better choice for applications with more stringent requirements
|
||||
* (performance and/or correctness).</p>
|
||||
*
|
||||
* @deprecated Use Apache Commons RNG's optimized <a href="https://commons.apache.org/proper/commons-rng/commons-rng-client-api/apidocs/org/apache/commons/rng/UniformRandomProvider.html">UniformRandomProvider</a>
|
||||
* @see RandomStringUtils
|
||||
* @since 3.3
|
||||
*/
|
||||
@Deprecated
|
||||
public class RandomUtils {
|
||||
|
||||
private static RandomUtils INSECURE = new RandomUtils(ThreadLocalRandom::current);
|
||||
|
||||
private static final Supplier<Random> SECURE_SUPPLIER = () -> RandomUtils.SECURE_RANDOM.get();
|
||||
|
||||
private static RandomUtils SECURE = new RandomUtils(SECURE_SUPPLIER);
|
||||
|
||||
private static final ThreadLocal<SecureRandom> SECURE_RANDOM = ThreadLocal.withInitial(() -> {
|
||||
try {
|
||||
return SecureRandom.getInstanceStrong();
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
throw new UncheckedException(e);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets the singleton instance based on {@link ThreadLocalRandom#current()}; <b>which is not cryptographically
|
||||
* secure</b>; use {@link #secure()} to use an algorithms/providers specified in the
|
||||
* {@code securerandom.strongAlgorithms} {@link Security} property.
|
||||
* </p>
|
||||
* <p>
|
||||
* The method {@link ThreadLocalRandom#current()} is called on-demand.
|
||||
* </p>
|
||||
*
|
||||
* @return the singleton instance based on {@link ThreadLocalRandom#current()}.
|
||||
* @see ThreadLocalRandom#current()
|
||||
* @see #secure()
|
||||
* @since 3.16.0
|
||||
*/
|
||||
static RandomUtils insecure() {
|
||||
return INSECURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random boolean value.
|
||||
*
|
||||
|
@ -40,22 +95,18 @@ public class RandomUtils {
|
|||
* @since 3.5
|
||||
*/
|
||||
public static boolean nextBoolean() {
|
||||
return RandomStringUtils.random().nextBoolean();
|
||||
return secure().randomBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of random bytes.
|
||||
*
|
||||
* @param count
|
||||
* the size of the returned array
|
||||
* @param count the size of the returned array
|
||||
* @return the random byte array
|
||||
* @throws IllegalArgumentException if {@code count} is negative
|
||||
*/
|
||||
public static byte[] nextBytes(final int count) {
|
||||
Validate.isTrue(count >= 0, "Count cannot be negative.");
|
||||
final byte[] result = new byte[count];
|
||||
RandomStringUtils.random().nextBytes(result);
|
||||
return result;
|
||||
return secure().randomBytes(count);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,29 +117,20 @@ public class RandomUtils {
|
|||
* @since 3.5
|
||||
*/
|
||||
public static double nextDouble() {
|
||||
return nextDouble(0, Double.MAX_VALUE);
|
||||
return secure().randomDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random double within the specified range.
|
||||
*
|
||||
* @param startInclusive
|
||||
* the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive
|
||||
* the upper bound (not included)
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code startInclusive > endExclusive} or if
|
||||
* {@code startInclusive} is negative
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random double
|
||||
*/
|
||||
public static double nextDouble(final double startInclusive, final double endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive,
|
||||
"Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + (endExclusive - startInclusive) * RandomStringUtils.random().nextDouble();
|
||||
return secure().randomDouble(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,29 +141,20 @@ public class RandomUtils {
|
|||
* @since 3.5
|
||||
*/
|
||||
public static float nextFloat() {
|
||||
return nextFloat(0, Float.MAX_VALUE);
|
||||
return secure().randomFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random float within the specified range.
|
||||
*
|
||||
* @param startInclusive
|
||||
* the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive
|
||||
* the upper bound (not included)
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code startInclusive > endExclusive} or if
|
||||
* {@code startInclusive} is negative
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random float
|
||||
*/
|
||||
public static float nextFloat(final float startInclusive, final float endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive,
|
||||
"Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + (endExclusive - startInclusive) * RandomStringUtils.random().nextFloat();
|
||||
return secure().randomFloat(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,29 +165,20 @@ public class RandomUtils {
|
|||
* @since 3.5
|
||||
*/
|
||||
public static int nextInt() {
|
||||
return nextInt(0, Integer.MAX_VALUE);
|
||||
return secure().randomInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer within the specified range.
|
||||
*
|
||||
* @param startInclusive
|
||||
* the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive
|
||||
* the upper bound (not included)
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code startInclusive > endExclusive} or if
|
||||
* {@code startInclusive} is negative
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random integer
|
||||
*/
|
||||
public static int nextInt(final int startInclusive, final int endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive,
|
||||
"Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + RandomStringUtils.random().nextInt(endExclusive - startInclusive);
|
||||
return secure().randomInt(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,24 +189,213 @@ public class RandomUtils {
|
|||
* @since 3.5
|
||||
*/
|
||||
public static long nextLong() {
|
||||
return secure().randomLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@code long} value between 0 (inclusive) and the specified value (exclusive).
|
||||
*
|
||||
* @param n Bound on the random number to be returned. Must be positive.
|
||||
* @return a random {@code long} value between 0 (inclusive) and {@code n} (exclusive).
|
||||
*/
|
||||
private static long nextLong(final long n) {
|
||||
return secure().randomLong(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random long within the specified range.
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random long
|
||||
*/
|
||||
public static long nextLong(final long startInclusive, final long endExclusive) {
|
||||
return secure().randomLong(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the singleton instance based on {@link SecureRandom#getInstanceStrong()} which uses an algorithms/providers
|
||||
* specified in the {@code securerandom.strongAlgorithms} {@link Security} property.
|
||||
* <p>
|
||||
* The method {@link SecureRandom#getInstanceStrong()} is called on-demand.
|
||||
* </p>
|
||||
*
|
||||
* @return the singleton instance based on {@link SecureRandom#getInstanceStrong()}.
|
||||
* @see SecureRandom#getInstanceStrong()
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public static RandomUtils secure() {
|
||||
return SECURE;
|
||||
}
|
||||
|
||||
static SecureRandom secureRandom() {
|
||||
return SECURE_RANDOM.get();
|
||||
}
|
||||
|
||||
private final Supplier<Random> random;
|
||||
|
||||
/**
|
||||
* {@link RandomUtils} instances should NOT be constructed in standard programming. Instead, the class should be
|
||||
* used as {@code RandomUtils.nextBytes(5);}.
|
||||
* <p>
|
||||
* This constructor is public to permit tools that require a JavaBean instance to operate.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated TODO Make private in 4.0.
|
||||
*/
|
||||
@Deprecated
|
||||
public RandomUtils() {
|
||||
this(SECURE_SUPPLIER);
|
||||
}
|
||||
|
||||
private RandomUtils(final Supplier<Random> random) {
|
||||
this.random = random;
|
||||
}
|
||||
|
||||
Random random() {
|
||||
return random.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random boolean value.
|
||||
*
|
||||
* @return the random boolean
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public boolean randomBoolean() {
|
||||
return random().nextBoolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of random bytes.
|
||||
*
|
||||
* @param count the size of the returned array
|
||||
* @return the random byte array
|
||||
* @throws IllegalArgumentException if {@code count} is negative
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public byte[] randomBytes(final int count) {
|
||||
Validate.isTrue(count >= 0, "Count cannot be negative.");
|
||||
final byte[] result = new byte[count];
|
||||
random().nextBytes(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random double between 0 (inclusive) and Double.MAX_VALUE (exclusive).
|
||||
*
|
||||
* @return the random double
|
||||
* @see #nextDouble(double, double)
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public double randomDouble() {
|
||||
return nextDouble(0, Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random double within the specified range.
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random double
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public double randomDouble(final double startInclusive, final double endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + (endExclusive - startInclusive) * random().nextDouble();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random float between 0 (inclusive) and Float.MAX_VALUE (exclusive).
|
||||
*
|
||||
* @return the random float
|
||||
* @see #nextFloat(float, float)
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public float randomFloat() {
|
||||
return nextFloat(0, Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random float within the specified range.
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random float
|
||||
*/
|
||||
public float randomFloat(final float startInclusive, final float endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + (endExclusive - startInclusive) * random().nextFloat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random int between 0 (inclusive) and Integer.MAX_VALUE (exclusive).
|
||||
*
|
||||
* @return the random integer
|
||||
* @see #nextInt(int, int)
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public int randomInt() {
|
||||
return nextInt(0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer within the specified range.
|
||||
*
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random integer
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public int randomInt(final int startInclusive, final int endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
}
|
||||
return startInclusive + random().nextInt(endExclusive - startInclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random long between 0 (inclusive) and Long.MAX_VALUE (exclusive).
|
||||
*
|
||||
* @return the random long
|
||||
* @see #nextLong(long, long)
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public long randomLong() {
|
||||
return nextLong(Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a {@code long} value between 0 (inclusive) and the specified
|
||||
* value (exclusive).
|
||||
* Generates a {@code long} value between 0 (inclusive) and the specified value (exclusive).
|
||||
*
|
||||
* @param n Bound on the random number to be returned. Must be positive.
|
||||
* @return a random {@code long} value between 0 (inclusive) and {@code n}
|
||||
* (exclusive).
|
||||
* @param n Bound on the random number to be returned. Must be positive.
|
||||
* @return a random {@code long} value between 0 (inclusive) and {@code n} (exclusive).
|
||||
*/
|
||||
private static long nextLong(final long n) {
|
||||
private long randomLong(final long n) {
|
||||
// Extracted from o.a.c.rng.core.BaseProvider.nextLong(long)
|
||||
long bits;
|
||||
long val;
|
||||
do {
|
||||
bits = RandomStringUtils.random().nextLong() >>> 1;
|
||||
val = bits % n;
|
||||
bits = random().nextLong() >>> 1;
|
||||
val = bits % n;
|
||||
} while (bits - val + n - 1 < 0);
|
||||
return val;
|
||||
}
|
||||
|
@ -190,18 +403,15 @@ public class RandomUtils {
|
|||
/**
|
||||
* Generates a random long within the specified range.
|
||||
*
|
||||
* @param startInclusive
|
||||
* the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive
|
||||
* the upper bound (not included)
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code startInclusive > endExclusive} or if
|
||||
* {@code startInclusive} is negative
|
||||
* @param startInclusive the smallest value that can be returned, must be non-negative
|
||||
* @param endExclusive the upper bound (not included)
|
||||
* @throws IllegalArgumentException if {@code startInclusive > endExclusive} or if {@code startInclusive} is
|
||||
* negative
|
||||
* @return the random long
|
||||
* @since 3.16.0
|
||||
*/
|
||||
public static long nextLong(final long startInclusive, final long endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive,
|
||||
"Start value must be smaller or equal to end value.");
|
||||
public long randomLong(final long startInclusive, final long endExclusive) {
|
||||
Validate.isTrue(endExclusive >= startInclusive, "Start value must be smaller or equal to end value.");
|
||||
Validate.isTrue(startInclusive >= 0, "Both range values must be non-negative.");
|
||||
if (startInclusive == endExclusive) {
|
||||
return startInclusive;
|
||||
|
@ -209,19 +419,9 @@ public class RandomUtils {
|
|||
return startInclusive + nextLong(endExclusive - startInclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link RandomUtils} instances should NOT be constructed in standard
|
||||
* programming. Instead, the class should be used as
|
||||
* {@code RandomUtils.nextBytes(5);}.
|
||||
* <p>
|
||||
* This constructor is public to permit tools that require a JavaBean
|
||||
* instance to operate.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated TODO Make private in 4.0.
|
||||
*/
|
||||
@Deprecated
|
||||
public RandomUtils() {
|
||||
// empty
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RandomUtils [random=" + random() + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,19 +24,20 @@ import static org.hamcrest.Matchers.lessThan;
|
|||
import static org.hamcrest.Matchers.lessThanOrEqualTo;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* Tests {@link RandomStringUtils}.
|
||||
|
@ -45,6 +46,10 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
|
||||
private static final int LOOP_COUNT = 1_000;
|
||||
|
||||
static Stream<RandomStringUtils> randomProvider() {
|
||||
return Stream.of(RandomStringUtils.secure(), RandomStringUtils.insecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes Chi-Square statistic given observed and expected counts
|
||||
*
|
||||
|
@ -85,11 +90,6 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
@Test
|
||||
public void testConstructor() {
|
||||
assertNotNull(new RandomStringUtils());
|
||||
final Constructor<?>[] cons = RandomStringUtils.class.getDeclaredConstructors();
|
||||
assertEquals(1, cons.length);
|
||||
assertTrue(Modifier.isPublic(cons[0].getModifiers()));
|
||||
assertTrue(Modifier.isPublic(RandomStringUtils.class.getModifiers()));
|
||||
assertFalse(Modifier.isFinal(RandomStringUtils.class.getModifiers()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -108,31 +108,118 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(1, Integer.MIN_VALUE, -10, false, false, null));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandom(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, true, true));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, new char[] { 'a' }));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(1, new char[0]));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, ""));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, (String) null));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, 'a', 'z', false, false));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(-1, 'a', 'z', false, false, new char[] { 'a' }));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(8, 32, 48, false, true));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(8, 32, 65, true, false));
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.next(1, Integer.MIN_VALUE, -10, false, false, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomAlphabetic() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomAlphabetic(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandomAlphabetic(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.nextAlphabetic(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomAscii() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomAscii(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandomAscii(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.nextAscii(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomGraph() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomGraph(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandomGraph(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.nextGraph(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomNumeric() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomNumeric(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandomNumeric(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.nextNumeric(-1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceptionsRandomPrint() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.randomPrint(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExceptionsRandomPrint(final RandomStringUtils rsu) {
|
||||
assertThrows(IllegalArgumentException.class, () -> rsu.nextPrint(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test homogeneity of random strings generated -- i.e., test that characters show up with expected frequencies in generated strings. Will fail randomly
|
||||
* about 1 in 100,000 times. Repeated failures indicate a problem.
|
||||
*
|
||||
* @param rsu the instance to test.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testHomogeneity(final RandomStringUtils rsu) {
|
||||
final String set = "abc";
|
||||
final char[] chars = set.toCharArray();
|
||||
final int[] counts = { 0, 0, 0 };
|
||||
final int[] expected = { 200, 200, 200 };
|
||||
for (int i = 0; i < 100; i++) {
|
||||
final String gen = rsu.next(6, chars);
|
||||
for (int j = 0; j < 6; j++) {
|
||||
switch (gen.charAt(j)) {
|
||||
case 'a': {
|
||||
counts[0]++;
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
counts[1]++;
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
counts[2]++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fail("generated character not in set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Perform chi-square test with degrees of freedom = 3-1 = 2, testing at 1e-5 level.
|
||||
// This expects a failure rate of 1 in 100,000.
|
||||
// critical value: from scipy.stats import chi2; chi2(2).isf(1e-5)
|
||||
assertThat("test homogeneity -- will fail about 1 in 100,000 times", chiSquare(expected, counts), lessThan(23.025850929940457d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the string got by {@link RandomStringUtils#random(int)} can be converted to UTF-8 and back without loss.
|
||||
*
|
||||
|
@ -159,15 +246,44 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
assertEquals(orig, copy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the string got by {@link RandomStringUtils#random(int)} can be converted to UTF-8 and back without loss.
|
||||
*
|
||||
* @param rsu the instance to test
|
||||
* @see <a href="https://issues.apache.org/jira/browse/LANG-100">LANG-100</a>
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testLang100(final RandomStringUtils rsu) {
|
||||
final int size = 5000;
|
||||
final Charset charset = StandardCharsets.UTF_8;
|
||||
final String orig = rsu.next(size);
|
||||
final byte[] bytes = orig.getBytes(charset);
|
||||
final String copy = new String(bytes, charset);
|
||||
|
||||
// for a verbose compare:
|
||||
for (int i = 0; i < orig.length() && i < copy.length(); i++) {
|
||||
final char o = orig.charAt(i);
|
||||
final char c = copy.charAt(i);
|
||||
assertEquals(o, c, "differs at " + i + "(" + Integer.toHexString(Character.valueOf(o).hashCode()) + ","
|
||||
+ Integer.toHexString(Character.valueOf(c).hashCode()) + ")");
|
||||
}
|
||||
// compare length also
|
||||
assertEquals(orig.length(), copy.length());
|
||||
// just to be complete
|
||||
assertEquals(orig, copy);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLANG805() {
|
||||
final long seedMillis = System.currentTimeMillis();
|
||||
assertEquals("aaa", RandomStringUtils.random(3, 0, 0, false, false, new char[] { 'a' }, new Random(seedMillis)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLANG807() {
|
||||
final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> RandomStringUtils.random(3, 5, 5, false, false));
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testLANG807(final RandomStringUtils rsu) {
|
||||
final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> rsu.next(3, 5, 5, false, false));
|
||||
final String msg = ex.getMessage();
|
||||
assertTrue(msg.contains("start"), "Message (" + msg + ") must contain 'start'");
|
||||
assertTrue(msg.contains("end"), "Message (" + msg + ") must contain 'end'");
|
||||
|
@ -193,6 +309,29 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure boundary alpha characters are generated by randomAlphabetic This test will fail randomly with probability = 4 * (51/52)**1000 ~ 1.58E-8
|
||||
*
|
||||
* @param rsu the instance to test
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomAlphabetic(final RandomStringUtils rsu) {
|
||||
final char[] testChars = { 'a', 'z', 'A', 'Z' };
|
||||
final boolean[] found = { false, false, false, false };
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String randString = rsu.nextAlphabetic(10);
|
||||
for (int j = 0; j < testChars.length; j++) {
|
||||
if (randString.indexOf(testChars[j]) > 0) {
|
||||
found[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < testChars.length; i++) {
|
||||
assertTrue(found[i], "alphanumeric character not generated in 1000 attempts: " + testChars[i] + " -- repeated failures indicate a problem ");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomAlphabeticRange() {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
|
@ -218,6 +357,32 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomAlphabeticRange(final RandomStringUtils rsu) {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
final int expectedMaxLengthExclusive = 11;
|
||||
final String pattern = "^\\p{Alpha}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$";
|
||||
|
||||
int maxCreatedLength = expectedMinLengthInclusive;
|
||||
int minCreatedLength = expectedMaxLengthExclusive - 1;
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String s = rsu.nextAlphabetic(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1)));
|
||||
assertTrue(s.matches(pattern), s);
|
||||
|
||||
if (s.length() < minCreatedLength) {
|
||||
minCreatedLength = s.length();
|
||||
}
|
||||
|
||||
if (s.length() > maxCreatedLength) {
|
||||
maxCreatedLength = s.length();
|
||||
}
|
||||
}
|
||||
assertThat("min generated, may fail randomly rarely", minCreatedLength, is(expectedMinLengthInclusive));
|
||||
assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure boundary alphanumeric characters are generated by randomAlphaNumeric This test will fail randomly with probability = 6 * (61/62)**1000 ~ 5.2E-7
|
||||
*/
|
||||
|
@ -238,6 +403,29 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure boundary alphanumeric characters are generated by randomAlphaNumeric This test will fail randomly with probability = 6 * (61/62)**1000 ~ 5.2E-7
|
||||
*
|
||||
* @param rsu the instance to test
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomAlphaNumeric(final RandomStringUtils rsu) {
|
||||
final char[] testChars = { 'a', 'z', 'A', 'Z', '0', '9' };
|
||||
final boolean[] found = { false, false, false, false, false, false };
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String randString = rsu.nextAlphanumeric(10);
|
||||
for (int j = 0; j < testChars.length; j++) {
|
||||
if (randString.indexOf(testChars[j]) > 0) {
|
||||
found[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < testChars.length; i++) {
|
||||
assertTrue(found[i], "alphanumeric character not generated in 1000 attempts: " + testChars[i] + " -- repeated failures indicate a problem ");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomAlphanumericRange() {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
|
@ -264,15 +452,114 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Make sure 32 and 127 are generated by randomNumeric This test will fail randomly with probability = 2*(95/96)**1000 ~ 5.7E-5
|
||||
* Test the implementation
|
||||
*
|
||||
* @param rsu the instance to test.
|
||||
*/
|
||||
@Test
|
||||
public void testRandomAscii() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomApis(final RandomStringUtils rsu) {
|
||||
String r1 = rsu.next(50);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
String r2 = rsu.next(50);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextAscii(50);
|
||||
assertEquals(50, r1.length(), "randomAscii(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertThat("char >= 32 && <= 127", (int) r1.charAt(i), allOf(greaterThanOrEqualTo(32), lessThanOrEqualTo(127)));
|
||||
}
|
||||
r2 = rsu.nextAscii(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextAlphabetic(50);
|
||||
assertEquals(50, r1.length(), "randomAlphabetic(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isLetter(r1.charAt(i)) && !Character.isDigit(r1.charAt(i)), "r1 contains alphabetic");
|
||||
}
|
||||
r2 = rsu.nextAlphabetic(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextAlphanumeric(50);
|
||||
assertEquals(50, r1.length(), "randomAlphanumeric(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isLetterOrDigit(r1.charAt(i)), "r1 contains alphanumeric");
|
||||
}
|
||||
r2 = rsu.nextAlphabetic(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextGraph(50);
|
||||
assertEquals(50, r1.length(), "randomGraph(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(r1.charAt(i) >= 33 && r1.charAt(i) <= 126, "char between 33 and 126");
|
||||
}
|
||||
r2 = rsu.nextGraph(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextNumeric(50);
|
||||
assertEquals(50, r1.length(), "randomNumeric(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isDigit(r1.charAt(i)) && !Character.isLetter(r1.charAt(i)), "r1 contains numeric");
|
||||
}
|
||||
r2 = rsu.nextNumeric(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.nextPrint(50);
|
||||
assertEquals(50, r1.length(), "randomPrint(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(r1.charAt(i) >= 32 && r1.charAt(i) <= 126, "char between 32 and 126");
|
||||
}
|
||||
r2 = rsu.nextPrint(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
String set = "abcdefg";
|
||||
r1 = rsu.next(50, set);
|
||||
assertEquals(50, r1.length(), "random(50, \"abcdefg\")");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set");
|
||||
}
|
||||
r2 = rsu.next(50, set);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.next(50, (String) null);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
r2 = rsu.next(50, (String) null);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
set = "stuvwxyz";
|
||||
r1 = rsu.next(50, set.toCharArray());
|
||||
assertEquals(50, r1.length(), "random(50, \"stuvwxyz\")");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set");
|
||||
}
|
||||
r2 = rsu.next(50, set);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.next(50, (char[]) null);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
r2 = rsu.next(50, (char[]) null);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = rsu.next(0);
|
||||
assertEquals("", r1, "random(0).equals(\"\")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure 32 and 127 are generated by randomNumeric This test will fail randomly with probability = 2*(95/96)**1000 ~ 5.7E-5
|
||||
*
|
||||
* @param rsu the instance to test
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomAscii(final RandomStringUtils rsu) {
|
||||
final char[] testChars = { (char) 32, (char) 126 };
|
||||
final boolean[] found = { false, false };
|
||||
// Test failures have been observed on GitHub builds with a 100 limit.
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String randString = RandomStringUtils.randomAscii(10);
|
||||
final String randString = rsu.nextAscii(10);
|
||||
for (int j = 0; j < testChars.length; j++) {
|
||||
if (randString.indexOf(testChars[j]) > 0) {
|
||||
found[j] = true;
|
||||
|
@ -284,8 +571,9 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomAsciiRange() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomAsciiRange(final RandomStringUtils rsu) {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
final int expectedMaxLengthExclusive = 11;
|
||||
final String pattern = "^\\p{ASCII}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$";
|
||||
|
@ -293,7 +581,7 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
int maxCreatedLength = expectedMinLengthInclusive;
|
||||
int minCreatedLength = expectedMaxLengthExclusive - 1;
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String s = RandomStringUtils.randomAscii(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
final String s = rsu.nextAscii(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1)));
|
||||
assertTrue(s.matches(pattern), s);
|
||||
|
||||
|
@ -309,8 +597,9 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomGraphRange() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomGraphRange(final RandomStringUtils rsu) {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
final int expectedMaxLengthExclusive = 11;
|
||||
final String pattern = "^\\p{Graph}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$";
|
||||
|
@ -318,7 +607,7 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
int maxCreatedLength = expectedMinLengthInclusive;
|
||||
int minCreatedLength = expectedMaxLengthExclusive - 1;
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String s = RandomStringUtils.randomGraph(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
final String s = rsu.nextGraph(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1)));
|
||||
assertTrue(s.matches(pattern), s);
|
||||
|
||||
|
@ -336,13 +625,16 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
|
||||
/**
|
||||
* Make sure '0' and '9' are generated by randomNumeric This test will fail randomly with probability = 2 * (9/10)**1000 ~ 3.5E-46
|
||||
*
|
||||
* @param rsu the instance to test
|
||||
*/
|
||||
@Test
|
||||
public void testRandomNumeric() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomNumeric(final RandomStringUtils rsu) {
|
||||
final char[] testChars = { '0', '9' };
|
||||
final boolean[] found = { false, false };
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String randString = RandomStringUtils.randomNumeric(10);
|
||||
final String randString = rsu.nextNumeric(10);
|
||||
for (int j = 0; j < testChars.length; j++) {
|
||||
if (randString.indexOf(testChars[j]) > 0) {
|
||||
found[j] = true;
|
||||
|
@ -354,8 +646,9 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandomNumericRange() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomNumericRange(final RandomStringUtils rsu) {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
final int expectedMaxLengthExclusive = 11;
|
||||
final String pattern = "^\\p{Digit}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$";
|
||||
|
@ -363,7 +656,7 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
int maxCreatedLength = expectedMinLengthInclusive;
|
||||
int minCreatedLength = expectedMaxLengthExclusive - 1;
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String s = RandomStringUtils.randomNumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
final String s = rsu.nextNumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1)));
|
||||
assertTrue(s.matches(pattern), s);
|
||||
|
||||
|
@ -380,7 +673,16 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRandomPrintRange() {
|
||||
public void testRandomParameter() {
|
||||
final long seedMillis = System.currentTimeMillis();
|
||||
final String r1 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
|
||||
final String r2 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
|
||||
assertEquals(r1, r2, "r1.equals(r2)");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomPrintRange(final RandomStringUtils rsu) {
|
||||
final int expectedMinLengthInclusive = 1;
|
||||
final int expectedMaxLengthExclusive = 11;
|
||||
final String pattern = "^\\p{Print}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$";
|
||||
|
@ -388,7 +690,7 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
int maxCreatedLength = expectedMinLengthInclusive;
|
||||
int minCreatedLength = expectedMaxLengthExclusive - 1;
|
||||
for (int i = 0; i < LOOP_COUNT; i++) {
|
||||
final String s = RandomStringUtils.randomPrint(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
final String s = rsu.nextPrint(expectedMinLengthInclusive, expectedMaxLengthExclusive);
|
||||
assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1)));
|
||||
assertTrue(s.matches(pattern), s);
|
||||
|
||||
|
@ -404,162 +706,29 @@ public class RandomStringUtilsTest extends AbstractLangTest {
|
|||
assertThat("max generated, may fail randomly rarely", maxCreatedLength, is(expectedMaxLengthExclusive - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the implementation
|
||||
*/
|
||||
@Test
|
||||
public void testRandomStringUtils() {
|
||||
String r1 = RandomStringUtils.random(50);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
String r2 = RandomStringUtils.random(50);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomAscii(50);
|
||||
assertEquals(50, r1.length(), "randomAscii(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertThat("char >= 32 && <= 127", (int) r1.charAt(i), allOf(greaterThanOrEqualTo(32), lessThanOrEqualTo(127)));
|
||||
}
|
||||
r2 = RandomStringUtils.randomAscii(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomAlphabetic(50);
|
||||
assertEquals(50, r1.length(), "randomAlphabetic(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isLetter(r1.charAt(i)) && !Character.isDigit(r1.charAt(i)), "r1 contains alphabetic");
|
||||
}
|
||||
r2 = RandomStringUtils.randomAlphabetic(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomAlphanumeric(50);
|
||||
assertEquals(50, r1.length(), "randomAlphanumeric(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isLetterOrDigit(r1.charAt(i)), "r1 contains alphanumeric");
|
||||
}
|
||||
r2 = RandomStringUtils.randomAlphabetic(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomGraph(50);
|
||||
assertEquals(50, r1.length(), "randomGraph(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(r1.charAt(i) >= 33 && r1.charAt(i) <= 126, "char between 33 and 126");
|
||||
}
|
||||
r2 = RandomStringUtils.randomGraph(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomNumeric(50);
|
||||
assertEquals(50, r1.length(), "randomNumeric(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(Character.isDigit(r1.charAt(i)) && !Character.isLetter(r1.charAt(i)), "r1 contains numeric");
|
||||
}
|
||||
r2 = RandomStringUtils.randomNumeric(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.randomPrint(50);
|
||||
assertEquals(50, r1.length(), "randomPrint(50) length");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(r1.charAt(i) >= 32 && r1.charAt(i) <= 126, "char between 32 and 126");
|
||||
}
|
||||
r2 = RandomStringUtils.randomPrint(50);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
String set = "abcdefg";
|
||||
r1 = RandomStringUtils.random(50, set);
|
||||
assertEquals(50, r1.length(), "random(50, \"abcdefg\")");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set");
|
||||
}
|
||||
r2 = RandomStringUtils.random(50, set);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.random(50, (String) null);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
r2 = RandomStringUtils.random(50, (String) null);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
set = "stuvwxyz";
|
||||
r1 = RandomStringUtils.random(50, set.toCharArray());
|
||||
assertEquals(50, r1.length(), "random(50, \"stuvwxyz\")");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(set.indexOf(r1.charAt(i)) > -1, "random char in set");
|
||||
}
|
||||
r2 = RandomStringUtils.random(50, set);
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.random(50, (char[]) null);
|
||||
assertEquals(50, r1.length(), "random(50) length");
|
||||
r2 = RandomStringUtils.random(50, (char[]) null);
|
||||
assertEquals(50, r2.length(), "random(50) length");
|
||||
assertFalse(r1.equals(r2), "!r1.equals(r2)");
|
||||
|
||||
final long seedMillis = System.currentTimeMillis();
|
||||
r1 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
|
||||
r2 = RandomStringUtils.random(50, 0, 0, true, true, null, new Random(seedMillis));
|
||||
assertEquals(r1, r2, "r1.equals(r2)");
|
||||
|
||||
r1 = RandomStringUtils.random(0);
|
||||
assertEquals("", r1, "random(0).equals(\"\")");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test homogeneity of random strings generated -- i.e., test that characters show up with expected frequencies in generated strings. Will fail randomly
|
||||
* about 1 in 100,000 times. Repeated failures indicate a problem.
|
||||
*/
|
||||
@Test
|
||||
public void testRandomStringUtilsHomog() {
|
||||
final String set = "abc";
|
||||
final char[] chars = set.toCharArray();
|
||||
final int[] counts = { 0, 0, 0 };
|
||||
final int[] expected = { 200, 200, 200 };
|
||||
for (int i = 0; i < 100; i++) {
|
||||
final String gen = RandomStringUtils.random(6, chars);
|
||||
for (int j = 0; j < 6; j++) {
|
||||
switch (gen.charAt(j)) {
|
||||
case 'a': {
|
||||
counts[0]++;
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
counts[1]++;
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
counts[2]++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fail("generated character not in set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Perform chi-square test with degrees of freedom = 3-1 = 2, testing at 1e-5 level.
|
||||
// This expects a failure rate of 1 in 100,000.
|
||||
// critical value: from scipy.stats import chi2; chi2(2).isf(1e-5)
|
||||
assertThat("test homogeneity -- will fail about 1 in 100,000 times", chiSquare(expected, counts), lessThan(23.025850929940457d));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test {@code RandomStringUtils.random} works appropriately when chars specified.
|
||||
*
|
||||
* @param rsu the instance to test.
|
||||
*/
|
||||
@Test
|
||||
void testRandomWithChars() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testRandomWithChars(final RandomStringUtils rsu) {
|
||||
final char[] digitChars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
|
||||
|
||||
String r1, r2, r3;
|
||||
|
||||
r1 = RandomStringUtils.random(50, 0, 0, true, true, digitChars);
|
||||
r1 = rsu.next(50, 0, 0, true, true, digitChars);
|
||||
assertEquals(50, r1.length(), "randomNumeric(50)");
|
||||
for (int i = 0; i < r1.length(); i++) {
|
||||
assertTrue(
|
||||
Character.isDigit(r1.charAt(i)) && !Character.isLetter(r1.charAt(i)),
|
||||
"r1 contains numeric");
|
||||
}
|
||||
r2 = RandomStringUtils.randomNumeric(50);
|
||||
r2 = rsu.nextNumeric(50);
|
||||
assertNotEquals(r1, r2);
|
||||
|
||||
r3 = RandomStringUtils.random(50, 0, 0, true, true, digitChars);
|
||||
r3 = rsu.next(50, 0, 0, true, true, digitChars);
|
||||
assertNotEquals(r1, r3);
|
||||
assertNotEquals(r2, r3);
|
||||
}
|
||||
|
|
|
@ -22,16 +22,16 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|||
import static org.hamcrest.Matchers.lessThan;
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
/**
|
||||
* Tests for {@link RandomUtils}
|
||||
|
@ -43,6 +43,10 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
*/
|
||||
private static final double DELTA = 1e-5;
|
||||
|
||||
static Stream<RandomUtils> randomProvider() {
|
||||
return Stream.of(RandomUtils.secure(), RandomUtils.insecure());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next boolean
|
||||
*/
|
||||
|
@ -52,14 +56,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertTrue(result || !result);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testBoolean(final RandomUtils ru) {
|
||||
final boolean result = ru.randomBoolean();
|
||||
assertTrue(result || !result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor() {
|
||||
assertNotNull(new RandomUtils());
|
||||
final Constructor<?>[] cons = RandomUtils.class.getDeclaredConstructors();
|
||||
assertEquals(1, cons.length);
|
||||
assertTrue(Modifier.isPublic(cons[0].getModifiers()));
|
||||
assertTrue(Modifier.isPublic(RandomUtils.class.getModifiers()));
|
||||
assertFalse(Modifier.isFinal(RandomUtils.class.getModifiers()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,6 +77,13 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertTrue(result >= 0 && result <= Double.MAX_VALUE); // TODO: should be <max?
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExtremeRangeDouble(final RandomUtils ru) {
|
||||
final double result = ru.randomDouble(0, Double.MAX_VALUE);
|
||||
assertTrue(result >= 0 && result <= Double.MAX_VALUE); // TODO: should be <max?
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
|
@ -80,6 +93,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertTrue(result >= 0f && result <= Float.MAX_VALUE); // TODO: should be <max?
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExtremeRangeFloat(final RandomUtils ru) {
|
||||
final float result = ru.randomFloat(0, Float.MAX_VALUE);
|
||||
assertTrue(result >= 0f && result <= Float.MAX_VALUE); // TODO: should be <max?
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
|
@ -89,6 +112,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 0 && result < Integer.MAX_VALUE", result, allOf(greaterThanOrEqualTo(0), lessThan(Integer.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExtremeRangeInt(final RandomUtils ru) {
|
||||
final int result = ru.randomInt(0, Integer.MAX_VALUE);
|
||||
assertThat("result >= 0 && result < Integer.MAX_VALUE", result, allOf(greaterThanOrEqualTo(0), lessThan(Integer.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
|
@ -98,6 +131,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 0 && result < Long.MAX_VALUE", result, allOf(greaterThanOrEqualTo(0L), lessThan(Long.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests extreme range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testExtremeRangeLong(final RandomUtils ru) {
|
||||
final long result = ru.randomLong(0, Long.MAX_VALUE);
|
||||
assertThat("result >= 0 && result < Long.MAX_VALUE", result, allOf(greaterThanOrEqualTo(0L), lessThan(Long.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a large value for long. A previous implementation using
|
||||
* {@link RandomUtils#nextDouble(double, double)} could generate a value equal
|
||||
|
@ -122,6 +165,31 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test a large value for long. A previous implementation using
|
||||
* {@link RandomUtils#nextDouble(double, double)} could generate a value equal
|
||||
* to the upper limit.
|
||||
*
|
||||
* <pre>
|
||||
* return (long) nextDouble(startInclusive, endExclusive);
|
||||
* </pre>
|
||||
*
|
||||
* <p>See LANG-1592.</p>
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testLargeValueRangeLong(final RandomUtils ru) {
|
||||
final long startInclusive = 12900000000001L;
|
||||
final long endExclusive = 12900000000016L;
|
||||
// Note: The method using 'return (long) nextDouble(startInclusive, endExclusive)'
|
||||
// takes thousands of calls to generate an error. This size loop fails most
|
||||
// of the time with the previous method.
|
||||
final int n = (int) (endExclusive - startInclusive) * 1000;
|
||||
for (int i = 0; i < n; i++) {
|
||||
assertNotEquals(endExclusive, ru.randomLong(startInclusive, endExclusive));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests random byte array.
|
||||
*/
|
||||
|
@ -131,11 +199,27 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertEquals(20, result.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests random byte array.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextBytes(final RandomUtils ru) {
|
||||
final byte[] result = ru.randomBytes(20);
|
||||
assertEquals(20, result.length);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextBytesNegative() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextBytes(-1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextBytesNegative(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomBytes(-1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next double range.
|
||||
*/
|
||||
|
@ -145,11 +229,27 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 33d && result < 42d", result, allOf(greaterThanOrEqualTo(33d), lessThan(42d)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next double range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextDouble(final RandomUtils ru) {
|
||||
final double result = ru.randomDouble(33d, 42d);
|
||||
assertThat("result >= 33d && result < 42d", result, allOf(greaterThanOrEqualTo(33d), lessThan(42d)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextDoubleLowerGreaterUpper() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextDouble(2, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextDoubleLowerGreaterUpper(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomDouble(2, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next double range with minimal range.
|
||||
*/
|
||||
|
@ -158,11 +258,26 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertEquals(42.1, RandomUtils.nextDouble(42.1, 42.1), DELTA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next double range with minimal range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextDoubleMinimalRange(final RandomUtils ru) {
|
||||
assertEquals(42.1, ru.randomDouble(42.1, 42.1), DELTA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextDoubleNegative() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextDouble(-1, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextDoubleNegative(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomDouble(-1, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next double range, random result.
|
||||
*/
|
||||
|
@ -172,6 +287,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("randomResult >= 0 0 && randomResult < Double.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0d), lessThan(Double.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next double range, random result.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextDoubleRandomResult(final RandomUtils ru) {
|
||||
final double randomResult = ru.randomDouble();
|
||||
assertThat("randomResult >= 0 0 && randomResult < Double.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0d), lessThan(Double.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next float range.
|
||||
*/
|
||||
|
@ -181,11 +306,27 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 33f && result < 42f", result, allOf(greaterThanOrEqualTo(33f), lessThan(42f)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next float range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextFloat(final RandomUtils ru) {
|
||||
final float result = ru.randomFloat(33f, 42f);
|
||||
assertThat("result >= 33f && result < 42f", result, allOf(greaterThanOrEqualTo(33f), lessThan(42f)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextFloatLowerGreaterUpper() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextFloat(2, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextFloatLowerGreaterUpper(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomFloat(2, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next float range with minimal range.
|
||||
*/
|
||||
|
@ -194,11 +335,26 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertEquals(42.1f, RandomUtils.nextFloat(42.1f, 42.1f), DELTA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next float range with minimal range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextFloatMinimalRange(final RandomUtils ru) {
|
||||
assertEquals(42.1f, ru.randomFloat(42.1f, 42.1f), DELTA);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextFloatNegative() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextFloat(-1, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextFloatNegative(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomFloat(-1, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next float range, random result.
|
||||
*/
|
||||
|
@ -208,6 +364,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("randomResult >= 0 && randomResult < Double.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0f), lessThan(Float.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next float range, random result.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextFloatRandomResult(final RandomUtils ru) {
|
||||
final float randomResult = ru.randomFloat();
|
||||
assertThat("randomResult >= 0 && randomResult < Double.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0f), lessThan(Float.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next int range.
|
||||
*/
|
||||
|
@ -217,11 +383,27 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 33 && result < 42", result, allOf(greaterThanOrEqualTo(33), lessThan(42)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next int range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextInt(final RandomUtils ru) {
|
||||
final int result = ru.randomInt(33, 42);
|
||||
assertThat("result >= 33 && result < 42", result, allOf(greaterThanOrEqualTo(33), lessThan(42)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextIntLowerGreaterUpper() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextInt(2, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextIntLowerGreaterUpper(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomInt(2, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next int range with minimal range.
|
||||
*/
|
||||
|
@ -230,11 +412,26 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertEquals(42, RandomUtils.nextInt(42, 42));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next int range with minimal range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextIntMinimalRange(final RandomUtils ru) {
|
||||
assertEquals(42, ru.randomInt(42, 42));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextIntNegative() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextInt(-1, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextIntNegative(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomInt(-1, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next int range, random result.
|
||||
*/
|
||||
|
@ -245,6 +442,17 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertTrue(randomResult < Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next int range, random result.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextIntRandomResult(final RandomUtils ru) {
|
||||
final int randomResult = ru.randomInt();
|
||||
assertTrue(randomResult > 0);
|
||||
assertTrue(randomResult < Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next long range.
|
||||
*/
|
||||
|
@ -254,11 +462,27 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("result >= 33L && result < 42L", result, allOf(greaterThanOrEqualTo(33L), lessThan(42L)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next long range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextLong(final RandomUtils ru) {
|
||||
final long result = ru.randomLong(33L, 42L);
|
||||
assertThat("result >= 33L && result < 42L", result, allOf(greaterThanOrEqualTo(33L), lessThan(42L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextLongLowerGreaterUpper() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextLong(2, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextLongLowerGreaterUpper(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomLong(2, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next long range with minimal range.
|
||||
*/
|
||||
|
@ -267,11 +491,26 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertEquals(42L, RandomUtils.nextLong(42L, 42L));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test next long range with minimal range.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextLongMinimalRange(final RandomUtils ru) {
|
||||
assertEquals(42L, ru.randomLong(42L, 42L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextLongNegative() {
|
||||
assertThrows(IllegalArgumentException.class, () -> RandomUtils.nextLong(-1, 1));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextLongNegative(final RandomUtils ru) {
|
||||
assertThrows(IllegalArgumentException.class, () -> ru.randomLong(-1, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next long range, random result.
|
||||
*/
|
||||
|
@ -281,6 +520,16 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
assertThat("randomResult >= 0 && randomResult < Long.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0L), lessThan(Long.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests next long range, random result.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testNextLongRandomResult(final RandomUtils ru) {
|
||||
final long randomResult = ru.randomLong();
|
||||
assertThat("randomResult >= 0 && randomResult < Long.MAX_VALUE", randomResult, allOf(greaterThanOrEqualTo(0L), lessThan(Long.MAX_VALUE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a zero byte array length.
|
||||
*/
|
||||
|
@ -288,4 +537,13 @@ public class RandomUtilsTest extends AbstractLangTest {
|
|||
public void testZeroLengthNextBytes() {
|
||||
assertArrayEquals(new byte[0], RandomUtils.nextBytes(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a zero byte array length.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("randomProvider")
|
||||
public void testZeroLengthNextBytes(final RandomUtils ru) {
|
||||
assertArrayEquals(new byte[0], ru.randomBytes(0));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue