From 3a818da77acf50e7ea0d2c02d669cb67b9f114e3 Mon Sep 17 00:00:00 2001 From: Ben Culkin Date: Tue, 6 Oct 2020 20:05:00 -0400 Subject: Add unit tests for defines Adds unit tests for SimpleDefine and IteratedDefine. This also fixes an issue with IteratedDefine, where once you had consumed a replacer, it was consumed for good; you couldn't use it in the future, even in a different call to apply(). This was fixed through the introduction of a new iterator type from esodata - ResettableIterator. See that project/type for more details on what exactly this does; but suffice to say, it allows to restore our iterator and re-iterate over the same elements on every call to apply. --- .../utils/parserutils/defines/IteratedDefine.java | 46 +++++++++++++++++- .../utils/parserutils/defines/SimpleDefine.java | 12 +++++ .../parserutils/defines/IteratedDefineTest.java | 54 ++++++++++++++++++++++ .../test/parserutils/defines/SimpleDefineTest.java | 42 +++++++++++++++++ 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 base/src/test/java/bjc/utils/test/parserutils/defines/IteratedDefineTest.java create mode 100644 base/src/test/java/bjc/utils/test/parserutils/defines/SimpleDefineTest.java (limited to 'base/src') diff --git a/base/src/main/java/bjc/utils/parserutils/defines/IteratedDefine.java b/base/src/main/java/bjc/utils/parserutils/defines/IteratedDefine.java index 2dad9c6..8bed45c 100644 --- a/base/src/main/java/bjc/utils/parserutils/defines/IteratedDefine.java +++ b/base/src/main/java/bjc/utils/parserutils/defines/IteratedDefine.java @@ -7,6 +7,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import bjc.data.CircularIterator; +import bjc.data.ResettableIterator; /** * An iterated find/replace, using a circular assortment of replacements. @@ -16,7 +17,7 @@ import bjc.data.CircularIterator; public class IteratedDefine implements UnaryOperator { private Pattern patt; - private Iterator repls; + private ResettableIterator repls; /** * Create a new iterated define. @@ -32,15 +33,56 @@ public class IteratedDefine implements UnaryOperator { public IteratedDefine(Pattern pattern, boolean circular, String... replacers) { patt = pattern; - repls = new CircularIterator<>(Arrays.asList(replacers), circular); + Iterator tmp = new CircularIterator<>(Arrays.asList(replacers), circular); + repls = new ResettableIterator<>(tmp); + } + + /** + * Create a new iterated define. + * + * @param pattern + * The pattern to use for matching. + * @param circular + * Whether or not to loop through the list of replacers, or + * just repeat the last one. + * @param replacers + * The set of replacement strings to use. + */ + public IteratedDefine(String pattern, boolean circular, String... replacers) { + this(Pattern.compile(pattern), circular, replacers); } @Override public String apply(String ln) { + /* + * NOTE Oct 6 2020 - Ben Culkin - Should this be configurable to do/not do? + */ + + /* + * Reset the iterator. This means that the fact that you iterated over a + * replacer previously, doesn't keep it from being used again. + */ + repls.reset(); + Matcher mat = patt.matcher(ln); StringBuffer sb = new StringBuffer(); while (mat.find()) { + /* + * @NOTE Oct 6, 2020 - Ben Culkin + * + * Policy question here. Should we throw an exception if we exhaust our + * replacers and we weren't supposed to? + * + * Other alternatives are: + * + * a) Default to the empty string + * + * b) Keep the last valid replacer. This seems to be what we do as of now, per + * the behavior of CircularIterator. + * + * c) Use the replacer "$0", which is the same as not doing a replace at all + */ String repl = repls.next(); mat.appendReplacement(sb, repl); diff --git a/base/src/main/java/bjc/utils/parserutils/defines/SimpleDefine.java b/base/src/main/java/bjc/utils/parserutils/defines/SimpleDefine.java index b31d937..f20e22a 100644 --- a/base/src/main/java/bjc/utils/parserutils/defines/SimpleDefine.java +++ b/base/src/main/java/bjc/utils/parserutils/defines/SimpleDefine.java @@ -26,6 +26,18 @@ public class SimpleDefine implements UnaryOperator { repl = replace; } + + /** + * Create a new simple define. + * + * @param pattern + * The pattern to match against. + * @param replace + * The text to use as a replacement. + */ + public SimpleDefine(String pattern, String replace) { + this(Pattern.compile(pattern), replace); + } @Override public String apply(String line) { diff --git a/base/src/test/java/bjc/utils/test/parserutils/defines/IteratedDefineTest.java b/base/src/test/java/bjc/utils/test/parserutils/defines/IteratedDefineTest.java new file mode 100644 index 0000000..944ae07 --- /dev/null +++ b/base/src/test/java/bjc/utils/test/parserutils/defines/IteratedDefineTest.java @@ -0,0 +1,54 @@ +package bjc.utils.test.parserutils.defines; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import bjc.utils.parserutils.defines.IteratedDefine; + +/** + * Test {@link IteratedDefine} + * @author Ben Culkin + * + */ +public class IteratedDefineTest { + + /** + * Do testing of iterated define. + */ + @Test + public void testSingle() { + IteratedDefine itrd = new IteratedDefine("a", false, "b"); + + assertEquals("c", itrd.apply("c")); + assertEquals("b", itrd.apply("a")); + assertEquals("bb", itrd.apply("aa")); + } + + /** + * Test iterated define with multiple patterns. + */ + @Test + public void testMultiple() { + IteratedDefine itrd = new IteratedDefine("a", false, "b", "c"); + + assertEquals("d", itrd.apply("d")); + assertEquals("b", itrd.apply("a")); + assertEquals("bc", itrd.apply("aa")); + assertEquals("bcc", itrd.apply("aaa")); + } + + /** + * Test iterated define with circular patterns. + */ + @Test + public void testCircular() { + IteratedDefine itrd = new IteratedDefine("a", true, "b", "c"); + + assertEquals("d", itrd.apply("d")); + assertEquals("b", itrd.apply("a")); + assertEquals("bc", itrd.apply("aa")); + assertEquals("bcb", itrd.apply("aaa")); + assertEquals("bcbcb", itrd.apply("aaaaa")); + } +} diff --git a/base/src/test/java/bjc/utils/test/parserutils/defines/SimpleDefineTest.java b/base/src/test/java/bjc/utils/test/parserutils/defines/SimpleDefineTest.java new file mode 100644 index 0000000..035d33b --- /dev/null +++ b/base/src/test/java/bjc/utils/test/parserutils/defines/SimpleDefineTest.java @@ -0,0 +1,42 @@ +package bjc.utils.test.parserutils.defines; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import bjc.utils.parserutils.defines.SimpleDefine; + +/** + * Test of SimpleDefine. + * @author Ben Culkin + * + */ +public class SimpleDefineTest { + + /** + * Test literal patterns. + */ + @Test + public void testLiteralPatterns() { + SimpleDefine sd = new SimpleDefine("a b", "b a"); + + assertEquals("a a a a", sd.apply("a a a a")); + assertEquals("b a", sd.apply("a b")); + assertEquals("a a b a", sd.apply("a a a b")); + assertEquals("b a b a", sd.apply("a b a b")); + } + + /** + * Test regex patterns. + */ + @Test + public void testRegexPatterns() { + SimpleDefine sd2 = new SimpleDefine("a+", "b"); + + assertEquals("c", sd2.apply("c")); + assertEquals("b", sd2.apply("a")); + assertEquals("b", sd2.apply("aaa")); + assertEquals("bb", sd2.apply("aaab")); + } + +} -- cgit v1.2.3