Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trailing empty string ignoring and tests to ExprJoinSplit #6930

Merged
merged 14 commits into from
Aug 15, 2024
76 changes: 34 additions & 42 deletions src/main/java/ch/njol/skript/expressions/ExprJoinSplit.java
Original file line number Diff line number Diff line change
@@ -1,30 +1,7 @@
/**
* This file is part of Skript.
*
* Skript 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.
*
* Skript 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 Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.expressions;

import java.util.regex.Pattern;

import ch.njol.skript.SkriptConfig;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.SkriptConfig;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
Expand All @@ -35,43 +12,48 @@
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import ch.njol.util.StringUtils;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;

import java.util.regex.Pattern;

/**
* @author Peter Güttinger
*/
@Name("Join & Split")
@Description("Joins several texts with a common delimiter (e.g. \", \"), or splits a text into multiple texts at a given delimiter.")
@Examples({
"message \"Online players: %join all players with \"\" | \"\"%\" # %all players% would use the default \"x, y, and z\"",
"set {_s::*} to the string argument split at \",\""
"message \"Online players: %join all players' names with \"\" | \"\"%\" # %all players% would use the default \"x, y, and z\"",
"set {_s::*} to the string argument split at \",\""
})
@Since("2.1, 2.5.2 (regex support), 2.7 (case sensitivity)")
@Since("2.1, 2.5.2 (regex support), 2.7 (case sensitivity), INSERT VERSION (without trailing string)")
public class ExprJoinSplit extends SimpleExpression<String> {

static {
Skript.registerExpression(ExprJoinSplit.class, String.class, ExpressionType.COMBINED,
"(concat[enate]|join) %strings% [(with|using|by) [[the] delimiter] %-string%]",
"split %string% (at|using|by) [[the] delimiter] %string% [case:with case sensitivity]",
"%string% split (at|using|by) [[the] delimiter] %string% [case:with case sensitivity]",
"regex split %string% (at|using|by) [[the] delimiter] %string%",
"regex %string% split (at|using|by) [[the] delimiter] %string%");
"split %string% (at|using|by) [[the] delimiter] %string% [case:with case sensitivity] [trailing:without [the] trailing [empty] (string|text)]",
"%string% split (at|using|by) [[the] delimiter] %string% [case:with case sensitivity] [trailing:without [the] trailing [empty] (string|text)]",
"regex split %string% (at|using|by) [[the] delimiter] %string% [trailing:without [the] trailing [empty] (string|text)]",
"regex %string% split (at|using|by) [[the] delimiter] %string% [trailing:without [the] trailing [empty] (string|text)]");
}

private boolean join;
private boolean regex;
private boolean caseSensitivity;
private boolean removeTrailing;

@SuppressWarnings("null")
@UnknownNullability
private Expression<String> strings;
@Nullable
@UnknownNullability
private Expression<String> delimiter;

@Override
@SuppressWarnings({"unchecked", "null"})
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
join = matchedPattern == 0;
regex = matchedPattern >= 3;
caseSensitivity = SkriptConfig.caseSensitive.value() || parseResult.hasTag("case");
removeTrailing = parseResult.hasTag("trailing");

strings = (Expression<String>) exprs[0];
delimiter = (Expression<String>) exprs[1];
return true;
Expand All @@ -82,12 +64,18 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
protected String[] get(Event event) {
String[] strings = this.strings.getArray(event);
String delimiter = this.delimiter != null ? this.delimiter.getSingle(event) : "";

if (strings.length == 0 || delimiter == null)
return new String[0];

if (join) {
return new String[] {StringUtils.join(strings, delimiter)};
return new String[]{StringUtils.join(strings, delimiter)};
} else {
return strings[0].split(regex ? delimiter : (caseSensitivity ? "" : "(?i)") + Pattern.quote(delimiter), -1);
if (!regex) {
delimiter = (caseSensitivity ? "" : "(?i)") + Pattern.quote(delimiter);
}

return strings[0].split(delimiter, removeTrailing ? 0 : -1);
}
}

Expand All @@ -104,9 +92,13 @@ public Class<? extends String> getReturnType() {
@Override
public String toString(@Nullable Event event, boolean debug) {
if (join)
return "join " + strings.toString(event, debug) + (delimiter != null ? " with " + delimiter.toString(event, debug) : "");
return (regex ? "regex " : "") + "split " + strings.toString(event, debug) + (delimiter != null ? " at " + delimiter.toString(event, debug) : "")
+ (regex ? "" : "(case sensitive: " + caseSensitivity + ")");
return "join " + strings.toString(event, debug) +
(delimiter != null ? " with " + delimiter.toString(event, debug) : "");
return (regex ? "regex " : "") +
"split " + strings.toString(event, debug) +
(delimiter != null ? " at " + delimiter.toString(event, debug) : "") +
(regex ? "" : "(case sensitive: " + caseSensitivity + ")") +
(removeTrailing ? " without trailing string" : "");
}

}
27 changes: 27 additions & 0 deletions src/test/skript/tests/syntaxes/expressions/ExprJoinSplit.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
test "join strings":
assert join "a", "b", "c" is "abc" with "join strings without delimiter failed"
assert join "a", "b", "c" with " " is "a b c" with "join strings with delimiter failed"

test "split strings on string":
assert split "abc" at "[a-z]" is "abc" with "split with regex chars failed"

assert split "a b c" at " " is "a", "b", "c" with "split failed"
assert split "a b c" at " " with case sensitivity is "a", "b", "c" with "split with case sensitivity failed"
assert split "a b c" at " " without trailing string is "a", "b", "c" with "split without trailing string failed"

assert split "abc" at "" is "a", "b", "c", "" with "split with empty delimiter failed"
assert split "abc" at "" with case sensitivity is "a", "b", "c", "" with "split with empty delimiter with case sensitivity failed"
assert split "abc" at "" without trailing string is "a", "b", "c" with "split with empty delimiter without trailing string failed"
assert split "abc" at "" with case sensitivity without trailing string is "a", "b", "c" with "split with empty delimiter with case sensitivity without trailing string failed"

assert split "-x-X" at "x" is "-", "-", "" with "split with delimiter at end failed"
assert split "-x-X" at "x" with case sensitivity is "-", "-X" with "split with delimiter at end with case sensitivity failed"
assert split "-x-X" at "x" without trailing string is "-", "-" with "split with delimiter at end without trailing string failed"
assert split "-x-X" at "x" with case sensitivity without trailing string is "-", "-X" with "split with delimiter at end with case sensitivity without trailing string failed"

test "split strings on regex":
assert regex split "a b c" at " " is "a", "b", "c" with "regex split failed"
assert regex split "a b_c" at "( |_)" is "a", "b", "c" with "regex split with regex failed"

assert regex split "-a-b-c" at "[a-z]" is "-", "-", "-", "" with "regex split with delimiter at end failed"
assert regex split "-a-b-c" at "[a-z]" without trailing string is "-", "-", "-" with "regex split with delimiter at end without trailing string failed"