/* * Copyright (c) 2006-2014 DMDirc Developers * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.dmdirc.actions; import com.dmdirc.Channel; import com.dmdirc.Server; import com.dmdirc.ServerState; import com.dmdirc.config.InvalidIdentityFileException; import com.dmdirc.interfaces.ActionController; import com.dmdirc.interfaces.CommandController; import com.dmdirc.interfaces.config.AggregateConfigProvider; import com.dmdirc.parser.interfaces.ChannelClientInfo; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import static org.junit.Assert.*; import static org.mockito.Mockito.*; @RunWith(Parameterized.class) public class ActionSubstitutorTest { private static final Map SETTINGS = new HashMap<>(); private final String input, expected; private final Channel channel; private final ActionSubstitutor substitutor; private final Object[] args; @BeforeClass public static void setup() throws InvalidIdentityFileException { SETTINGS.put("alpha", "A"); SETTINGS.put("bravo", "$alpha"); SETTINGS.put("charlie", "${bravo}"); SETTINGS.put("delta", "${${bravo}${bravo}}"); SETTINGS.put("AA", "win!"); } public ActionSubstitutorTest(final String input, final String expected) { this.input = input; this.expected = expected; this.channel = mock(Channel.class); final AggregateConfigProvider manager = mock(AggregateConfigProvider.class); final Server server = mock(Server.class); final ChannelClientInfo clientInfo = mock(ChannelClientInfo.class); when(channel.getConnection()).thenReturn(server); when(channel.getConfigManager()).thenReturn(manager); when(server.getState()).thenReturn(ServerState.DISCONNECTED); when(server.getAwayMessage()).thenReturn("foo"); when(server.getProtocol()).thenReturn("$alpha"); when(manager.getOptions(eq("actions"))).thenReturn(SETTINGS); for (Map.Entry entry : SETTINGS.entrySet()) { when(manager.hasOptionString("actions", entry.getKey())).thenReturn(true); when(manager.getOption("actions", entry.getKey())).thenReturn(entry.getValue()); } final ActionController controller = mock(ActionController.class); when(controller.getComponent("STRING_STRING")).thenReturn(CoreActionComponent.STRING_STRING); when(controller.getComponent("STRING_LENGTH")).thenReturn(CoreActionComponent.STRING_LENGTH); when(controller.getComponent("SERVER_NETWORK")).thenReturn(CoreActionComponent.SERVER_NETWORK); when(controller.getComponent("SERVER_PROTOCOL")).thenReturn(CoreActionComponent.SERVER_PROTOCOL); when(controller.getComponent("SERVER_MYAWAYREASON")).thenReturn(CoreActionComponent.SERVER_MYAWAYREASON); substitutor = new ActionSubstitutor(controller, mock(CommandController.class), mock(AggregateConfigProvider.class), CoreActionType.CHANNEL_MESSAGE); args = new Object[]{ channel, clientInfo, "1 2 3 fourth_word_here 5 6 7" }; } @Test public void testSubstitution() { assertEquals(expected, substitutor.doSubstitution(input, args)); } @Parameterized.Parameters public static List data() { final String[][] tests = { // -- Existing behaviour ------------------------------------------- // ---- No subs at all --------------------------------------------- {"no subs here!", "no subs here!"}, // ---- Config subs ------------------------------------------------ {"$alpha", "A"}, {"--$alpha--", "--A--"}, // ---- Word subs -------------------------------------------------- {"$1", "1"}, {"$4", "fourth_word_here"}, {"$5-", "5 6 7"}, // ---- Component subs --------------------------------------------- {"${2.STRING_LENGTH}", "28"}, {"${2.STRING_STRING}", "1 2 3 fourth_word_here 5 6 7"}, // ---- Server subs ------------------------------------------------ {"${SERVER_MYAWAYREASON}", "foo"}, // ---- Combinations ----------------------------------------------- {"${1}${2.STRING_LENGTH}$alpha", "128A"}, {"$alpha$4${SERVER_MYAWAYREASON}", "Afourth_word_herefoo"}, // -- New behaviour ------------------------------------------------ // ---- Config subs ------------------------------------------------ {"${alpha}", "A"}, {"\\$alpha", "$alpha"}, {"$bravo", "A"}, {"$charlie", "A"}, {"$delta", "win!"}, {"$sigma", "not_defined"}, // ---- Word subs -------------------------------------------------- {"$5-6", "5 6"}, {"${5-6}", "5 6"}, {"${5-$6}", "5 6"}, {"${5-${${6}}}", "5 6"}, // ---- Component subs --------------------------------------------- {"${2.STRING_STRING.STRING_LENGTH}", "28"}, {"${2.STRING_FLUB.STRING_LENGTH}", "illegal_component"}, {"${SERVER_NETWORKFOO}", "illegal_component"}, {"${SERVER_NETWORK}", "not_connected"}, {"${SERVER_PROTOCOL}", "$alpha"}, // ---- Escaping --------------------------------------------------- {"\\$1", "$1"}, {"\\$alpha $alpha", "$alpha A"}, {"\\$$1", "$1"}, {"\\\\$4", "\\fourth_word_here"}, {"\\\\${4}", "\\fourth_word_here"}, {"\\\\\\$4", "\\$4"}, }; return Arrays.asList(tests); } }