20
20
import java .util .Locale ;
21
21
import java .util .Optional ;
22
22
import java .util .function .Function ;
23
+ import java .util .function .Supplier ;
23
24
import java .util .regex .Matcher ;
24
25
import java .util .regex .Pattern ;
25
26
import java .util .regex .PatternSyntaxException ;
@@ -186,35 +187,64 @@ public static String generate(String pattern, int min, int max) {
186
187
String cleanedPattern = cleanPattern (pattern );
187
188
String flattenedPattern = RegexFlattener .flattenRegex (cleanedPattern );
188
189
190
+ List <Supplier <Optional <String >>> attempts = List .of (
191
+ () -> generateString (pattern , min , max , cleanedPattern , flattenedPattern ),
192
+ () -> generateString (cleanedPattern , min , max , cleanedPattern , flattenedPattern ),
193
+ () -> generateString (cleanedPattern , min , max , cleanedPattern , cleanedPattern ),
194
+ () -> generateString (flattenedPattern , min , max , cleanedPattern , flattenedPattern ),
195
+ () -> generateString (flattenedPattern , min , max , flattenedPattern , flattenedPattern )
196
+ );
197
+
198
+ return attempts .stream ()
199
+ .flatMap (attempt -> attempt .get ().stream ())
200
+ .findFirst ()
201
+ .orElseThrow (() -> new IllegalArgumentException (
202
+ String .format ("Could not generate a string for pattern %s with min %d and max %d" , pattern , min , max )
203
+ ));
204
+ }
205
+
206
+ private static Optional <String > generateString (String pattern , int min , int max , String cleanedPattern , String flattenedPattern ) {
189
207
String valueBasedOnSimpleRegexes = tryGenerateWithSimpleRegexes (pattern , min , max , cleanedPattern );
190
208
191
209
if (valueBasedOnSimpleRegexes != null ) {
192
- return valueBasedOnSimpleRegexes ;
210
+ return Optional . of ( valueBasedOnSimpleRegexes ) ;
193
211
}
194
212
195
213
GeneratorParams generatorParams = new GeneratorParams (flattenedPattern , min , max , cleanedPattern );
196
214
197
- String generatedWithRgxGenerator = callGenerateTwice ( StringGenerator :: generateUsingRgxGenerator , generatorParams );
198
- if (generatedWithRgxGenerator != null ) {
199
- return generatedWithRgxGenerator ;
215
+ Optional < String > generatedWithInitialMinMax = callGeneratorsInOrder ( generatorParams );
216
+ if (generatedWithInitialMinMax . isPresent () ) {
217
+ return generatedWithInitialMinMax ;
200
218
}
201
219
202
220
if (min == -1 && max == -1 ) {
203
- GeneratorParams generatorParamsWithMinMax = new GeneratorParams (flattenedPattern , 0 , 300 , cleanedPattern );
204
- return generateUsingRegexpGen (generatorParamsWithMinMax );
221
+ GeneratorParams generatorParamsWithMinMax = new GeneratorParams (flattenedPattern , 1 , 300 , cleanedPattern );
222
+
223
+ Optional <String > generatedWithAdjustedMinMax = callGeneratorsInOrder (generatorParamsWithMinMax );
224
+ if (generatedWithAdjustedMinMax .isPresent ()) {
225
+ return generatedWithAdjustedMinMax ;
226
+ }
205
227
}
206
228
207
- String generatedUsingCatsRegexGenerator = callGenerateTwice (StringGenerator ::generateUsingCatsRegexGenerator , generatorParams );
208
- if (generatedUsingCatsRegexGenerator != null ) {
209
- return generatedUsingCatsRegexGenerator ;
229
+ return Optional .empty ();
230
+ }
231
+
232
+ private static Optional <String > callGeneratorsInOrder (GeneratorParams generatorParams ) {
233
+ String rgxGeneratedWithMinMax = callGenerateTwice (StringGenerator ::generateUsingRgxGenerator , generatorParams );
234
+ if (rgxGeneratedWithMinMax != null ) {
235
+ return Optional .of (rgxGeneratedWithMinMax );
210
236
}
211
237
212
- String generateUsingRegexpGen = callGenerateTwice (StringGenerator ::generateUsingRegexpGen , generatorParams );
213
- if (generateUsingRegexpGen != null ) {
214
- return generateUsingRegexpGen ;
238
+ String generatedWithCatsRegexGenerator = callGenerateTwice (StringGenerator ::generateUsingCatsRegexGenerator , generatorParams );
239
+ if (generatedWithCatsRegexGenerator != null ) {
240
+ return Optional . of ( generatedWithCatsRegexGenerator ) ;
215
241
}
216
242
217
- throw new IllegalArgumentException ("Could not generate a string for pattern " + pattern + " with min " + min + " and max " + max );
243
+ String generatedWithRegexpGen = callGenerateTwice (StringGenerator ::generateUsingRegexpGen , generatorParams );
244
+ if (generatedWithRegexpGen != null ) {
245
+ return Optional .of (generatedWithRegexpGen );
246
+ }
247
+ return Optional .empty ();
218
248
}
219
249
220
250
public static String tryGenerateWithSimpleRegexes (String originalPattern , int min , int max , String cleanedPattern ) {
@@ -239,7 +269,10 @@ public static String callGenerateTwice(Function<GeneratorParams, String> generat
239
269
LOGGER .debug ("Generator {} failed #atempt 1" , generator .getClass ().getSimpleName ());
240
270
}
241
271
try {
242
- String secondVersion = generator .apply (new GeneratorParams (removeLookaheadAssertions (generatorParams .cleanedPattern ()), generatorParams .min , generatorParams .max , generatorParams .originalPattern ()));
272
+ String patternWithLookaheadsRemoved = removeLookaheadAssertions (generatorParams .cleanedPattern ());
273
+ LOGGER .debug ("Pattern with lookaheads removed {}" , patternWithLookaheadsRemoved );
274
+
275
+ String secondVersion = generator .apply (new GeneratorParams (patternWithLookaheadsRemoved , generatorParams .min , generatorParams .max , generatorParams .originalPattern ()));
243
276
if (secondVersion .matches (generatorParams .originalPattern ())) {
244
277
LOGGER .debug ("Generated value with lookaheads removed " + secondVersion + " matched " + generatorParams .originalPattern ());
245
278
return secondVersion ;
@@ -604,7 +637,7 @@ public static List<String> getUnsupportedMediaTypes() {
604
637
*/
605
638
public static String removeLookaheadAssertions (String regex ) {
606
639
regex = regex .replaceAll ("\\ (\\ ?=([^)]*)\\ )" , "($1)" );
607
- regex = regex .replaceAll ("\\ (\\ ?!([^)]*)\\ )" , "(^$1) " );
640
+ regex = regex .replaceAll ("\\ (\\ ?!([^)]*)\\ )" , "" );
608
641
regex = regex .replaceAll ("\\ (\\ ?<=([^)]*)\\ )" , "($1)" );
609
642
regex = regex .replaceAll ("\\ (\\ ?<!([^)]*)\\ )" , "(^$1)" );
610
643
0 commit comments