/* * Copyright 2009-2012 The 99 Software Foundation * * 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 org.nnsoft.guice.rocoto.variables; import static java.text.MessageFormat.format; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.HashMap; import java.util.Map; import org.junit.Before; import org.junit.Test; /** * Test variable resolving with {@link AntStyleParser}: default value, variables in default value, dynamic variable, recursive variable, etc. * */ public class VariableResolvingTestCase { private VariablesMap variablesMap; /** * Set up some variables use cases to test on */ @Before public void setUp() { variablesMap = new VariablesMap(new AntStyleParser()); variablesMap.put("prop.1", "One"); variablesMap.put("prop.2", "Two"); variablesMap.put("prop.3", "Three"); variablesMap.put("found", "I'm here"); variablesMap.put("real", "delegated value"); variablesMap.put("dollarSymbol", "$"); variablesMap.put("dollarGod", "$$$ Prey the $ god! ${dollarSymbol}${dollarSymbol}${dollarSymbol}"); variablesMap.put("Three", "yeah"); variablesMap.put("simple", "${prop.1}, ${prop.2}, ${prop.3}"); variablesMap.put("delegate", "${real|fallback value}"); variablesMap.put("withDefault", "${not.found|default value}"); variablesMap.put("withEmptyDefault", "${not.found|}"); variablesMap.put("withVariableDefault", "${not.found|${found}}"); variablesMap.put("withDelegatedVariableDefault", "${not.found|${delegate}}"); variablesMap.put("withMixinDefault", "${not.found|${found}, and i'm hungry}"); variablesMap.put("withMixinDefault2", "${not.found|${prop.1} moment please, ok ${found}}"); variablesMap.put("withDefaultOfDefault", "${not.found|${not.found.again|Crap!}}"); variablesMap.put("withLotsOfDefault", "${not.found|${not.found.again|${found} to ${last.hope|${oh.really|kill}} it with fire!}}"); variablesMap.put("dynamicSimpleVariable", "${${prop.1}}"); variablesMap.put("dynamicDefaultVariable", "Property: ${prop.${number|1}}!"); variablesMap.put("dynamicDefaultVariableWithDefault", "${${prop.4|${prop.1}}|fallback}"); variablesMap.put("dynamicDefaultVariableWithDefaultDynamicVariable", "${${prop.4|${prop.1}}|${${fallback|${prop.3}}}}"); variablesMap.put("hello.en", "Hi!"); variablesMap.put("hello.fr", "Salut !"); variablesMap.put("hello.i18n", "${hello.${locale|en}}"); variablesMap.put("trimKey", "${prop.1}"); variablesMap.put("notrimKey", "${ prop.1 }"); variablesMap.put("trimDefault", "${not.found|default}"); variablesMap.put("notrimDefault", "${not.found| default }"); variablesMap.put("trimDynamic", "${${prop.3}}"); variablesMap.put("notrimDynamic", "${ ${ prop.3 } }"); } /** * Test variable replacement. */ @Test public void verifySimpleVariables() { assertEquals("One, Two, Three", variablesMap.get("simple")); } /** * Test variables transitivity. */ @Test public void verifyDelegateVariables() { assertEquals("delegated value", variablesMap.get("delegate")); } /** * Test variables with simple default value. */ @Test public void verifyVariablesWithDefault() { assertNull(variablesMap.get("not.found")); assertEquals("default value", variablesMap.get("withDefault")); variablesMap.put("not.found", "Surprise!"); assertEquals("Surprise!", variablesMap.get("withDefault")); } /** * Test variables with empty default value. */ @Test public void verifyVariablesWithEmptyDefault() { assertNull(variablesMap.get("not.found")); assertEquals("", variablesMap.get("withEmptyDefault")); variablesMap.put("not.found", "Surprise!"); assertEquals("Surprise!", variablesMap.get("withEmptyDefault")); } /** * Test variables with variable as default value. */ @Test public void verifyVariablesWithVariableAsDefault() { assertNull(variablesMap.get("not.found")); assertEquals("I'm here", variablesMap.get("withVariableDefault")); variablesMap.put("not.found", "Surprise!"); assertEquals("Surprise!", variablesMap.get("withVariableDefault")); } /** * Test variables transitivity on default variable. */ @Test public void verifyVariablesWithDelegatedVariableAsDefault() { assertNull(variablesMap.get("not.found")); assertEquals("delegated value", variablesMap.get("withDelegatedVariableDefault")); variablesMap.put("not.found", "Surprise!"); assertEquals("Surprise!", variablesMap.get("withDelegatedVariableDefault")); } /** * Test variables with mixin default value. */ @Test public void verifyVariablesWithMixinDefault() { assertNull(variablesMap.get("not.found")); assertEquals("I'm here, and i'm hungry", variablesMap.get("withMixinDefault")); } /** * Test variables with mixin default value. */ @Test public void verifyVariablesWithMixinDefault2() { assertNull(variablesMap.get("not.found")); assertEquals("One moment please, ok I'm here", variablesMap.get("withMixinDefault2")); } /** * Test variables with nested default value. */ @Test public void verifyVariablesWithDefaultOfDefault() { assertNull(variablesMap.get("not.found")); assertNull(variablesMap.get("not.found.again")); assertEquals("Crap!", variablesMap.get("withDefaultOfDefault")); variablesMap.put("not.found.again", "Lesser crap!"); assertEquals("Lesser crap!", variablesMap.get("withDefaultOfDefault")); variablesMap.put("not.found", "At least!"); assertEquals("At least!", variablesMap.get("withDefaultOfDefault")); } /** * Test variables with complex mixin nested default value. */ @Test public void verifyVariablesWithNestedDefaults() { assertNull(variablesMap.get("not.found")); assertNull(variablesMap.get("not.found.again")); assertNull(variablesMap.get("last.hope")); assertNull(variablesMap.get("oh.really")); assertEquals("I'm here to kill it with fire!", variablesMap.get("withLotsOfDefault")); variablesMap.put("oh.really", "hurt"); assertEquals("I'm here to hurt it with fire!", variablesMap.get("withLotsOfDefault")); variablesMap.put("last.hope", "tease"); assertEquals("I'm here to tease it with fire!", variablesMap.get("withLotsOfDefault")); variablesMap.put("not.found.again", "fire any${prop.1}?"); assertEquals("fire anyOne?", variablesMap.get("withLotsOfDefault")); variablesMap.put("not.found", "don't care..."); assertEquals("don't care...", variablesMap.get("withLotsOfDefault")); } /** * Test simple dynamic variables */ @Test public void verifySimpleDynamicVariables() { assertNull(variablesMap.get("One")); variablesMap.put("One", "like PHP!"); assertEquals("like PHP!", variablesMap.get("dynamicSimpleVariable")); } /** * Test variables which name is based on other variables with default. */ @Test public void verifyDynamicDefaultVariables() { assertNull(variablesMap.get("number")); assertEquals("Property: One!", variablesMap.get("dynamicDefaultVariable")); variablesMap.put("number", "2"); assertEquals("Property: Two!", variablesMap.get("dynamicDefaultVariable")); variablesMap.put("number", "3"); assertEquals("Property: Three!", variablesMap.get("dynamicDefaultVariable")); variablesMap.put("number", "${not.found|2}"); assertNull(variablesMap.get("not.found")); assertEquals("Property: Two!", variablesMap.get("dynamicDefaultVariable")); } /** * Test variables which name is based on other variables with default. */ @Test public void verifyDynamicDefaultVariables2() { assertNull(variablesMap.get("locale")); assertEquals("Hi!", variablesMap.get("hello.i18n")); variablesMap.put("locale", "fr"); assertEquals("Salut !", variablesMap.get("hello.i18n")); } /** * Test dynamic default variables with default value */ @Test public void verifyDynamicDefaultVariablesWithDefault() { assertNull(variablesMap.get("prop.4")); assertNull(variablesMap.get("One")); assertEquals("fallback", variablesMap.get("dynamicDefaultVariableWithDefault")); variablesMap.put("One", "${prop.2}"); assertEquals("Two", variablesMap.get("dynamicDefaultVariableWithDefault")); variablesMap.put("prop.4", "prop.1"); assertEquals("One", variablesMap.get("dynamicDefaultVariableWithDefault")); } /** * Test dynamic default variables with default dynamic variable */ @Test public void verifyDynamicDefaultVariableWithDefaultDynamicVariable() { assertNull(variablesMap.get("prop.4")); assertNull(variablesMap.get("One")); assertNull(variablesMap.get("fallback")); assertEquals("yeah", variablesMap.get("dynamicDefaultVariableWithDefaultDynamicVariable")); variablesMap.put("fallback", "prop.3"); assertEquals("Three", variablesMap.get("dynamicDefaultVariableWithDefaultDynamicVariable")); variablesMap.put("One", "${prop.2}"); assertEquals("Two", variablesMap.get("dynamicDefaultVariableWithDefaultDynamicVariable")); variablesMap.put("prop.4", "prop.1"); assertEquals("One", variablesMap.get("dynamicDefaultVariableWithDefaultDynamicVariable")); } @Test public void verifyGreatAnswer() { Map<String, String> t = new HashMap<String, String>(); t.put("g", "2g"); t.put("gg2", "2"); t.put("h", "${${${g}4|${g}2}}"); t.put("2g", "gg"); t.put("2g2", "4"); t.put("gg", "${h}${4|${${2g}2}}"); variablesMap.clear(); variablesMap.putAll(t); assertEquals("42", variablesMap.get("gg")); assertEquals(6, variablesMap.size()); } /** * Check no infinite loop on direct recursion.<br> * Check recursive variable grow each time variables are resolved.<br> */ @Test public void verifyVariablesWithNerdyStuffLikeRecursion() { try { variablesMap.clear(); variablesMap.put("GNU", "${GNU}'s Not UNIX"); String one = variablesMap.get("GNU"); variablesMap.put("whatever", "we just want to force map to resolve variables again..."); String two = variablesMap.get("GNU"); assertTrue(one.length() < two.length()); } catch (Error ouch) { fail(ouch.getMessage()); } } /** * Check no infinite loop on indirect recursion.<br> * Check recursive variable grow each time variables are resolved.<br> */ @Test public void verifyVariablesWithNerdyStuffLikeIndirectRecursion() { try { variablesMap.put("a", "${found} I am ${b} "); variablesMap.put("b", "what ${a}"); String one = variablesMap.get("a"); variablesMap.put("whatever", "we just want to force map to resolve variables again..."); String two = variablesMap.get("a"); assertTrue(one.length() < two.length()); } catch (Error ouch) { fail(ouch.getMessage()); } } /** * Check no infinite loop on indirect recursion.<br> * Check recursive variable doesn't grow each time variables are resolved.<br> */ @Test public void verifyDynamicVariablesRecursion() { try { variablesMap.put("divideByZero", "${${divideByZero}}"); String one = variablesMap.get("divideByZero"); variablesMap.put("whatever", "we just want to force map to resolve variables again..."); String two = variablesMap.get("divideByZero"); // Variable must have the same length here assertTrue(one.length() == two.length()); } catch (Error ouch) { fail(ouch.getMessage()); } } /** * Check we can use the dollar symbol alone in variable */ @Test public void verifyDollarValue() { assertEquals("$", variablesMap.get("dollarSymbol")); assertEquals("$$$ Prey the $ god! $$$", variablesMap.get("dollarGod")); } /** * Test variables removal. */ @Test public void verifyVariablesRemoval() { assertEquals("delegated value", variablesMap.get("delegate")); variablesMap.remove("real"); assertEquals("fallback value", variablesMap.get("delegate")); } /** * Test parser change */ @Test public void verifyParserChange() { assertEquals("One", variablesMap.get("prop.1")); variablesMap.setParser(new DummyParser()); assertEquals("enO", variablesMap.get("prop.1")); variablesMap.setParser(new AntStyleParser()); assertEquals("One", variablesMap.get("prop.1")); } /** * Test trimming on variable key */ @Test public void verifyTrimOnKey() { assertEquals(variablesMap.get("trimKey"), variablesMap.get("notrimKey")); variablesMap.put("trimedDefault", "${not.found|default}"); variablesMap.put("untrimedDefault", "${not.found| default }"); variablesMap.put("untrimedDynamic", "${${prop.3}}"); variablesMap.put("trimedDynamic", "${ ${ prop3 } }"); } /** * Test trimming on variable default value */ @Test public void verifyTrimOnDefault() { assertNull(variablesMap.get("not.found")); assertEquals(variablesMap.get("trimDefault"), variablesMap.get("notrimDefault")); variablesMap.put("not.found", "Surprise!"); assertEquals("Surprise!", variablesMap.get("trimDefault")); assertEquals(variablesMap.get("trimDefault"), variablesMap.get("notrimDefault")); } /** * Test trimming on dynamic variable */ @Test public void verifyTrimOnDynamic() { assertEquals("yeah", variablesMap.get("trimDynamic")); assertEquals(variablesMap.get("trimDynamic"), variablesMap.get("notrimDynamic")); } /** * Test trimming on recursive variable */ @Test public void verifyTrimOnRecursion() { try { variablesMap.put("GNU", "${ GNU }'s Not UNIX"); } catch (Error ouch) { fail(ouch.getMessage()); } } /** * Test syntax check for incorrect variable value */ @Test public void verifySyntaxErrorMissingClosedBracket() { verifySyntaxError("${foo"); verifySyntaxError("${"); verifySyntaxError("${${ds}"); verifySyntaxError("${fd${fdfd}"); verifySyntaxError("${fd|${fdfd}"); verifySyntaxError("dsd ${fd"); } private void verifySyntaxError( String value ) { try { variablesMap.put("mustFail", value); fail(format("Expected an IllegalArgumentException for syntaxically incorrect variable value ''{0}''.", value)); } catch (IllegalArgumentException expected) { // ok } } }