diff --git a/Core/src/main/java/com/plotsquared/core/plot/flag/implementations/PlotTitleFlag.java b/Core/src/main/java/com/plotsquared/core/plot/flag/implementations/PlotTitleFlag.java index c9aa129bc..1030b0fac 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/flag/implementations/PlotTitleFlag.java +++ b/Core/src/main/java/com/plotsquared/core/plot/flag/implementations/PlotTitleFlag.java @@ -29,6 +29,7 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.plot.PlotTitle; import com.plotsquared.core.plot.flag.FlagParseException; import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.util.StringMan; import org.checkerframework.checker.nullness.qual.NonNull; public class PlotTitleFlag extends PlotFlag { @@ -56,17 +57,18 @@ public class PlotTitleFlag extends PlotFlag { if (!input.contains("\"")) { return new PlotTitleFlag(new PlotTitle(input, "")); } - input = input.substring(input.indexOf("\"")); - input = input.substring(0, input.lastIndexOf("\"") + 1); - String[] inputs = input.split("\""); - PlotTitle value; - if (inputs.length == 2) { - value = new PlotTitle(inputs[1], ""); - } else if (inputs.length > 3) { - value = new PlotTitle(inputs[1], inputs[3]); - } else { + + var split = StringMan.splitMessage(input); + + if (split.isEmpty() || split.size() > 2) { throw new FlagParseException(this, input, TranslatableCaption.of("flags.flag_error_title")); } + PlotTitle value; + if (split.size() == 1) { + value = new PlotTitle(split.get(0), ""); + } else { + value = new PlotTitle(split.get(0), split.get(1)); + } return new PlotTitleFlag(value); } diff --git a/Core/src/main/java/com/plotsquared/core/util/StringMan.java b/Core/src/main/java/com/plotsquared/core/util/StringMan.java index f44c8e04e..a5c740a19 100644 --- a/Core/src/main/java/com/plotsquared/core/util/StringMan.java +++ b/Core/src/main/java/com/plotsquared/core/util/StringMan.java @@ -30,16 +30,21 @@ import com.plotsquared.core.configuration.caption.Caption; import org.checkerframework.checker.nullness.qual.NonNull; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.regex.Pattern; public class StringMan { + private static final Pattern STRING_SPLIT_PATTERN = Pattern.compile("(?\"[\\w ]+\")|(?\\w+)"); + public static String replaceFromMap(String string, Map replacements) { StringBuilder sb = new StringBuilder(string); int size = string.length(); @@ -320,4 +325,46 @@ public class StringMan { return col; } + /** + * @param message an input string + * @return a list of strings + * @since TODO + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Converts multiple quoted and single strings into a list of strings
InputOutput
title "sub title"["title", "sub title"]
"a title" subtitle["a title", "subtitle"]
"title" "subtitle"["title", "subtitle"]
"PlotSquared is going well" the authors "and many contributors"["PlotSquared is going well", "the", "authors", "and many contributors"]
+ */ + public static @NonNull List splitMessage(@NonNull String message) { + var matcher = StringMan.STRING_SPLIT_PATTERN.matcher(message); + List splitMessages = new ArrayList<>(); + while (matcher.find()) { + splitMessages.add(matcher.group(0).replaceAll("\"", "")); + } + return splitMessages; + } + } diff --git a/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java b/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java index c3c774e7b..c2fd9d1d0 100644 --- a/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java +++ b/Core/src/test/java/com/plotsquared/core/plot/FlagTest.java @@ -25,9 +25,12 @@ */ package com.plotsquared.core.plot; +import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.database.AbstractDBTest; import com.plotsquared.core.database.DBFunc; +import com.plotsquared.core.plot.flag.FlagParseException; import com.plotsquared.core.plot.flag.PlotFlag; +import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag; import com.plotsquared.core.plot.flag.implementations.UseFlag; import com.sk89q.worldedit.world.item.ItemType; import org.apache.logging.log4j.LogManager; @@ -74,4 +77,62 @@ public class FlagTest { Assertions.assertEquals("use", flagName); } + @Test + public void shouldSuccessfullyParseTitleFlagWithTitleSingularAndSubTitleEmpty() { + Assertions.assertDoesNotThrow(() -> { + var title = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"test\" \"\"").getValue(); + Assertions.assertEquals("test", title.title()); + Assertions.assertEquals("", title.subtitle()); + }, "Should not throw a FlagParseException"); + } + + @Test + public void shouldSuccessfullyParseTitleFlagWithTitleMultipleWordsAndSubTitleEmpty() { + Assertions.assertDoesNotThrow(() -> { + var title = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"test hello test\" \"\"").getValue(); + Assertions.assertEquals("test hello test", title.title()); + Assertions.assertEquals("", title.subtitle()); + }, "Should not throw a FlagParseException"); + } + + @Test + public void shouldSuccessfullyParseTitleFlagWithTitleMultipleWordsAndSubTitleMultipleWords() { + Assertions.assertDoesNotThrow(() -> { + var title = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"test hello test\" \"a very long subtitle\"").getValue(); + Assertions.assertEquals("test hello test", title.title()); + Assertions.assertEquals("a very long subtitle", title.subtitle()); + }, "Should not throw a FlagParseException"); + } + + @Test + public void shouldSuccessfullyParseTitleFlagWithTitleEmptyAndSubTitleSingleWord() { + Assertions.assertDoesNotThrow(() -> { + var title = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"\" \"single\"").getValue(); + Assertions.assertEquals(" ", title.title()); + Assertions.assertEquals("single", title.subtitle()); + }, "Should not throw a FlagParseException"); + } + + @Test + public void shouldExtractTitleWhenASingleDoubleQuoteAtEndOfTitle() { + Assertions.assertDoesNotThrow(() -> { + var plotTitle = PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("title\"").getValue(); + Assertions.assertEquals("title", plotTitle.title()); + Assertions.assertEquals("", plotTitle.subtitle()); + }, "Should not throw a FlagParseException"); + } + + @Test + public void shouldThrowFlagParseExceptionWithQuotesGreater4() { + var exception = Assertions.assertThrows( + FlagParseException.class, + () -> PlotTitleFlag.TITLE_FLAG_DEFAULT.parse("\"title\" \"subtitle\" \"more\""), + "Needs to throw a FlagParseException" + ); + Assertions.assertTrue(exception.getErrorMessage() instanceof TranslatableCaption); + Assertions.assertEquals( + "flags.flag_error_title", + ((TranslatableCaption) exception.getErrorMessage()).getKey() + ); + } } diff --git a/Core/src/test/java/com/plotsquared/core/util/StringManTest.java b/Core/src/test/java/com/plotsquared/core/util/StringManTest.java new file mode 100644 index 000000000..829284b8c --- /dev/null +++ b/Core/src/test/java/com/plotsquared/core/util/StringManTest.java @@ -0,0 +1,61 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.List; + +public class StringManTest { + + @Test + public void ensureThatAllVariationsHasTheExpectedOutcome() { + + List messages = List.of( + new Message("title", List.of("title")), + new Message("title \"sub title\"", List.of("title", "sub title")), + new Message("\"a title\" subtitle", List.of("a title", "subtitle")), + new Message("\"title\" \"subtitle\"", List.of("title", "subtitle")) + ); + + for (Message message : messages) { + var messageList = StringMan.splitMessage(message.input); + + Assertions.assertEquals(message.expected.size(), messageList.size()); + if (message.expected.size() > 0) { + Assertions.assertEquals(message.expected.get(0), messageList.get(0)); + } + if (message.expected.size() > 1) { + Assertions.assertEquals(message.expected.get(1), messageList.get(1)); + } + } + } + + private record Message(String input, List expected) { + + } +}