Skip to content

Commit

Permalink
Merge pull request #3860 from emmebi/develop
Browse files Browse the repository at this point in the history
Fixes #3259
  • Loading branch information
Phergus authored Mar 12, 2023
2 parents 5c4eeb5 + f033cd8 commit 4f22f04
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 15 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ dependencies {
implementation group: 'com.google.code.gson', name: 'gson', version: '2.9.0' // https://mvnrepository.com/artifact/com.google.code.gson/gson

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'

// For mocking features during unit tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import java.awt.EventQueue;
import java.awt.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.rptools.maptool.client.MapTool;
import net.rptools.maptool.client.MapToolVariableResolver;
import net.rptools.maptool.client.functions.exceptions.*;
import net.rptools.maptool.client.functions.exceptions.AbortFunctionException;
import net.rptools.maptool.client.functions.exceptions.AssertFunctionException;
import net.rptools.maptool.client.functions.json.JSONMacroFunctions;
import net.rptools.maptool.client.ui.commandpanel.CommandPanel;
import net.rptools.maptool.client.ui.zone.ZoneRenderer;
Expand Down Expand Up @@ -64,8 +66,18 @@ private enum OutputTo {
/** Singleton instance of the MacroLinkFunction class. */
private static final MacroLinkFunction instance = new MacroLinkFunction();

private static final Pattern AUTOEXEC_PATTERN =
Pattern.compile("([^:]*)://([^/]*)/([^/]*)/([^?]*)(?:\\?(.*))?");
/** Moving all the patterns together to ensure that we don't forget any */
static final Pattern AUTOEXEC_PATTERN =
Pattern.compile("([^:]*)://(.*)/([^/]*)/([^?]*)(?:\\?(.*))?");

static final Pattern TOOLTIP_PATTERN =
Pattern.compile("([^:]*)://(.*)/([^/]*)/([^?]*)(?:\\?(.*))?");
/** Pattern to distinguish a link (group 1) from its data (group 2). */
public static final Pattern LINK_DATA_PATTERN =
Pattern.compile("((?s)[^:]*://.*/[^/]*/[^?]*\\?)(.*)?");

static final Pattern MACROLINK_PATTERN =
Pattern.compile("(?s)([^:]*)://(.*)/([^/]*)/([^?]*)(?:\\?(.*))?");

/**
* Gets and instance of the MacroLinkFunction class.
Expand Down Expand Up @@ -278,10 +290,6 @@ public String strPropListToArgs(String props) {
return args.toString();
}

/** Pattern to distinguish a link (group 1) from its data (group 2). */
public static final Pattern LINK_DATA_PATTERN =
Pattern.compile("((?s)[^:]*://[^/]*/[^/]*/[^?]*\\?)(.*)?");

/**
* Returns the link data as a json element.
*
Expand All @@ -301,9 +309,6 @@ public JsonElement getLinkDataAsJson(String linkData) {
}
}

private static final Pattern TOOLTIP_PATTERN =
Pattern.compile("([^:]*)://([^/]*)/([^/]*)/([^?]*)(?:\\?(.*))?");

/**
* Gets a string that describes the macro link.
*
Expand Down Expand Up @@ -376,9 +381,6 @@ public static void runMacroLink(String link) {
runMacroLink(link, false);
}

private static final Pattern macroLink =
Pattern.compile("(?s)([^:]*)://([^/]*)/([^/]*)/([^?]*)(?:\\?(.*))?");

/**
* Runs the macro specified by the link.
*
Expand All @@ -390,7 +392,7 @@ public static void runMacroLink(String link, boolean setVars) {
if (link == null || link.length() == 0) {
return;
}
Matcher m = macroLink.matcher(link);
Matcher m = MACROLINK_PATTERN.matcher(link);

if (m.matches() && m.group(1).equalsIgnoreCase("macro")) {
OutputTo outputTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
caseName,macro,link,data
no slashes in macro name,macro://jukebox_playAllClient@lib:bizland5e/all/Impersonated?281_Escape_from_Shadow.mp3,macro://jukebox_playAllClient@lib:bizland5e/all/Impersonated?,281_Escape_from_Shadow.mp3
slashes in macro name,macro://jukebox/playAllClient@lib:bizland5e/all/Impersonated?281_Escape_from_Shadow.mp3,macro://jukebox/playAllClient@lib:bizland5e/all/Impersonated?,281_Escape_from_Shadow.mp3
spaces before the protocol, macro://macroName@lib:token/all/Impersonated?val,macro://macroName@lib:token/all/Impersonated?,val
minimal match,:////?,:////?,""
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
caseName,macroLink,protocol,macroName,who,targets,val
no slashes in macro name,macro://jukebox_playAllClient@lib:bizland5e/all/Impersonated?281_Escape_from_Shadow.mp3,macro,jukebox_playAllClient@lib:bizland5e,all,Impersonated,281_Escape_from_Shadow.mp3
slashes in macro name,macro://jukebox/playAllClient@lib:bizland5e/all/Impersonated?281_Escape_from_Shadow.mp3,macro,jukebox/playAllClient@lib:bizland5e,all,Impersonated,281_Escape_from_Shadow.mp3
spaces before the protocol, macro://macroName@lib:token/all/Impersonated?val,macro,macroName@lib:token,all,Impersonated,val
minimal match,:////,"","","","",
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* This software Copyright by the RPTools.net development team, and
* licensed under the Affero GPL Version 3 or, at your option, any later
* version.
*
* MapTool Source Code 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.
*
* You should have received a copy of the GNU Affero General Public
* License * along with this source Code. If not, please visit
* <http://www.gnu.org/licenses/> and specifically the Affero license
* text at <http://www.gnu.org/licenses/agpl.html>.
*/
package net.rptools.maptool.client.functions;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;

class MacroLinkFunctionTest {

@ParameterizedTest(name = "{index} - {0} is properly parsed")
@CsvFileSource(
resources = "/net/rptools/maptool/client/functions/macroURLCases.csv",
numLinesToSkip = 1)
void testMacroLinkPattern(
String caseName,
String macroLink,
String protocol,
String macroName,
String who,
String target,
String val) {
Pattern macroLinkPattern = MacroLinkFunction.MACROLINK_PATTERN;

Matcher matcher = macroLinkPattern.matcher(macroLink);

assertTrue(matcher.matches());
assertEquals(protocol, matcher.group(1));
assertEquals(macroName, matcher.group(2));
assertEquals(who, matcher.group(3));
assertEquals(target, matcher.group(4));
assertEquals(val, matcher.group(5));
}

@ParameterizedTest(name = "{index} - {0} is properly parsed")
@CsvFileSource(
resources = "/net/rptools/maptool/client/functions/macroURLCases.csv",
numLinesToSkip = 1)
void testAutoExecPattern(
String caseName,
String macroLink,
String protocol,
String macroName,
String who,
String target,
String val) {
Pattern autoexecPattern = MacroLinkFunction.AUTOEXEC_PATTERN;

Matcher matcher = autoexecPattern.matcher(macroLink);

assertTrue(matcher.matches());
assertEquals(protocol, matcher.group(1));
assertEquals(macroName, matcher.group(2));
assertEquals(who, matcher.group(3));
assertEquals(target, matcher.group(4));
assertEquals(val, matcher.group(5));
}

@ParameterizedTest(name = "{index} - {0} is properly parsed")
@CsvFileSource(
resources = "/net/rptools/maptool/client/functions/macroURLCases.csv",
numLinesToSkip = 1)
void testTooltipPattern(
String caseName,
String macroLink,
String protocol,
String macroName,
String who,
String target,
String val) {
Pattern tooltipPattern = MacroLinkFunction.TOOLTIP_PATTERN;

Matcher matcher = tooltipPattern.matcher(macroLink);

assertTrue(matcher.matches());
assertEquals(protocol, matcher.group(1));
assertEquals(macroName, matcher.group(2));
assertEquals(who, matcher.group(3));
assertEquals(target, matcher.group(4));
assertEquals(val, matcher.group(5));
}

@ParameterizedTest(name = "{index} - {0} is properly parsed")
@CsvFileSource(
resources = "/net/rptools/maptool/client/functions/linkDataCases.csv",
numLinesToSkip = 1)
void testLinkDataPattern(String caseName, String macro, String macroLink, String macroData) {
Pattern linkDataPattern = MacroLinkFunction.LINK_DATA_PATTERN;

Matcher matcher = linkDataPattern.matcher(macro);

assertTrue(matcher.matches());
assertEquals(macroLink, matcher.group(1));
assertEquals(macroData, matcher.group(2));
}
}

0 comments on commit 4f22f04

Please sign in to comment.