Skip to content

Commit 0a8ab0c

Browse files
Release 2.0.0 (#11)
1 parent c8c0bd5 commit 0a8ab0c

File tree

4 files changed

+74
-17
lines changed

4 files changed

+74
-17
lines changed

README.md

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# rexexp-gen
22

3-
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.cornutum.regexp/regexp-gen/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/org.cornutum.regexp/regexp-gen)
4-
[![javadoc](https://javadoc.io/badge2/org.cornutum.regexp/regexp-gen/javadoc.svg?style=plastic)](https://javadoc.io/doc/org.cornutum.regexp/regexp-gen)
3+
[![Maven](https://img.shields.io/badge/maven-2.0.0-green.svg)](https://search.maven.org/search?q=regexp-gen)
4+
[![Javadoc](https://img.shields.io/badge/javadoc-2.0.0-green.svg)](https://javadoc.io/doc/org.cornutum.regexp/regexp-gen/latest/index.html)
55

66
## Contents ##
77

@@ -10,6 +10,7 @@
1010
* [How Does It Work?](#how-does-it-work)
1111
* [The basics](#the-basics)
1212
* [Exact matches vs. substring matches](#exact-matches-vs-substring-matches)
13+
* [Want strings that _DON'T_ match?](#want-strings-that-dont-match)
1314
* [What matches "dot"?](#what-matches-dot)
1415
* [How to create longer matching strings](#how-to-create-longer-matching-strings)
1516
* [How to generate random matches repeatably](#how-to-generate-random-matches-repeatably)
@@ -18,7 +19,7 @@
1819

1920
## What's New? ##
2021

21-
* The latest version ([1.2.4](https://github.com/Cornutum/regexp-gen/releases/tag/release-1.2.4))
22+
* The latest version ([2.0.0](https://github.com/Cornutum/regexp-gen/releases/tag/release-2.0.0))
2223
is now available at the [Maven Central Repository](https://search.maven.org/search?q=regexp-gen).
2324

2425
## What Is It? ##
@@ -37,7 +38,7 @@ Here's a simple example of how to use a `RegExpGen`.
3738
```java
3839
import org.cornutum.regexpgen.RandomGen;
3940
import org.cornutum.regexpgen.RegExpGen;
40-
import org.cornutum.regexpgen.js.Parser;
41+
import org.cornutum.regexpgen.js.Provider;
4142
import org.cornutum.regexpgen.random.RandomBoundsGen;
4243

4344
// Given a JavaScript regular expression...
@@ -47,7 +48,7 @@ String regexp = "^Regular expressions are ((odd|hard|stupid), )+but cool!$";
4748
RandomGen random = new RandomBoundsGen();
4849

4950
// ...create a RegExpGen instance...
50-
RegExpGen generator = Parser.parseRegExp( regexp);
51+
RegExpGen generator = Provider.forEcmaScript().matching( regexp);
5152

5253
for( int i = 0; i < 3; i++)
5354
{
@@ -75,7 +76,7 @@ least one substring that matches". For example, consider what happens when you r
7576
String regexp = "(Hello|Howdy|Allô), world!";
7677

7778
// ...create a RegExpGen instance...
78-
RegExpGen generator = Parser.parseRegExp( regexp);
79+
RegExpGen generator = Provider.forEcmaScript().matching( regexp);
7980
...
8081
```
8182

@@ -92,15 +93,15 @@ These strings contain not only a substring that matches the regular expression,
9293
general "substring match", that's exactly what you want to give it.
9394

9495
But what if you need to generate only "exact" matches? In other words, strings containing only the matching characters.
95-
To do that, use `Parser.parseRegExpExact()`.
96+
To do that, use `Provider.matchingExact()`.
9697

9798
```java
9899
...
99100
// Given a JavaScript regular expression...
100101
String regexp = "(Hello|Howdy|Allô), world!";
101102

102103
// ...create a RegExpGen instance...
103-
RegExpGen generator = Parser.parseRegExpExact( regexp);
104+
RegExpGen generator = Provider.forEcmaScript().matchingExact( regexp);
104105
...
105106
```
106107

@@ -112,6 +113,35 @@ Allô, world!
112113
Howdy, world!
113114
```
114115

116+
### Want strings that _DON'T_ match? ###
117+
118+
You can also create a `RegExpGen` that generates strings that _don't_ match a specified regular expression. This is handy when
119+
you're testing a system that applies a regular expression and you want to see what happens when it gets invalid input. Here's how to do it.
120+
121+
```java
122+
...
123+
// Given a JavaScript regular expression...
124+
String regexp = "(Hello|Howdy|Allô), world!";
125+
126+
// ...create a RegExpGen instance...
127+
RegExpGen generator =
128+
Provider.forEcmaScript().notMatching( regexp)
129+
.orElseThrow( () -> new IllegalStateException( String.format( "Unable to generate string not matching '%s'", regexp)));
130+
131+
...
132+
```
133+
134+
Run with this change and the result will look like this:
135+
136+
```
137+
HHHAA
138+
3)!)5!':<
139+
"+#6)!%;)*8/ 28
140+
```
141+
142+
Note that `Provider.notMatching()` returns an optional result. Why? Because some regular expressions will match any string, making it
143+
impossible to generate strings that don't match. For example, there is no string that doesn't match `".*"`.
144+
115145
### What matches "dot"? ###
116146

117147
What matches the regular expression `.`? In general, any printable character. For a `RegExpGen`, by default, that means "any printable character
@@ -129,7 +159,7 @@ String regexp = regexp( "<< My secret is [^\\d\\s]{8,32} >>");
129159
RandomGen random = getRandomGen();
130160

131161
// ...create a RegExpGen instance...
132-
RegExpGen generator = Parser.parseRegExp( regexp);
162+
RegExpGen generator = Provider.forEcmaScript().matching( regexp);
133163

134164
// ...matching "." with specific characters...
135165
generator.getOptions().setAnyPrintableChars( "1001 Anagrams!");
@@ -283,9 +313,9 @@ matches will always lie between the given limits. Instead, `RegExpGen` makes a s
283313
* **What flavor of regular expression syntax is supported?**
284314

285315
The `RegExpGen` interface is designed to allow implementations for different regular expression
286-
engines. The current version provides an implementation for JavaScript `RegExp` (specifically,
287-
as defined by the [ECMAScript](https://www.ecma-international.org/ecma-262/#sec-patterns)
288-
standard).
316+
engines. The current version provides an
317+
[implementation for JavaScript `RegExp`](http://www.cornutum.org/regexp-gen/apidocs/org/cornutum/regexpgen/js/Provider.html)
318+
(specifically, as defined by the [ECMAScript](https://www.ecma-international.org/ecma-262/#sec-patterns) standard).
289319

290320
Note that the syntax for the Java `Pattern` implementation overlaps quite a bit with `RegExp`,
291321
so this `RegExpGen` implementation can also be used to generate matches for most Java `Pattern`
@@ -306,7 +336,7 @@ matches will always lie between the given limits. Instead, `RegExpGen` makes a s
306336

307337
* **Now that I've created a `RegExpGen`, how do I know the regular expression it's generating matches for?**
308338

309-
Easy -- just call `RegExpGen.getOptions().getRegExp()`.
339+
Easy -- just call `RegExpGen.getSource()`.
310340

311341
* **Hey, what happened to release version 1.2.2?**
312342

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<groupId>org.cornutum.regexp</groupId>
88
<artifactId>regexp-gen</artifactId>
99
<packaging>jar</packaging>
10-
<version>1.2.5-SNAPSHOT</version>
10+
<version>2.0.0</version>
1111

1212
<name>RegExpGen</name>
1313
<description>Generates strings that match a regular expression</description>

src/main/java/org/cornutum/regexpgen/js/NotMatchingFactory.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,11 @@ else if( sequences.stream().anyMatch( List::isEmpty))
9393
if( Optional.ofNullable( mismatching).map( m -> !m.isEmpty()).orElse( false))
9494
{
9595
// Yes, include a mismatching generator.
96-
notAlternatives.add( withSource( new AnyOfGen( regExpGen.getOptions(), mismatching), mismatching));
96+
notAlternatives.add(
97+
withLength(
98+
withSource( new AnyOfGen( regExpGen.getOptions(), mismatching), mismatching),
99+
1,
100+
null));
97101
}
98102

99103
// Minimum length required?
@@ -109,6 +113,7 @@ else if( sequences.stream().anyMatch( List::isEmpty))
109113
notAlternatives.add(
110114
withLength(
111115
withSource( new AnyOfGen( regExpGen.getOptions(), allowed), allowed),
116+
0,
112117
regExpGen.getMinLength() - 1));
113118
}
114119

@@ -216,9 +221,9 @@ private static <T extends AbstractRegExpGen> T withSource( T regExpGen, String s
216221
return regExpGen;
217222
}
218223

219-
private static <T extends AbstractRegExpGen> T withLength( T regExpGen, int length)
224+
private static <T extends AbstractRegExpGen> T withLength( T regExpGen, int minLength, Integer maxLength)
220225
{
221-
regExpGen.setOccurrences( length, length);
226+
regExpGen.setOccurrences( minLength, maxLength);
222227
return regExpGen;
223228
}
224229

src/test/java/org/cornutum/regexpgen/examples/ExampleTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,28 @@ public void exactMatches()
144144
}
145145
}
146146

147+
@Test
148+
public void notMatching()
149+
{
150+
// Given a JavaScript regular expression...
151+
String regexp = regexp( "(Hello|Howdy|Allô), world!");
152+
153+
// ...and a random number generator...
154+
RandomGen random = getRandomGen();
155+
156+
// ...create a RegExpGen instance...
157+
RegExpGen generator =
158+
Provider.forEcmaScript().notMatching( regexp)
159+
.orElseThrow( () -> new IllegalStateException( String.format( "Unable to generate string not matching '%s'", regexp)));
160+
161+
System.out.println( String.format( "\n%s [ %s ]:", "notMatching", regexp));
162+
for( int i = 0; i < getGeneratorCount(); i++)
163+
{
164+
// ...and generate matching strings.
165+
System.out.println( generator.generate( random));
166+
}
167+
}
168+
147169
/**
148170
* Returns the number of matches to generate for each regular expression.
149171
*/

0 commit comments

Comments
 (0)