Skip to content

Commit 747df61

Browse files
committed
#1659 fix method faker.text().text(1, 64, true, false, true)
... to return a valid string of length 2..64 instead of empty string.
1 parent 146947c commit 747df61

File tree

4 files changed

+126
-28
lines changed

4 files changed

+126
-28
lines changed

src/main/java/net/datafaker/providers/base/Lorem.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,12 @@ public String characters(int fixedNumberOfCharacters) {
4848
}
4949

5050
public String characters(int fixedNumberOfCharacters, boolean includeUppercase) {
51-
return faker.credentials().password(fixedNumberOfCharacters, fixedNumberOfCharacters, includeUppercase);
51+
return faker.text().text(fixedNumberOfCharacters, fixedNumberOfCharacters, includeUppercase);
5252
}
5353

5454
public String characters(int minimumLength, int maximumLength,
5555
boolean includeUppercase, boolean includeSpecial, boolean includeDigit) {
56-
return faker.credentials().password(minimumLength, maximumLength, includeUppercase, includeSpecial, includeDigit);
56+
return faker.text().text(minimumLength, maximumLength, includeUppercase, includeSpecial, includeDigit);
5757
}
5858

5959
public String characters(int fixedNumberOfCharacters, boolean includeUppercase, boolean includeDigit) {
@@ -62,7 +62,7 @@ public String characters(int fixedNumberOfCharacters, boolean includeUppercase,
6262

6363
public String characters(int fixedNumberOfCharacters,
6464
boolean includeUppercase, boolean includeSpecial, boolean includeDigit) {
65-
return faker.credentials().password(fixedNumberOfCharacters, fixedNumberOfCharacters, includeUppercase, includeSpecial, includeDigit);
65+
return faker.text().text(fixedNumberOfCharacters, fixedNumberOfCharacters, includeUppercase, includeSpecial, includeDigit);
6666
}
6767

6868
public List<String> words(int num) {

src/main/java/net/datafaker/providers/base/Text.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,38 @@ public String text(int minimumLength, int maximumLength, boolean includeUppercas
6666
return text(minimumLength, maximumLength, includeUppercase, includeSpecial, false);
6767
}
6868

69-
public String text(int minimumLength, int maximumLength, boolean includeUppercase, boolean includeSpecial, boolean includeDigit) {
69+
public String text(int requestedMinimumLength, int maximumLength, boolean includeUppercase, boolean includeSpecial, boolean includeDigit) {
70+
if (requestedMinimumLength > maximumLength) {
71+
throw new IllegalArgumentException("Min length (%s) should be not greater than max length (%s)".formatted(
72+
requestedMinimumLength, maximumLength));
73+
}
74+
75+
final int minimumLength = Math.max(requestedMinimumLength, min(includeUppercase) + min(includeSpecial) + min(includeDigit));
76+
if (minimumLength > maximumLength) {
77+
throw new IllegalArgumentException("Minimum number of required characters (%s) should be not greater than max length (%s)".formatted(
78+
minimumLength, maximumLength));
79+
}
80+
7081
final int len = faker.number().numberBetween(minimumLength, maximumLength + 1);
7182
TextConfigPojo pojo = new TextConfigPojo(len, includeUppercase, includeSpecial, includeDigit);
72-
Text.TextRuleConfig config = configMap.get(pojo);
73-
if (config == null) {
83+
Text.TextRuleConfig config = configMap.computeIfAbsent(pojo, (x) -> {
7484
TextSymbolsBuilder builder =
7585
TextSymbolsBuilder.builder()
7686
.with(Text.EN_LOWERCASE);
7787
if (includeUppercase) builder = builder.with(Text.EN_UPPERCASE, 1);
7888
if (includeSpecial) builder = builder.with(Text.DEFAULT_SPECIAL, 1);
7989
if (includeDigit) builder = builder.with(Text.DIGITS, 1);
8090

81-
config = builder.len(len).build();
82-
configMap.putIfAbsent(pojo, config);
83-
}
91+
return builder.len(len).throwIfLengthSmall(true).build();
92+
});
8493

8594
return text(config);
8695
}
8796

97+
private static int min(boolean requireSomeKindOfSymbols) {
98+
return requireSomeKindOfSymbols ? 1 : 0;
99+
}
100+
88101
public static final String EN_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
89102
public static final String EN_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
90103
public static final String DIGITS = "0123456789";
@@ -102,6 +115,9 @@ public static class TextRuleConfig {
102115
private final int numberOfRequiredSymbols;
103116

104117
private TextRuleConfig(int fixedNumberOfCharacters, Map<String, Integer> map, int numberOfRequiredSymbols) {
118+
assert numberOfRequiredSymbols >= 0;
119+
assert fixedNumberOfCharacters >= numberOfRequiredSymbols;
120+
105121
this.fixedNumberOfCharacters = fixedNumberOfCharacters;
106122
this.numberOfRequiredSymbols = numberOfRequiredSymbols;
107123
this.textKeys = new char[map.size()][];
@@ -200,10 +216,10 @@ public TextRuleConfig build() {
200216
* {@code final String customSpecialSymbols = "!@#$%^*;'][{}";}.
201217
*/
202218
public String text(TextRuleConfig textRuleConfig) {
203-
final int fixedNumberOfCharacters = textRuleConfig.getFixedNumberOfCharacters();
219+
int fixedNumberOfCharacters = textRuleConfig.getFixedNumberOfCharacters();
204220
final int numberOfRequiredSymbols = textRuleConfig.getNumberOfRequiredSymbols();
205221
if (fixedNumberOfCharacters < numberOfRequiredSymbols) {
206-
return "";
222+
fixedNumberOfCharacters = numberOfRequiredSymbols;
207223
}
208224
char[] buffer = new char[fixedNumberOfCharacters];
209225
int idx = 0;

src/test/java/net/datafaker/providers/base/LoremTest.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.regex.Pattern;
1313

1414
import static org.assertj.core.api.Assertions.assertThat;
15+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1516

1617
class LoremTest extends BaseFakerTest {
1718

@@ -74,7 +75,9 @@ void testCharactersWithLength() {
7475
assertThat(lorem.characters(2)).matches("[a-z\\d]{2}");
7576
assertThat(lorem.characters(500)).matches("[a-z\\d]{500}");
7677
assertThat(lorem.characters(0)).isEmpty();
77-
assertThat(lorem.characters(-1)).isEmpty();
78+
assertThatThrownBy(() -> lorem.characters(-1))
79+
.isInstanceOf(IllegalArgumentException.class)
80+
.hasMessage("Minimum number of required characters (0) should be not greater than max length (-1)");
7881
}
7982

8083
@Test
@@ -84,7 +87,14 @@ void testCharactersWithLengthIncludeUppercase() {
8487
assertThat(lorem.characters(2, true)).matches("[a-zA-Z\\d]{2}");
8588
assertThat(lorem.characters(500, true)).matches("[a-zA-Z\\d]{500}");
8689
assertThat(lorem.characters(0, false)).isEmpty();
87-
assertThat(lorem.characters(-1, true)).isEmpty();
90+
assertThat(lorem.characters(1, true)).matches("[A-Z]");
91+
92+
assertThatThrownBy(() -> lorem.characters(-1, false))
93+
.isInstanceOf(IllegalArgumentException.class)
94+
.hasMessage("Minimum number of required characters (0) should be not greater than max length (-1)");
95+
assertThatThrownBy(() -> lorem.characters(0, true))
96+
.isInstanceOf(IllegalArgumentException.class)
97+
.hasMessage("Minimum number of required characters (1) should be not greater than max length (0)");
8898
}
8999

90100
@Test
@@ -109,11 +119,16 @@ void testCharactersFixedLengthIncludingUppercaseAndIncludingDigit() {
109119

110120
@Test
111121
void testFixedNumberOfCharactersEmpty() {
112-
assertThat(lorem.characters(-1)).isEmpty();
113122
assertThat(lorem.characters(0)).isEmpty();
114-
115-
assertThat(lorem.characters(-1, true, true, true)).isEmpty();
116123
assertThat(lorem.characters(0, false, false, false)).isEmpty();
124+
125+
assertThatThrownBy(() -> lorem.characters(-1, true, true, true))
126+
.isInstanceOf(IllegalArgumentException.class)
127+
.hasMessage("Minimum number of required characters (3) should be not greater than max length (-1)");
128+
129+
assertThatThrownBy(() -> lorem.characters(-1))
130+
.isInstanceOf(IllegalArgumentException.class)
131+
.hasMessage("Minimum number of required characters (0) should be not greater than max length (-1)");
117132
}
118133

119134

src/test/java/net/datafaker/providers/base/TextTest.java

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
import java.util.regex.Pattern;
99

10+
import static net.datafaker.providers.base.Text.DEFAULT_SPECIAL;
1011
import static net.datafaker.providers.base.Text.DIGITS;
1112
import static net.datafaker.providers.base.Text.EN_LOWERCASE;
1213
import static net.datafaker.providers.base.Text.EN_UPPERCASE;
1314
import static org.assertj.core.api.Assertions.assertThat;
1415
import static org.assertj.core.api.Assertions.assertThatThrownBy;
1516

1617
class TextTest {
18+
private static final Pattern characterPattern = Pattern.compile("[A-Za-z]");
1719
private final Faker faker = new Faker();
1820

1921
@Test
@@ -57,7 +59,8 @@ void exceptionIfLengthIsShorterThanNumberOfRequiredSymbols() {
5759
.with(DIGITS, 1)
5860
.throwIfLengthSmall(true)
5961
.build()))
60-
.isInstanceOf(IllegalArgumentException.class);
62+
.isInstanceOf(IllegalArgumentException.class)
63+
.hasMessage("Min length (1) should be not smaller than number of required characters (3)");
6164
}
6265

6366
@Test
@@ -99,11 +102,8 @@ void everyTextShouldContainLowerCaseUpperCaseAndDigit() {
99102

100103
@Test
101104
void testCharacter() {
102-
final Pattern characterPattern = Pattern.compile("[A-Za-z]");
103-
for (int i = 0; i < 100; i++) {
104-
Character character = faker.text().character();
105-
assertThat(character.toString()).matches(characterPattern);
106-
}
105+
Character character = faker.text().character();
106+
assertThat(character.toString()).matches(characterPattern);
107107
}
108108

109109
@RepeatedTest((100))
@@ -122,16 +122,83 @@ void testLowercaseCharacter() {
122122
void testFixedLengthText() {
123123
for (int i = 0; i < 100; i++) {
124124
String text = faker.text().text(i);
125-
assertThat(text).hasSize(i);
125+
assertThat(text).hasSize(i).matches("[a-z]*");
126126
}
127127
}
128128

129-
@Test
129+
@RepeatedTest(10)
130130
void testDefaultLengthText() {
131-
for (int i = 0; i < 100; i++) {
132-
String text = faker.text().text();
133-
assertThat(text).hasSizeBetween(20, 80);
134-
}
131+
String text = faker.text().text();
132+
assertThat(text).hasSizeBetween(20, 80).matches("[a-z]{20,80}");
133+
}
134+
135+
@RepeatedTest(10)
136+
void upTo64LowerCase() {
137+
assertThat(faker.text().text(1, 64, false, false, false)).matches("[a-z]{1,64}");
138+
assertThat(faker.text().text(2, 64, false, false, false)).matches("[a-z]{2,64}");
139+
assertThat(faker.text().text(64, 64, false, false, false)).matches("[a-z]{64}");
140+
}
141+
142+
@Test
143+
void zeroLength() {
144+
assertThat(faker.text().text(0, 0, false, false, false)).isEqualTo("");
145+
}
146+
147+
@Test
148+
void oneLowerCase() {
149+
assertThat(faker.text().text(1, 1, false, false, false)).matches("[a-z]");
150+
assertThat(faker.text().text(0, 1, false, false, false)).matches("[a-z]?");
151+
}
152+
153+
@RepeatedTest(10)
154+
void oneWithUpperCase() {
155+
assertThat(faker.text().text(1, 1, true, false, false)).matches("[A-Z]");
135156
}
136157

158+
@RepeatedTest(10)
159+
void oneWithDigit() {
160+
assertThat(faker.text().text(1, 1, false, false, true)).matches("[0-9]");
161+
}
162+
163+
@RepeatedTest(10)
164+
void oneWithSpecialSymbol() {
165+
assertThat(faker.text().text(1, 1, false, true, false)).matches("[" + DEFAULT_SPECIAL + "]");
166+
}
167+
168+
@RepeatedTest(10)
169+
void twoWithUpperCaseAndDigit() {
170+
assertThat(faker.text().text(2, 2, true, false, true)).matches("[A-Z0-9]{2}");
171+
}
172+
173+
@RepeatedTest(10)
174+
void twoWithLowerAndUpperCaseAndDigit() {
175+
assertThat(faker.text().text(2, 2, true, false, true)).matches("[a-zA-Z0-9]{2}");
176+
assertThat(faker.text().text(3, 3, true, true, true)).matches("[a-zA-Z0-9" + DEFAULT_SPECIAL + "]{3}");
177+
}
178+
179+
@Test
180+
void minLengthCannotBeGreaterThanMaxLength() {
181+
assertThatThrownBy(() -> faker.text().text(22, 21, false, false, false))
182+
.isInstanceOf(IllegalArgumentException.class)
183+
.hasMessage("Min length (22) should be not greater than max length (21)");
184+
185+
assertThatThrownBy(() -> faker.text().text(3, 2, true, true, true))
186+
.isInstanceOf(IllegalArgumentException.class)
187+
.hasMessage("Min length (3) should be not greater than max length (2)");
188+
}
189+
190+
@Test
191+
void isNotEnoughLengthToContainAllRequiredSymbols() {
192+
assertThatThrownBy(() -> faker.text().text(0, 0, true, false, false))
193+
.isInstanceOf(IllegalArgumentException.class)
194+
.hasMessage("Minimum number of required characters (1) should be not greater than max length (0)");
195+
assertThatThrownBy(() -> faker.text().text(1, 2, true, true, true))
196+
.isInstanceOf(IllegalArgumentException.class)
197+
.hasMessage("Minimum number of required characters (3) should be not greater than max length (2)");
198+
}
199+
200+
@RepeatedTest(10)
201+
void minimumLengthIsNotEnoughToContainAllRequiredSymbols() {
202+
assertThat(faker.text().text(1, 4, true, false, true)).matches("[a-zA-Z0-9]{2,4}");
203+
}
137204
}

0 commit comments

Comments
 (0)