Introduce ThingPickerParser.

To ensure that we are extensible from the get-go, this commit introduces
the parser aspect of the ThingPicker framework with parsers for the two
non-trivial picker implementations.

Nothing is wired up yet.
This commit is contained in:
Andreas Troelsen
2020-08-22 17:12:26 +02:00
parent e8bb8a9e4d
commit 5566d8fd86
7 changed files with 609 additions and 0 deletions
@@ -0,0 +1,224 @@
package com.garbagemule.MobArena.things;
import org.hamcrest.collection.IsEmptyCollection;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsEmptyCollection.empty;
public class ParserUtilTest {
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void extractBetweenThrowsIfNoLeftSymbol() {
String input = "a, b, c)";
exception.expect(IllegalArgumentException.class);
ParserUtil.extractBetween(input, '(', ')');
}
@Test
public void extractBetweenThrowsIfNoRightSymbol() {
String input = "(a, b, c";
exception.expect(IllegalArgumentException.class);
ParserUtil.extractBetween(input, '(', ')');
}
@Test
public void extractBetweenStripsPrefixAndSuffix() {
String inner = "a, b, c";
String input = "hello [" + inner + "] world";
String result = ParserUtil.extractBetween(input, '[', ']');
assertThat(result, equalTo(inner));
}
@Test
public void extractBetweenSkipsNestedGroups() {
String inner = "a, b, c";
String wrapped = "<" + inner + ">";
String input = "<" + wrapped + ">";
String result = ParserUtil.extractBetween(input, '<', '>');
assertThat(result, equalTo(wrapped));
}
@Test
public void extractBetweenThingGroup1() {
String inner = "random(a, b), random(c, d)";
String input = "all(" + inner + ")";
String result = ParserUtil.extractBetween(input, '(', ')');
assertThat(result, equalTo(inner));
}
@Test
public void splitThrowsOnUnmatchedLeftParen() {
String input = "(a, b), (c, d";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedRightParen() {
String input = "(a, b), c, d)";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedLeftBracket() {
String input = "[a, b], [c, d";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedRightBracket() {
String input = "[a, b], c, d]";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedLeftBrace() {
String input = "{a, b}, {c, d";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedRightBrace() {
String input = "{a, b}, c, d}";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedLeftAngle() {
String input = "<a, b>, <c, d";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitThrowsOnUnmatchedRightAngle() {
String input = "<a, b>, c, d>";
exception.expect(IllegalArgumentException.class);
ParserUtil.split(input);
}
@Test
public void splitReturnsEmptyListOnEmptyInput() {
String input = " ";
List<String> result = ParserUtil.split(input);
assertThat(result, empty());
}
@Test
public void splitReturnsInputIfNoCommas() {
String input = "abc";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Collections.singletonList(input)));
}
@Test
public void splitWorksOnBareLists() {
String input = "abc, de, f";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "de", "f")));
}
@Test
public void splitOmitsEmptyParts() {
String input = "abc, , f, ";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "f")));
}
@Test
public void splitSkipsParentheses() {
String input = "abc, (de, f)";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "(de, f)")));
}
@Test
public void splitSkipsSquareBrackets() {
String input = "abc, [de, f]";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "[de, f]")));
}
@Test
public void splitSkipsCurlyBraces() {
String input = "abc, {de, f}";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "{de, f}")));
}
@Test
public void splitSkipsAngleBrackets() {
String input = "abc, <de, f>";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList("abc", "<de, f>")));
}
@Test
public void splitThingGroup1() {
String input = "all(random(a, b), random(c, d))";
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Collections.singletonList(input)));
}
@Test
public void splitThingGroup2() {
String group1 = "all(random(a, b), random(c, d))";
String group2 = "random(all(e, f), all(g, h))";
String input = group1 + ", " + group2;
List<String> result = ParserUtil.split(input);
assertThat(result, equalTo(Arrays.asList(group1, group2)));
}
}
@@ -0,0 +1,99 @@
package com.garbagemule.MobArena.things;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.Random;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class RandomThingPickerParserTest {
private RandomThingPickerParser subject;
private ThingPickerParser parser;
@Rule
public ExpectedException exception = ExpectedException.none();
@Before
public void setup() {
parser = mock(ThingPickerParser.class);
subject = new RandomThingPickerParser(parser, new Random());
}
@Test
public void returnsNullIfRandomIsMissing() {
String input = "(a, b, c)";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void returnsNullIfParenthesesAreMissing() {
String input = "random[a, b, c]";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void returnsNullIfNotRandom() {
String input = "all(a, b, c)";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void invokesUnderlyingParserForEachItem() {
String input = "random(a, b, c)";
subject.parse(input);
verify(parser, times(1)).parse("a");
verify(parser, times(1)).parse("b");
verify(parser, times(1)).parse("c");
}
@Test
public void returnsRandomThingPickerMultipleThings() {
String input = "random(a, b)";
ThingPicker result = subject.parse(input);
assertThat(result, instanceOf(RandomThingPicker.class));
}
@Test
public void returnsOnlyPickerInsteadOfWrapping() {
String input = "random(a)";
ThingPicker picker = mock(ThingPicker.class);
when(parser.parse("a")).thenReturn(picker);
ThingPicker result = subject.parse(input);
assertThat(result, is(picker));
}
@Test
public void throwsIfZeroThings() {
String input = "random()";
exception.expect(IllegalArgumentException.class);
subject.parse(input);
}
}
@@ -0,0 +1,97 @@
package com.garbagemule.MobArena.things;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ThingGroupPickerParserTest {
private ThingGroupPickerParser subject;
private ThingPickerParser parser;
@Rule
public ExpectedException exception = ExpectedException.none();
@Before
public void setup() {
parser = mock(ThingPickerParser.class);
subject = new ThingGroupPickerParser(parser);
}
@Test
public void returnsNullIfAllIsMissing() {
String input = "(a, b, c)";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void returnsNullIfParenthesesAreMissing() {
String input = "all[a, b, c]";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void returnsNullIfNotAll() {
String input = "random(a, b, c)";
ThingPicker result = subject.parse(input);
assertThat(result, nullValue());
}
@Test
public void invokesUnderlyingParserForEachItem() {
String input = "all(a, b, c)";
subject.parse(input);
verify(parser, times(1)).parse("a");
verify(parser, times(1)).parse("b");
verify(parser, times(1)).parse("c");
}
@Test
public void returnsRandomThingPickerMultipleThings() {
String input = "all(a, b)";
ThingPicker result = subject.parse(input);
assertThat(result, instanceOf(ThingGroupPicker.class));
}
@Test
public void returnsSingleThingPickerIfOnlyOneThing() {
String input = "all(a)";
ThingPicker picker = mock(ThingPicker.class);
when(parser.parse("a")).thenReturn(picker);
ThingPicker result = subject.parse(input);
assertThat(result, is(picker));
}
@Test
public void throwsIfZeroThings() {
String input = "all()";
exception.expect(IllegalArgumentException.class);
subject.parse(input);
}
}