Move split(string) to DisguiseUtilities and add unit testing
This commit is contained in:
parent
f8172ed807
commit
6525503f78
@ -292,7 +292,7 @@ public class DisguiseConfig {
|
||||
|
||||
try {
|
||||
Disguise disguise = DisguiseParser
|
||||
.parseDisguise(Bukkit.getConsoleSender(), "disguise", DisguiseParser.split(toParse),
|
||||
.parseDisguise(Bukkit.getConsoleSender(), "disguise", DisguiseUtilities.split(toParse),
|
||||
DisguiseParser.getPermissions(Bukkit.getConsoleSender(), "disguise"));
|
||||
|
||||
customDisguises.put(key, disguise);
|
||||
|
@ -5,6 +5,7 @@ import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
import me.libraryaddict.disguise.utilities.parser.params.ParamInfo;
|
||||
@ -38,7 +39,7 @@ public class DisguiseCommand extends DisguiseBaseCommand implements TabCompleter
|
||||
|
||||
try {
|
||||
disguise = DisguiseParser
|
||||
.parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(args, " ")),
|
||||
.parseDisguise(sender, getPermNode(), DisguiseUtilities.split(StringUtils.join(args, " ")),
|
||||
getPermissions(sender));
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
|
@ -4,6 +4,7 @@ import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
import me.libraryaddict.disguise.utilities.parser.params.ParamInfo;
|
||||
@ -18,7 +19,6 @@ import org.bukkit.entity.Player;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCompleter {
|
||||
@ -43,7 +43,7 @@ public class DisguiseEntityCommand extends DisguiseBaseCommand implements TabCom
|
||||
|
||||
try {
|
||||
disguise = DisguiseParser
|
||||
.parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(args, " ")),
|
||||
.parseDisguise(sender, getPermNode(), DisguiseUtilities.split(StringUtils.join(args, " ")),
|
||||
getPermissions(sender));
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
|
@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands;
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
import me.libraryaddict.disguise.utilities.parser.params.ParamInfo;
|
||||
@ -55,7 +56,7 @@ public class DisguiseModifyCommand extends DisguiseBaseCommand implements TabCom
|
||||
|
||||
try {
|
||||
DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(),
|
||||
DisguiseParser.split(StringUtils.join(args, " ")));
|
||||
DisguiseUtilities.split(StringUtils.join(args, " ")));
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
if (ex.getMessage() != null) {
|
||||
|
@ -2,6 +2,7 @@ package me.libraryaddict.disguise.commands;
|
||||
|
||||
import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.DisguiseParser;
|
||||
import me.libraryaddict.disguise.utilities.parser.DisguisePerm;
|
||||
@ -43,7 +44,7 @@ public class DisguiseModifyEntityCommand extends DisguiseBaseCommand implements
|
||||
// TODO Validate if any disguises have this arg
|
||||
|
||||
LibsDisguises.getInstance().getListener()
|
||||
.setDisguiseModify(sender.getName(), DisguiseParser.split(StringUtils.join(args, " ")));
|
||||
.setDisguiseModify(sender.getName(), DisguiseUtilities.split(StringUtils.join(args, " ")));
|
||||
|
||||
sender.sendMessage(LibsMsg.DMODIFYENT_CLICK.get(DisguiseConfig.getDisguiseEntityExpire()));
|
||||
return true;
|
||||
|
@ -2,6 +2,7 @@ package me.libraryaddict.disguise.commands;
|
||||
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
import me.libraryaddict.disguise.utilities.parser.params.ParamInfo;
|
||||
@ -70,7 +71,7 @@ public class DisguiseModifyPlayerCommand extends DisguiseBaseCommand implements
|
||||
|
||||
try {
|
||||
DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(),
|
||||
DisguiseParser.split(StringUtils.join(newArgs, " ")));
|
||||
DisguiseUtilities.split(StringUtils.join(newArgs, " ")));
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
if (ex.getMessage() != null) {
|
||||
|
@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands;
|
||||
import me.libraryaddict.disguise.DisguiseAPI;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.TranslateType;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
@ -153,7 +154,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements
|
||||
|
||||
try {
|
||||
DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(),
|
||||
DisguiseParser.split(StringUtils.join(newArgs, " ")));
|
||||
DisguiseUtilities.split(StringUtils.join(newArgs, " ")));
|
||||
modifiedDisguises++;
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
|
@ -5,6 +5,7 @@ import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
import me.libraryaddict.disguise.utilities.parser.params.ParamInfo;
|
||||
@ -72,7 +73,7 @@ public class DisguisePlayerCommand extends DisguiseBaseCommand implements TabCom
|
||||
|
||||
try {
|
||||
disguise = DisguiseParser
|
||||
.parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")),
|
||||
.parseDisguise(sender, getPermNode(), DisguiseUtilities.split(StringUtils.join(newArgs, " ")),
|
||||
permissions);
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
|
@ -6,6 +6,7 @@ import me.libraryaddict.disguise.disguisetypes.Disguise;
|
||||
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
|
||||
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
||||
import me.libraryaddict.disguise.utilities.ClassGetter;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.TranslateType;
|
||||
import me.libraryaddict.disguise.utilities.parser.*;
|
||||
@ -134,7 +135,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom
|
||||
|
||||
try {
|
||||
disguise = DisguiseParser
|
||||
.parseDisguise(sender, getPermNode(), DisguiseParser.split(StringUtils.join(newArgs, " ")),
|
||||
.parseDisguise(sender, getPermNode(), DisguiseUtilities.split(StringUtils.join(newArgs, " ")),
|
||||
permissions);
|
||||
}
|
||||
catch (DisguiseParseException ex) {
|
||||
|
@ -51,6 +51,7 @@ import java.io.PrintWriter;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DisguiseUtilities {
|
||||
@ -1379,6 +1380,99 @@ public class DisguiseUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string while respecting quotes.
|
||||
* <p>
|
||||
* Re
|
||||
*/
|
||||
/*public static String[] split(String string) {
|
||||
Matcher matcher = Pattern.compile("\"(?:\"(?=\\S)|\\\\\"|[^\"])*(?:[^\\\\]\"(?=\\s|$))|\\S+").matcher(string);
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group();
|
||||
|
||||
// If the match was quoted, then remove quotes and escapes
|
||||
if (match.matches("\"(?:\"(?=\\S)|\\\\\"|[^\"])*(?:[^\\\\]\")")) {
|
||||
// Replace the match by removing first and last quote
|
||||
// Then remove escaped slashes from the trailing with regex
|
||||
match = match.substring(1, match.length() - 1).replaceAll("\\\\\\\\(?=(\\\\\\\\)*$)", "\\");
|
||||
}
|
||||
|
||||
list.add(matcher.group());
|
||||
}
|
||||
|
||||
return list.toArray(new String[0]);
|
||||
}*/
|
||||
public static String[] split(String string) {
|
||||
// Regex where we first match any character that isn't a slash, if it is a slash then it must not have more
|
||||
// slashes until it hits the quote
|
||||
// If any slashes before the quote, they must be escaped. That is, two of them.
|
||||
// Must end with a quote
|
||||
Pattern endsWithQuote = Pattern.compile("^([^\\\\]|\\\\(?!\\\\*\"$))*(\\\\\\\\)*\"$");
|
||||
// Matches \"message quote, and
|
||||
Pattern removeSlashes = Pattern.compile("^\\\\(\")|\\\\(?:(\\\\)(?=\\\\*\"$)|(\")$)");
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
String[] split = string.split(" ");
|
||||
String[] unescapedSplit = new String[split.length];
|
||||
|
||||
loop:
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
// If the word starts with a quote
|
||||
if (split[i].startsWith("\"")) {
|
||||
// Look for a word with an ending quote
|
||||
for (int a = i; a < split.length; a++) {
|
||||
// If it's the same word, but only one possible quote
|
||||
if (a == i && split[i].length() == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Does not end with a valid quote
|
||||
if (!endsWithQuote.matcher(split[a]).matches()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found a sentence, build it
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
for (int b = i; b <= a; b++) {
|
||||
Matcher matcher = removeSlashes.matcher(split[b]);
|
||||
|
||||
// Remove any escapes for escaped quotes
|
||||
String word = matcher.replaceAll("$1$2$3");
|
||||
|
||||
// If this is the beginning or end of a quote
|
||||
if (b == i || b == a) {
|
||||
// Remove the quote
|
||||
word = word.substring(b == i ? 1 : 0, word.length() - (b == a ? 1 : 0));
|
||||
}
|
||||
|
||||
if (b > i) {
|
||||
builder.append(" ");
|
||||
}
|
||||
|
||||
builder.append(word);
|
||||
}
|
||||
|
||||
list.add(builder.toString());
|
||||
i = a;
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove escapes if there, and add as a single word
|
||||
Matcher matcher = removeSlashes.matcher(split[i]);
|
||||
|
||||
String word = matcher.replaceAll("$1$2$3");
|
||||
|
||||
list.add(word);
|
||||
}
|
||||
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the self disguise to the player
|
||||
*/
|
||||
|
@ -17,8 +17,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DisguiseParser {
|
||||
private static void doCheck(CommandSender sender, DisguisePermissions permissions, DisguisePerm disguisePerm,
|
||||
@ -122,21 +120,6 @@ public class DisguiseParser {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a string while respecting quotes
|
||||
*/
|
||||
public static String[] split(String string) {
|
||||
Matcher matcher = Pattern.compile("\"(?:\"(?=\\S)|\\\\\"|[^\"])*(?:[^\\\\]\"(?=\\s|$))|\\S+").matcher(string);
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
while (matcher.find()) {
|
||||
list.add(matcher.group());
|
||||
}
|
||||
|
||||
return list.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the disguise if it all parsed correctly. Returns a exception with a complete message if it didn't. The
|
||||
* commandsender is purely used for checking permissions. Would defeat the purpose otherwise. To reach this
|
||||
|
@ -0,0 +1,120 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 25/10/2018.
|
||||
*/
|
||||
public class DisguiseUtilitiesTest {
|
||||
@Test
|
||||
public void testQuoteSplitter() {
|
||||
// Test if splits are correct
|
||||
Assert.assertArrayEquals(new String[]{"A", "simple", "string"}, DisguiseUtilities.split("A simple string"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A quoted string"}, DisguiseUtilities.split("\"A quoted string\""));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"\"A double quoted string\""},
|
||||
DisguiseUtilities.split("\"\"A double quoted string\"\""));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string", "containing a", "quote"},
|
||||
DisguiseUtilities.split("A string \"containing a\" quote"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string", "fully", "split"},
|
||||
DisguiseUtilities.split("\"A\" string fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string", "fully", "split"},
|
||||
DisguiseUtilities.split("\"A\" \"string\" fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string", "fully", "split"},
|
||||
DisguiseUtilities.split("A \"string\" fully split"));
|
||||
|
||||
// Test if quotes are ignored properly and included in result
|
||||
Assert.assertArrayEquals(new String[]{"A", "\"string", "fully", "split"},
|
||||
DisguiseUtilities.split("A \"string fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "\"string", "\"fully", "split"},
|
||||
DisguiseUtilities.split("A \"string \"fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"\"A", "\"string", "\"fully", "split"},
|
||||
DisguiseUtilities.split("\"A \"string \"fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string\"", "fully", "split"},
|
||||
DisguiseUtilities.split("A string\" fully split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string\"", "fully\"", "split"},
|
||||
DisguiseUtilities.split("A string\" fully\" split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A", "string", "fully\"", "split"},
|
||||
DisguiseUtilities.split("A \"string\" fully\" split"));
|
||||
|
||||
Assert.assertArrayEquals(new String[]{"A \"string", "with", "four", "splits"},
|
||||
DisguiseUtilities.split("\"A \"string\" with four splits"));
|
||||
|
||||
// Test for quotes inside words
|
||||
Assert.assertArrayEquals(new String[]{"Fully", "split", "\"", "message"},
|
||||
DisguiseUtilities.split("Fully split \"\"\" message"));
|
||||
|
||||
// Test to make sure space can be quoted, with an empty quote at the end
|
||||
Assert.assertArrayEquals(new String[]{" ", "\""}, DisguiseUtilities.split("\" \" \""));
|
||||
|
||||
// Test to make sure empty quotes, are still quotes
|
||||
Assert.assertArrayEquals(new String[]{"Three", "", "split"}, DisguiseUtilities.split("Three \"\" split"));
|
||||
|
||||
// Test to ensure single quotes, are still not quotes
|
||||
Assert.assertArrayEquals(new String[]{"'Three", "split", "message'"},
|
||||
DisguiseUtilities.split("'Three split message'"));
|
||||
|
||||
// There is a quoted message inside the quoted message, however it was not escaped
|
||||
Assert.assertArrayEquals(new String[]{"A", "quoted message \"inside a quoted message\""},
|
||||
DisguiseUtilities.split("A \"quoted message \"inside a quoted message\"\""));
|
||||
|
||||
// Now test for escaped quotes, however as escaped quotes look different inside editors, I'll be replacing \
|
||||
// with / and " with '
|
||||
|
||||
// Test for escaped quotes, they should be ignored
|
||||
splitEquals("/'Escaped quotes/'", "'Escaped", "quotes'");
|
||||
|
||||
// Test with one quote escaped
|
||||
splitEquals("'Escaped quotes/'", "'Escaped", "quotes'");
|
||||
|
||||
// Test with no quotes escaped, where the escape was escaped
|
||||
splitEquals("'Unescaped quotes/'", "'Unescaped", "quotes'");
|
||||
|
||||
// Test with three escaped slashes, then unescaped quote
|
||||
splitEquals("'Unescaped quotes//////'", "Unescaped quotes///");
|
||||
|
||||
// Test with three escaped slashes, then escaped quote
|
||||
splitEquals("'Escaped quotes///////'", "'Escaped", "quotes///'");
|
||||
|
||||
// Test with strings of escapes and quotes only
|
||||
splitEquals("////", "////");
|
||||
|
||||
splitEquals("////'", "//'");
|
||||
|
||||
splitEquals("'////'", "//");
|
||||
|
||||
splitEquals("'/////'", "'//'");
|
||||
|
||||
splitEquals("'// //'", "// /");
|
||||
|
||||
splitEquals("'//// ////'", "//// //");
|
||||
|
||||
splitEquals(
|
||||
"Foobar is not 'Foo Bar' but is a single word 'foobar' or as some quote it, /'foobar/' and again, " +
|
||||
"not /'foo bar/' - It is 'foobar'!",
|
||||
|
||||
"Foobar", "is", "not", "Foo Bar", "but", "is", "a", "single", "word", "foobar", "or", "as", "some",
|
||||
"quote", "it,", "'foobar'", "and", "again,", "not", "'foo", "bar'", "-", "It", "is", "'foobar'!");
|
||||
}
|
||||
|
||||
private void splitEquals(String toSplit, String... expected) {
|
||||
String[] splitted = DisguiseUtilities.split(toSplit.replace("/", "\\").replace("'", "\""));
|
||||
String[] expect = Arrays.stream(expected).map(string -> string.replace("/", "\\").replace("'", "\""))
|
||||
.toArray(String[]::new);
|
||||
|
||||
Assert.assertArrayEquals(expect, splitted);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user