diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 0e12312..4d1216a 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -13,5 +13,14 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 + - name: Run unit tests + run: ./gradlew test + - name: Determine coverage + run: ./gradlew jacocoTestReport + - name: Scan with Sonar + run: ./gradlew sonar + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - name: Build with Gradle run: ./gradlew build diff --git a/build.gradle b/build.gradle index 749e0bb..aaabe2a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,27 @@ plugins { id 'pl.allegro.tech.build.axion-release' version '1.10.1' + id "org.sonarqube" version "2.8" + id 'jacoco' id 'java' } +sonarqube { + properties { + property "sonar.projectKey", "kdebisschop_rundeck-conditional-logic-plugin" + property "sonar.organization", "kdebisschop" + property "sonar.host.url", "https://sonarcloud.io" + property "sonar.login", "807fd8589d7244bd324b5fecdfca9614d8a40c8c" + } +} + +jacocoTestReport { + reports { + xml.enabled true + csv.enabled false + html.destination file("${buildDir}/jacocoHtml") + } +} + apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' diff --git a/src/main/java/com/bioraft/rundeck/conditional/IfElse.java b/src/main/java/com/bioraft/rundeck/conditional/IfElse.java index e68cf17..6ee45f2 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/IfElse.java +++ b/src/main/java/com/bioraft/rundeck/conditional/IfElse.java @@ -19,6 +19,8 @@ import com.dtolabs.rundeck.core.dispatcher.ContextView; import com.dtolabs.rundeck.plugins.step.PluginStepContext; +import java.util.Map; + /** * Workflow Node Step Plug-in to choose one of several values to uplift into a * step variable. @@ -45,6 +47,11 @@ public class IfElse { private PluginStepContext ctx; + private Map cfg; + + /** If specified, also create a variable in global export context. */ + private boolean elevate = false; + /** * Constructor sets PluginStepContext. * @@ -54,6 +61,16 @@ public IfElse(PluginStepContext ctx) { this.ctx = ctx; } + public IfElse setElevate(boolean elevate) { + this.elevate = elevate; + return this; + } + + public IfElse setCfg(Map cfg) { + this.cfg = cfg; + return this; + } + /** * Add ifTrue value to SharedOutputContext if condition passes, otherwise add * ifFalse if not null. @@ -65,63 +82,93 @@ public IfElse(PluginStepContext ctx) { * @param comparisonValue The value to test against. * @param ifTrue The value to return if comparison is true. * @param ifFalse The value to return if comparison is false. - * @param elevateToGlobal If specified, also create a variable in global export - * context. */ public void ifElse(String group, String name, String testValue, String operator, String comparisonValue, - String ifTrue, String ifFalse, boolean elevateToGlobal) { + String ifTrue, String ifFalse) { + + group = cfg.getOrDefault("group", group).toString(); + name = cfg.getOrDefault("name", name).toString(); + testValue = cfg.getOrDefault("testValue", testValue).toString(); + operator = cfg.getOrDefault("operator", operator).toString(); + comparisonValue = cfg.getOrDefault("comparisonValue", comparisonValue).toString(); + ifTrue = cfg.getOrDefault("ifTrue", ifTrue).toString(); + ifFalse = cfg.getOrDefault("ifFalse", ifFalse).toString(); String value; - String matched = null; + String matched; - if (operator.equals(STRING_EQ) && testValue.endsWith(comparisonValue)) { - matched = STRING_EQ; + if (operator.equals(STRING_EQ) && testValue.equals(comparisonValue)) { + matched = STRING_EQ; } else if (operator.equals(STRING_NE) && !testValue.equals(comparisonValue)) { - matched = STRING_NE; - } else if (operator.equals(STRING_BEG) && testValue.startsWith(comparisonValue)) { - matched = STRING_BEG; - } else if (operator.equals(STRING_END) && testValue.endsWith(comparisonValue)) { - matched = STRING_END; - } else if (operator.equals(STRING_LT) && testValue.compareTo(comparisonValue) < 0) { - matched = STRING_LT; - } else if (operator.equals(STRING_LE) && testValue.compareTo(comparisonValue) <= 0) { - matched = STRING_LE; - } else if (operator.equals(STRING_GE) && testValue.compareTo(comparisonValue) >= 0) { - matched = STRING_GE; - } else if (operator.equals(STRING_GT) && testValue.compareTo(comparisonValue) > 0) { - matched = STRING_GT; - } else if (operator.equals(NUMBER_LT) && Double.parseDouble(testValue) < Double.parseDouble(comparisonValue)) { - matched = NUMBER_LT; - } else if (operator.equals(NUMBER_LE) && Double.parseDouble(testValue) <= Double.parseDouble(comparisonValue)) { - matched = NUMBER_LE; - } else if (operator.equals(NUMBER_GE) && Double.parseDouble(testValue) >= Double.parseDouble(comparisonValue)) { - matched = NUMBER_GE; - } else if (operator.equals(NUMBER_GT) && Double.parseDouble(testValue) > Double.parseDouble(comparisonValue)) { - matched = NUMBER_GT; - } else if (operator.equals(NUMBER_EQ) && Double.parseDouble(testValue) == Double.parseDouble(comparisonValue)) { - matched = NUMBER_EQ; - } else if (operator.equals(NUMBER_NE) && Double.parseDouble(testValue) != Double.parseDouble(comparisonValue)) { - matched = NUMBER_NE; + matched = STRING_NE; + } else { + matched = compareString(operator, testValue, comparisonValue); } - if (matched != null) { - value = ifTrue; - ctx.getLogger().log(Constants.DEBUG_LEVEL, "Matched " + matched + ", returning ifTrue value."); - } else { + if (matched.equals("")) { + matched = compareNumeric(operator, testValue, comparisonValue); + } + + if (matched.equals("")) { if (ifFalse == null || ifFalse.length() == 0) { ctx.getLogger().log(Constants.DEBUG_LEVEL, "No match, default is empty."); return; } ctx.getLogger().log(Constants.DEBUG_LEVEL, "No match, using default."); value = ifFalse; + } else { + value = ifTrue; + ctx.getLogger().log(Constants.DEBUG_LEVEL, "Matched " + matched + ", returning ifTrue value."); } ctx.getOutputContext().addOutput(group, name, value); - if (elevateToGlobal) { + if (elevate) { String groupName = group + "." + name; ctx.getOutputContext().addOutput(ContextView.global(), "export", groupName, value); ctx.getLogger().log(Constants.DEBUG_LEVEL, "Elevating to globsal ${export." + groupName + "}."); } } + private String compareString(String operator, String testValue, String comparisonValue) { + if (operator.equals(STRING_BEG) && testValue.startsWith(comparisonValue)) { + return STRING_BEG; + } else if (operator.equals(STRING_END) && testValue.endsWith(comparisonValue)) { + return STRING_END; + } + + int compare = testValue.compareTo(comparisonValue); + if (operator.equals(STRING_LT) && compare < 0) { + return STRING_LT; + } else if (operator.equals(STRING_LE) && compare <= 0) { + return STRING_LE; + } else if (operator.equals(STRING_GE) && compare >= 0) { + return STRING_GE; + } else if (operator.equals(STRING_GT) && compare > 0) { + return STRING_GT; + } + return ""; + } + + private String compareNumeric(String operator, String testValue, String comparisonValue) { + try { + double testDouble = Double.parseDouble(testValue); + double comparisonDouble = Double.parseDouble(comparisonValue); + if (operator.equals(NUMBER_LT) && testDouble < comparisonDouble) { + return NUMBER_LT; + } else if (operator.equals(NUMBER_LE) && testDouble <= comparisonDouble) { + return NUMBER_LE; + } else if (operator.equals(NUMBER_GE) && testDouble >= comparisonDouble) { + return NUMBER_GE; + } else if (operator.equals(NUMBER_GT) && testDouble > comparisonDouble) { + return NUMBER_GT; + } else if (operator.equals(NUMBER_EQ) && testDouble == comparisonDouble) { + return NUMBER_EQ; + } else if (operator.equals(NUMBER_NE) && testDouble != comparisonDouble) { + return NUMBER_NE; + } + } catch (Exception e) { + return ""; + } + return ""; + } } diff --git a/src/main/java/com/bioraft/rundeck/conditional/IfElseNodeStepPlugin.java b/src/main/java/com/bioraft/rundeck/conditional/IfElseNodeStepPlugin.java index 7e16195..3b0b7b6 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/IfElseNodeStepPlugin.java +++ b/src/main/java/com/bioraft/rundeck/conditional/IfElseNodeStepPlugin.java @@ -53,7 +53,7 @@ public class IfElseNodeStepPlugin implements NodeStepPlugin { @PluginProperty(title = "Operator", description = "Comparison operator", required = true) @SelectValues(values = { IfElse.STRING_EQ, IfElse.STRING_NE, IfElse.STRING_LT, IfElse.STRING_LE, IfElse.STRING_GE, IfElse.STRING_GT, IfElse.STRING_BEG, IfElse.STRING_END, IfElse.NUMBER_EQ, IfElse.NUMBER_NE, - IfElse.NUMBER_LT, IfElse.NUMBER_LE, IfElse.NUMBER_GE, IfElse.NUMBER_GT }, freeSelect = false) + IfElse.NUMBER_LT, IfElse.NUMBER_LE, IfElse.NUMBER_GE, IfElse.NUMBER_GT }) private String operator; @PluginProperty(title = "Comparison Value", description = "Second test value", required = true) @@ -62,31 +62,23 @@ public class IfElseNodeStepPlugin implements NodeStepPlugin { @PluginProperty(title = "If True", description = "Value to assign if comparison is true", required = true) private String ifTrue; - @PluginProperty(title = "If False", description = "Value to assign if comparison is false", required = false) + @PluginProperty(title = "If False", description = "Value to assign if comparison is false") private String ifFalse; - @PluginProperty(title = "Make global?", description = "Elevate this variable to global scope (default: false)", required = false) + @PluginProperty(title = "Make global?", description = "Elevate this variable to global scope (default: false)") private boolean elevateToGlobal; @Override public void executeNodeStep(PluginStepContext ctx, Map cfg, INodeEntry node) throws NodeStepException { - String group = cfg.getOrDefault("group", this.group).toString(); - String name = cfg.getOrDefault("name", this.name).toString(); - String testValue = cfg.getOrDefault("testValue", this.testValue).toString(); - String operator = cfg.getOrDefault("operator", this.operator).toString(); - String comparisonValue = cfg.getOrDefault("comparisonValue", this.comparisonValue).toString(); - String ifTrue = cfg.getOrDefault("ifTrue", this.ifTrue).toString(); - boolean elevateToGlobal = (boolean) cfg.getOrDefault("elevateToGlobal", this.elevateToGlobal); - if (cfg.containsKey("ifFalse") && cfg.get("ifFalse") != null) { - ifFalse = cfg.getOrDefault("ifFalse", this.ifFalse).toString(); - } - - ctx.getLogger().log(Constants.DEBUG_LEVEL, - "Setting " + group + "." + name + " based on " + testValue + " " + operator + " " + comparisonValue); - - (new IfElse(ctx)).ifElse(group, name, testValue, operator, comparisonValue, ifTrue, ifFalse, elevateToGlobal); + elevateToGlobal = (boolean) cfg.getOrDefault("elevateToGlobal", this.elevateToGlobal); + + String message = "Setting " + group + "." + name + " based on " + testValue + " " + operator + " " + comparisonValue; + ctx.getLogger().log(Constants.DEBUG_LEVEL, message); + + (new IfElse(ctx)).setElevate(elevateToGlobal).setCfg(cfg) + .ifElse(group, name, testValue, operator, comparisonValue, ifTrue, ifFalse); } } diff --git a/src/main/java/com/bioraft/rundeck/conditional/IfElseStepPlugin.java b/src/main/java/com/bioraft/rundeck/conditional/IfElseStepPlugin.java index b3276f2..c2568df 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/IfElseStepPlugin.java +++ b/src/main/java/com/bioraft/rundeck/conditional/IfElseStepPlugin.java @@ -54,7 +54,7 @@ public class IfElseStepPlugin implements StepPlugin { IfElse.STRING_LE, IfElse.STRING_GE, IfElse.STRING_GT, IfElse.STRING_BEG, IfElse.STRING_END, IfElse.NUMBER_EQ, IfElse.NUMBER_NE, IfElse.NUMBER_LT, IfElse.NUMBER_LE, - IfElse.NUMBER_GE, IfElse.NUMBER_GT }, freeSelect = false) + IfElse.NUMBER_GE, IfElse.NUMBER_GT }) private String operator; @PluginProperty(title = "Comparison Value", description = "Second test value", required = true) @@ -63,30 +63,22 @@ public class IfElseStepPlugin implements StepPlugin { @PluginProperty(title = "If True", description = "Value to assign if comparison is true", required = true) private String ifTrue; - @PluginProperty(title = "If False", description = "Value to assign if comparison is false", required = false) + @PluginProperty(title = "If False", description = "Value to assign if comparison is false") private String ifFalse; - @PluginProperty(title = "Make global?", description = "Elevate this variable to global scope (default: false)", required = false) + @PluginProperty(title = "Make global?", description = "Elevate this variable to global scope (default: false)") private boolean elevateToGlobal; @Override public void executeStep(final PluginStepContext ctx, final Map cfg) throws StepException { - String group = cfg.getOrDefault("group", this.group).toString(); - String name = cfg.getOrDefault("name", this.name).toString(); - String testValue = cfg.getOrDefault("testValue", this.testValue).toString(); - String operator = cfg.getOrDefault("operator", this.operator).toString(); - String comparisonValue = cfg.getOrDefault("comparisonValue", this.comparisonValue).toString(); - String ifTrue = cfg.getOrDefault("ifTrue", this.ifTrue).toString(); - boolean elevateToGlobal = (boolean) cfg.getOrDefault("elevateToGlobal", this.elevateToGlobal); - if (cfg.containsKey("ifFalse") && cfg.get("ifFalse") != null) { - ifFalse = cfg.getOrDefault("ifFalse", this.ifFalse).toString(); - } - - ctx.getLogger().log(Constants.DEBUG_LEVEL, - "Setting " + group + "." + name + " based on " + testValue + " " + operator + " " + comparisonValue); - - (new IfElse(ctx)).ifElse(group, name, testValue, operator, comparisonValue, ifTrue, ifFalse, elevateToGlobal); + elevateToGlobal = (boolean) cfg.getOrDefault("elevateToGlobal", this.elevateToGlobal); + + String message = "Setting " + group + "." + name + " based on " + testValue + " " + operator + " " + comparisonValue; + ctx.getLogger().log(Constants.DEBUG_LEVEL, message); + + (new IfElse(ctx)).setElevate(elevateToGlobal).setCfg(cfg) + .ifElse(group, name, testValue, operator, comparisonValue, ifTrue, ifFalse); } } diff --git a/src/main/java/com/bioraft/rundeck/conditional/Switch.java b/src/main/java/com/bioraft/rundeck/conditional/Switch.java index 4fd6464..ef1b41f 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/Switch.java +++ b/src/main/java/com/bioraft/rundeck/conditional/Switch.java @@ -35,6 +35,8 @@ */ public class Switch { + public static final String CFG_DEFAULT_VALUE = "defaultValue"; + private PluginStepContext ctx; /** @@ -72,7 +74,6 @@ public void switchCase(String group, String name, String cases, String test, Str } catch (JsonProcessingException e) { ctx.getLogger().log(Constants.ERR_LEVEL, "Failed to parse cases."); ctx.getLogger().log(Constants.ERR_LEVEL, e.getMessage()); - e.printStackTrace(); throw e; } } @@ -126,11 +127,11 @@ public static String ensureStringIsJsonObject(String string) { if (string == null) { return ""; } - String trimmed = string.replaceFirst("^\\s*\\{?", "{").replaceFirst("\\s*$", ""); - return trimmed + (trimmed.endsWith("}") ? "" : "}"); + String trimmed = string.trim().replaceFirst(",[\\s}]*$", ""); + return (trimmed.startsWith("{") ? "" : "{") + trimmed + (trimmed.endsWith("}") ? "" : "}"); } enum Causes implements FailureReason { - InvalidJSON + INVALID_JSON } } diff --git a/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPlugin.java b/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPlugin.java index 758cedd..ec2355a 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPlugin.java +++ b/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPlugin.java @@ -32,6 +32,7 @@ import static com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants.CODE_SYNTAX_MODE; import static com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants.DISPLAY_TYPE_KEY; +import static com.bioraft.rundeck.conditional.Switch.CFG_DEFAULT_VALUE; /** * Workflow Node Step Plug-in to choose one of several values to uplift into a @@ -76,18 +77,16 @@ public void executeNodeStep(PluginStepContext ctx, Map cfg, INod name = cfg.getOrDefault("name", this.name).toString(); cases = cfg.getOrDefault("cases", this.cases).toString(); testValue = cfg.getOrDefault("testValue", this.testValue).toString(); - if (cfg.containsKey("elevateToGlobal")) { - elevateToGlobal = cfg.get("elevateToGlobal").equals("true"); - } + elevateToGlobal = cfg.getOrDefault("elevateToGlobal", String.valueOf(elevateToGlobal)).equals("true"); boolean globalHasDefault = defaultValue != null && defaultValue.length() > 0; - boolean cfgHasDefault = cfg.containsKey("defaultValue") && cfg.get("defaultValue") != null; + boolean cfgHasDefault = cfg.containsKey(CFG_DEFAULT_VALUE) && cfg.get(CFG_DEFAULT_VALUE) != null; if (cfgHasDefault) { - this.defaultValue = cfg.get("defaultValue").toString(); + this.defaultValue = cfg.get(CFG_DEFAULT_VALUE).toString(); } - ctx.getLogger().log(Constants.DEBUG_LEVEL, - "Setting " + group + "." + name + " based on " + testValue + " " + cases); + String message = "Setting " + group + "." + name + " based on " + testValue + " " + cases; + ctx.getLogger().log(Constants.DEBUG_LEVEL, message); try { if (cfgHasDefault || globalHasDefault) { @@ -96,7 +95,7 @@ public void executeNodeStep(PluginStepContext ctx, Map cfg, INod (new Switch(ctx)).switchCase(group, name, cases, testValue, elevateToGlobal); } } catch (JsonProcessingException e) { - throw new NodeStepException(e.getMessage(), Switch.Causes.InvalidJSON, node.getNodename()); + throw new NodeStepException(e.getMessage(), Switch.Causes.INVALID_JSON, node.getNodename()); } } diff --git a/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseStepPlugin.java b/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseStepPlugin.java index 26c84db..2d45534 100644 --- a/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseStepPlugin.java +++ b/src/main/java/com/bioraft/rundeck/conditional/SwitchCaseStepPlugin.java @@ -31,6 +31,7 @@ import static com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants.CODE_SYNTAX_MODE; import static com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants.DISPLAY_TYPE_KEY; +import static com.bioraft.rundeck.conditional.Switch.CFG_DEFAULT_VALUE; /** * Workflow Node Step Plug-in to choose one of several values to uplift into a @@ -73,14 +74,12 @@ public void executeStep(final PluginStepContext ctx, final Map c name = cfg.getOrDefault("name", this.name).toString(); cases = cfg.getOrDefault("cases", this.cases).toString(); testValue = cfg.getOrDefault("testValue", this.testValue).toString(); - if (cfg.containsKey("elevateToGlobal")) { - elevateToGlobal = cfg.get("elevateToGlobal").equals("true"); - } + elevateToGlobal = cfg.getOrDefault("elevateToGlobal", String.valueOf(elevateToGlobal)).equals("true"); boolean globalHasDefault = defaultValue != null && defaultValue.length() > 0; - boolean cfgHasDefault = cfg.containsKey("defaultValue") && cfg.get("defaultValue") != null; + boolean cfgHasDefault = cfg.containsKey(CFG_DEFAULT_VALUE) && cfg.get(CFG_DEFAULT_VALUE) != null; if (cfgHasDefault) { - this.defaultValue = cfg.get("defaultValue").toString(); + this.defaultValue = cfg.get(CFG_DEFAULT_VALUE).toString(); } ctx.getLogger().log(Constants.DEBUG_LEVEL, @@ -94,7 +93,7 @@ public void executeStep(final PluginStepContext ctx, final Map c } } catch ( JsonProcessingException e) { - throw new StepException(e.getMessage(), Switch.Causes.InvalidJSON); + throw new StepException(e.getMessage(), Switch.Causes.INVALID_JSON); } } diff --git a/src/test/java/com/bioraft/rundeck/conditional/IfElseTest.java b/src/test/java/com/bioraft/rundeck/conditional/IfElseTest.java new file mode 100644 index 0000000..21491c4 --- /dev/null +++ b/src/test/java/com/bioraft/rundeck/conditional/IfElseTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2019 BioRAFT, Inc. (http://bioraft.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.bioraft.rundeck.conditional; + +import com.dtolabs.rundeck.core.execution.workflow.SharedOutputContext; +import com.dtolabs.rundeck.core.execution.workflow.steps.StepException; +import com.dtolabs.rundeck.plugins.PluginLogger; +import com.dtolabs.rundeck.plugins.step.PluginStepContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.*; + +/** + * Tests for IfTestStepPlugin. + * + * @author Karl DeBisschop + * @since 2019-12-11 + */ +@RunWith(MockitoJUnitRunner.class) +public class IfElseTest { + + IfElse plugin; + + @Mock + PluginStepContext context; + + @Mock + PluginLogger logger; + + @Mock + SharedOutputContext sharedOutputContext; + + Map configuration; + + @Before + public void setUp() { + this.plugin = new IfElse(context); + configuration = new HashMap<>(); + } + + @Test + public void runTrueTests() throws StepException { + int i = 0; + this.runTestTrue("apple", "eq", "apple", ++i); + this.runTestTrue("apple", "ne", "pear", ++i); + this.runTestTrue("bannana", "lt", "strawberry", ++i); + this.runTestTrue("pear", "gt", "apple", ++i); + this.runTestTrue("apple", "le", "apple", ++i); + this.runTestTrue("applepie", "ge", "apple", ++i); + this.runTestTrue("apple pie", "begins with", "apple", ++i); + this.runTestTrue("layer cake", "ends with", " cake", ++i); + this.runTestTrue("1.00", "=", "1.000", ++i); + this.runTestTrue("3", "<", "200", ++i); + this.runTestTrue("1.23", ">", "1.199", ++i); + this.runTestTrue("1", "<=", "1", ++i); + this.runTestTrue("1", ">=", "0", ++i); + this.runTestTrue("1", "!=", "2", ++i); + } + + @Test + public void runFalseTests() throws StepException { + int i = 0; + this.runTestFalse("apple", "eq", "apples", ++i); + this.runTestFalse("apple", "ne", "apple", ++i); + this.runTestFalse("bannana", "gt", "strawberry", ++i); + this.runTestFalse("pear", "lt", "apple", ++i); + this.runTestFalse("apples", "le", "apple", ++i); + this.runTestFalse("apple", "ge", "banana", ++i); + this.runTestFalse("apple pie", "begins with", "pie", ++i); + this.runTestFalse("layer cake", "ends with", "layer", ++i); + this.runTestFalse("1", "=", "2", ++i); + this.runTestFalse("300", "<", "200", ++i); + this.runTestFalse("1.13", ">", "1.199", ++i); + this.runTestFalse("1", "<=", "0", ++i); + this.runTestFalse("1", ">=", "2", ++i); + this.runTestFalse("2.0", "!=", "2.00", ++i); + } + + private void runTestTrue(String testValue, String operator, String comparison, int calls) throws StepException { + String group = "raft"; + String name = "test"; + String ifTrue = "1"; + String ifFalse = "0"; + + when(context.getOutputContext()).thenReturn(sharedOutputContext); + when(context.getLogger()).thenReturn(logger); + + this.plugin.setElevate(false).setCfg(configuration).ifElse(group, name, testValue, operator, comparison, ifTrue, ifFalse); + verify(context, atLeast(calls)).getOutputContext(); + verify(sharedOutputContext, atLeast(calls)).addOutput(eq(group), eq(name), eq(ifTrue)); + } + + private void runTestFalse(String testValue, String operator, String comparison, int calls) + throws StepException { + String group = "boat"; + String name = "real"; + String ifTrue = "yes"; + String ifFalse = "no"; + + when(context.getOutputContext()).thenReturn(sharedOutputContext); + when(context.getLogger()).thenReturn(logger); + + this.plugin.setElevate(false).setCfg(configuration).ifElse(group, name, testValue, operator, comparison, ifTrue, ifFalse); + verify(context, atLeast(calls)).getOutputContext(); + verify(sharedOutputContext, atLeast(calls)).addOutput(eq(group), eq(name), eq(ifFalse)); + } +} diff --git a/src/test/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPluginTest.java b/src/test/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPluginTest.java index 7980212..b3da176 100644 --- a/src/test/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPluginTest.java +++ b/src/test/java/com/bioraft/rundeck/conditional/SwitchCaseNodeStepPluginTest.java @@ -15,6 +15,7 @@ */ package com.bioraft.rundeck.conditional; +import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; @@ -70,6 +71,20 @@ public void setUp() { this.plugin = new SwitchCaseNodeStepPlugin(); } + @Test + public void testEnsureStringIsJsonObject() { + assertEquals("", Switch.ensureStringIsJsonObject(null)); + String given = "\"a\": \"1\""; + String expected = "{" + given + "}"; + assertEquals(expected, Switch.ensureStringIsJsonObject(given)); + assertEquals(expected, Switch.ensureStringIsJsonObject(given + ",")); + assertEquals(expected, Switch.ensureStringIsJsonObject(given + "}")); + assertEquals(expected, Switch.ensureStringIsJsonObject("{" + given)); + assertEquals(expected, Switch.ensureStringIsJsonObject("{" + given + "}")); + assertEquals(expected, Switch.ensureStringIsJsonObject("{" + given + ",}")); + assertEquals(expected, Switch.ensureStringIsJsonObject("{" + given + ", } ")); + } + @Test public void runTestOne() throws NodeStepException { Map cases = ImmutableMap.builder().put("k1", "v1").put("k2", "v2").build(); @@ -101,14 +116,40 @@ public void runTestNoDefaultValue() throws NodeStepException { this.runTestNoDefault(configuration); } + @Test + public void testStrippingTrailingComma() throws NodeStepException { + StringBuffer caseString = new StringBuffer(); + Map cases = ImmutableMap.builder().put("k1", "v1").put("k2", "v2").build(); + cases.forEach((k, v) -> caseString.append('"').append(k).append('"').append(":").append('"').append(v).append('"').append(",")); + validInput(caseString.toString()); + } + @Test(expected = NodeStepException.class) public void testInvalidCases() throws NodeStepException { StringBuffer caseString = new StringBuffer(); Map cases = ImmutableMap.builder().put("k1", "v1").put("k2", "v2").build(); - cases.forEach((k, v) -> caseString.append('"').append(k).append('"').append(":").append('"').append(v).append('"').append(",")); + cases.forEach((k, v) -> caseString.append('"').append(k).append('"').append(":").append('"').append(v).append('"').append(".")); invalidInput(caseString.toString()); } + private void validInput(String caseString) + throws NodeStepException { + + Map configuration = new HashMap<>(); + configuration.put("group", group); + configuration.put("name", name); + configuration.put("cases", caseString); + configuration.put("testValue", testValue); + configuration.put("defaultValue", defaultValue); + + when(context.getOutputContext()).thenReturn(sharedOutputContext); + when(context.getLogger()).thenReturn(logger); + + this.plugin.executeNodeStep(context, configuration, node); + verify(context, times(1)).getOutputContext(); + verify(sharedOutputContext, times(1)).addOutput(eq(group), eq(name), eq(defaultValue)); + } + private void invalidInput(String caseString) throws NodeStepException { @@ -166,7 +207,4 @@ public void runTestNoDefault(Map configuration) verify(context, never()).getOutputContext(); verify(sharedOutputContext, never()).addOutput(any(String.class), any(String.class), any(String.class)); } - - - }