From ec2fa6bd5695b36435cc66ca4cdd8183d077a0cf Mon Sep 17 00:00:00 2001 From: Caleb Cushing Date: Sun, 28 Jun 2015 02:06:27 -0500 Subject: [PATCH] LANG-1224: Extend RandomStringUtils with methods that generate strings between a min and max length (closes #101, closes #157) --- src/changes/changes.xml | 1 + .../commons/lang3/RandomStringUtils.java | 93 ++++++++++- .../commons/lang3/RandomStringUtilsTest.java | 155 ++++++++++++++++++ 3 files changed, 245 insertions(+), 4 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index d7ebb42fa..954ffedc8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -46,6 +46,7 @@ The type attribute can be add,update,fix,remove. + Extend RandomStringUtils with methods that generate strings between a min and max length Handle "void" in ClassUtils.getClass() SerializationUtils#deserialize has unnecessary code and a comment for that JavaDoc for ArrayUtils.isNotEmpty() is slightly misleading diff --git a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java index 3db461f1a..fdcf87f68 100644 --- a/src/main/java/org/apache/commons/lang3/RandomStringUtils.java +++ b/src/main/java/org/apache/commons/lang3/RandomStringUtils.java @@ -81,7 +81,22 @@ public class RandomStringUtils { public static String randomAscii(final int count) { return random(count, 32, 127, false, false); } - + + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of characters whose + * ASCII value is between {@code 32} and {@code 126} (inclusive).

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomAscii(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAscii(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters * specified.

@@ -95,7 +110,21 @@ public class RandomStringUtils { public static String randomAlphabetic(final int count) { return random(count, true, false); } - + + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of alphabetic characters.

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomAlphabetic(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAlphabetic(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters * specified.

@@ -109,7 +138,21 @@ public class RandomStringUtils { public static String randomAlphanumeric(final int count) { return random(count, true, true); } - + + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of alpha-numeric characters.

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomAlphanumeric(final int minLengthInclusive, final int maxLengthExclusive) { + return randomAlphanumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters specified.

* @@ -124,7 +167,21 @@ public class RandomStringUtils { public static String randomGraph(final int count) { return random(count, 33, 126, false, false); } - + + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of \p{Graph} characters.

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomGraph(final int minLengthInclusive, final int maxLengthExclusive) { + return randomGraph(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters * specified.

@@ -139,6 +196,20 @@ public class RandomStringUtils { return random(count, false, true); } + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of \p{Digit} characters.

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomNumeric(final int minLengthInclusive, final int maxLengthExclusive) { + return randomNumeric(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters specified.

* @@ -154,6 +225,20 @@ public class RandomStringUtils { return random(count, 32, 126, false, false); } + /** + *

Creates a random string whose length is between the inclusive minimum and + * the exclusive maximum.

+ * + *

Characters will be chosen from the set of \p{Print} characters.

+ * + * @param minLengthInclusive the inclusive minimum length of the string to generate + * @param maxLengthExclusive the exclusive maximum length of the string to generate + * @return the random string + */ + public static String randomPrint(final int minLengthInclusive, final int maxLengthExclusive) { + return randomPrint(RandomUtils.nextInt(minLengthInclusive, maxLengthExclusive)); + } + /** *

Creates a random string whose length is the number of characters * specified.

diff --git a/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java b/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java index 7cd71e886..28c014b87 100644 --- a/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/RandomStringUtilsTest.java @@ -16,9 +16,14 @@ */ package org.apache.commons.lang3; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -299,6 +304,156 @@ public class RandomStringUtilsTest { } } } + + @Test + public void testRandomAsciiRange() { + final int expectedMinLengthInclusive = 1; + final int expectedMaxLengthExclusive = 11; + final String pattern = "^\\p{ASCII}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; + + int maxCreatedLength = expectedMinLengthInclusive; + int minCreatedLength = expectedMaxLengthExclusive - 1; + for (int i = 0; i < 1000; i++) { + final String s = RandomStringUtils.randomAscii(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } + + @Test + public void testRandomAlphabeticRange() { + 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 < 1000; i++) { + final String s = RandomStringUtils.randomAlphabetic(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } + + @Test + public void testRandomAlphanumericRange() { + final int expectedMinLengthInclusive = 1; + final int expectedMaxLengthExclusive = 11; + final String pattern = "^\\p{Alnum}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; + + int maxCreatedLength = expectedMinLengthInclusive; + int minCreatedLength = expectedMaxLengthExclusive - 1; + for (int i = 0; i < 1000; i++) { + final String s = RandomStringUtils.randomAlphanumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } + + @Test + public void testRandomGraphRange() { + final int expectedMinLengthInclusive = 1; + final int expectedMaxLengthExclusive = 11; + final String pattern = "^\\p{Graph}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; + + int maxCreatedLength = expectedMinLengthInclusive; + int minCreatedLength = expectedMaxLengthExclusive - 1; + for (int i = 0; i < 1000; i++) { + final String s = RandomStringUtils.randomGraph(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } + + @Test + public void testRandomNumericRange() { + final int expectedMinLengthInclusive = 1; + final int expectedMaxLengthExclusive = 11; + final String pattern = "^\\p{Digit}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; + + int maxCreatedLength = expectedMinLengthInclusive; + int minCreatedLength = expectedMaxLengthExclusive - 1; + for (int i = 0; i < 1000; i++) { + final String s = RandomStringUtils.randomNumeric(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } + + @Test + public void testRandomPrintRange() { + final int expectedMinLengthInclusive = 1; + final int expectedMaxLengthExclusive = 11; + final String pattern = "^\\p{Print}{" + expectedMinLengthInclusive + ',' + expectedMaxLengthExclusive + "}$"; + + int maxCreatedLength = expectedMinLengthInclusive; + int minCreatedLength = expectedMaxLengthExclusive - 1; + for (int i = 0; i < 1000; i++) { + final String s = RandomStringUtils.randomPrint(expectedMinLengthInclusive, expectedMaxLengthExclusive); + assertThat("within range", s.length(), allOf(greaterThanOrEqualTo(expectedMinLengthInclusive), lessThanOrEqualTo(expectedMaxLengthExclusive - 1))); + assertTrue(s, s.matches(pattern)); + + 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)); + } /** * Test homogeneity of random strings generated --