This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new 5b1ea500dc expression parser - tweak to multi-word handling
5b1ea500dc is described below
commit 5b1ea500dcdbe71d2c12490906a680e251f4f722
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Feb 8 15:32:03 2024 +0000
expression parser - tweak to multi-word handling
simplify non-final-match-raw semantics
---
.../brooklyn/core/workflow/ShorthandProcessor.java | 3 +-
.../core/workflow/ShorthandProcessorEpToQst.java | 22 ++--
.../brooklyn/core/workflow/WorkflowBasicTest.java | 76 +++++++++---
.../core/workflow/WorkflowMapAndListTest.java | 15 +--
.../core/workflow/WorkflowOperandsTest.java | 14 +--
.../workflow/WorkflowParsingEdgeCasesTest.java | 134 +++++++++++++++++++++
6 files changed, 209 insertions(+), 55 deletions(-)
diff --git
a/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessor.java
b/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessor.java
index 0adbaffc23..356d655705 100644
---
a/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessor.java
+++
b/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessor.java
@@ -37,7 +37,8 @@ public class ShorthandProcessor {
return delegate.process(input);
}
- /** whether the last match should preserve quotes and spaces; default
false */
+ /** optionally skip the automatic unwrapping of a single quoted last word
lining up with the last word of a template;
+ * by default, we unwrap in that one special case, to facilitate eg return
"something fancy" */
public ShorthandProcessor withFinalMatchRaw(boolean finalMatchRaw) {
delegate.withFinalMatchRaw(finalMatchRaw);
return this;
diff --git
a/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessorEpToQst.java
b/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessorEpToQst.java
index cb94600636..6e48f8dc80 100644
---
a/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessorEpToQst.java
+++
b/core/src/main/java/org/apache/brooklyn/core/workflow/ShorthandProcessorEpToQst.java
@@ -83,7 +83,8 @@ public class ShorthandProcessorEpToQst {
return new ShorthandProcessorQstAttempt(this, input).call();
}
- /** whether the last match should preserve quotes and spaces; default
false */
+ /** optionally skip the automatic unwrapping of a single quoted last word
lining up with the last word of a template;
+ * by default, we unwrap in that one special case, to facilitate eg return
"something fancy" */
public ShorthandProcessorEpToQst withFinalMatchRaw(boolean finalMatchRaw) {
this.finalMatchRaw = finalMatchRaw;
return this;
@@ -131,7 +132,6 @@ public class ShorthandProcessorEpToQst {
inputRemaining = Strings.trimStart(inputRemaining);
if (Strings.isNonBlank(inputRemaining)) {
if (valueUpdater!=null) {
- //QuotedStringTokenizer qstInput = qst(inputRemaining);
valueUpdater.accept(getRemainderPossiblyRaw(inputRemaining));
} else {
// shouldn't come here
@@ -340,19 +340,13 @@ public class ShorthandProcessorEpToQst {
return mp.get();
}
private Maybe<String> getRemainderPossiblyRawEp(String inputRemaining)
{
- if (options.finalMatchRaw) {
- return Maybe.of(inputRemaining);
- }
- Maybe<List<ParseNodeOrValue>> mp =
ShorthandProcessorExprParser.tokenizer().parseEverything(inputRemaining);
- return mp.map(pnl -> {
- final boolean UNQUOTE_INDIVIDUAL_WORDS = false; // legacy
behaviour
-
- if (pnl.size()==1 || UNQUOTE_INDIVIDUAL_WORDS) {
- return ExpressionParser.getAllUnquoted(pnl);
- } else {
- return ExpressionParser.getUnescapedButNotUnquoted(pnl);
+ if (!options.finalMatchRaw) {
+ Maybe<List<ParseNodeOrValue>> mp =
ShorthandProcessorExprParser.tokenizer().parseEverything(inputRemaining);
+ if (mp.isPresent() && mp.get().size()==1 &&
ExpressionParser.isQuotedExpressionNode(mp.get().get(0))) {
+ return Maybe.of(ExpressionParser.getUnquoted(
mp.get().get(0) ));
}
- });
+ }
+ return Maybe.of(inputRemaining);
}
private String
getNextInputTokenUpToPossibleExpectedLiteralQst(QuotedStringTokenizer qstInput,
String nextLiteral) {
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
index 364a7090e9..1ab20b9887 100644
---
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowBasicTest.java
@@ -18,6 +18,12 @@
*/
package org.apache.brooklyn.core.workflow;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.reflect.TypeToken;
import org.apache.brooklyn.api.entity.Entity;
@@ -45,13 +51,38 @@ import
org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan;
import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
-import org.apache.brooklyn.core.workflow.steps.*;
-import org.apache.brooklyn.core.workflow.steps.appmodel.*;
+import org.apache.brooklyn.core.workflow.steps.CustomWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.AddEntityWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.AddPolicyWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ApplyInitializerWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ClearConfigWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ClearSensorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeleteEntityWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeletePolicyWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeployApplicationWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.InvokeEffectorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ReparentEntityWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.SetConfigWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.SetEntityNameWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.SetSensorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.UpdateChildrenWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.external.HttpWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.external.ShellWorkflowStep;
import org.apache.brooklyn.core.workflow.steps.external.SshWorkflowStep;
-import org.apache.brooklyn.core.workflow.steps.flow.*;
-import org.apache.brooklyn.core.workflow.steps.variables.*;
+import org.apache.brooklyn.core.workflow.steps.flow.FailWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.ForeachWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.GotoWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.LogWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.NoOpWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.RetryWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.ReturnWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.SleepWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.SwitchWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.ClearVariableWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.variables.LoadWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.SetVariableWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.TransformVariableWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.variables.WaitWorkflowStep;
import
org.apache.brooklyn.core.workflow.store.WorkflowStatePersistenceViaSensors;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.test.Asserts;
@@ -63,14 +94,9 @@ import
org.apache.brooklyn.util.core.json.BrooklynObjectsJsonMapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
+import org.apache.commons.lang3.tuple.Pair;
import org.testng.annotations.Test;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
public class WorkflowBasicTest extends BrooklynMgmtUnitTestSupport {
@@ -172,6 +198,23 @@ public class WorkflowBasicTest extends
BrooklynMgmtUnitTestSupport {
}
}
+ static Pair<BasicApplication,Object> runStepsInNewApp(ManagementContext
mgmt, List<?> steps) {
+ WorkflowBasicTest.addWorkflowStepTypes(mgmt);
+ BasicApplication app =
mgmt.getEntityManager().createEntity(EntitySpec.create(BasicApplication.class));
+ Task<?> invocation = runSteps(app, steps);
+ return Pair.of(app, invocation.getUnchecked());
+ }
+
+ static Task<?> runSteps(BasicApplication app, List<?> steps) {
+ WorkflowEffector eff = new WorkflowEffector(ConfigBag.newInstance()
+ .configure(WorkflowEffector.EFFECTOR_NAME, "myWorkflow")
+ .configure(WorkflowEffector.STEPS, (List) steps)
+ );
+ eff.apply((EntityLocal) app);
+ Task<?> invocation =
app.invoke(app.getEntityType().getEffectorByName("myWorkflow").get(), null);
+ return invocation;
+ }
+
@Test
public void testStepResolution() throws JsonProcessingException {
loadTypes();
@@ -376,16 +419,9 @@ public class WorkflowBasicTest extends
BrooklynMgmtUnitTestSupport {
loadTypes();
BasicApplication app =
mgmt.getEntityManager().createEntity(EntitySpec.create(BasicApplication.class));
- WorkflowEffector eff = new WorkflowEffector(ConfigBag.newInstance()
- .configure(WorkflowEffector.EFFECTOR_NAME, "myWorkflow")
- .configure(WorkflowEffector.STEPS, MutableList.of(
- WorkflowTestStep.of( setup::accept ),
- "set-sensor " + (type!=null ? type+" " : "") + "x = "
+ expression
- ))
- );
- eff.apply((EntityLocal)app);
-
- Task<?> invocation =
app.invoke(app.getEntityType().getEffectorByName("myWorkflow").get(), null);
+ Task<?> invocation = runSteps(app, MutableList.of(
+ WorkflowTestStep.of(setup::accept),
+ "set-sensor " + (type != null ? type + " " : "") + "x = " +
expression));
invocation.getUnchecked();
Dumper.dumpInfo(invocation);
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowMapAndListTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowMapAndListTest.java
index c42bd46223..738545dfcc 100644
---
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowMapAndListTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowMapAndListTest.java
@@ -25,6 +25,7 @@ import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Dumper;
import org.apache.brooklyn.core.entity.EntityAsserts;
@@ -36,6 +37,7 @@ import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;
@@ -47,16 +49,9 @@ public class WorkflowMapAndListTest extends
BrooklynMgmtUnitTestSupport {
private BasicApplication app;
Object runSteps(List<?> steps) {
- WorkflowBasicTest.addWorkflowStepTypes(mgmt);
-
- BasicApplication app =
mgmt().getEntityManager().createEntity(EntitySpec.create(BasicApplication.class));
- this.app = app;
- WorkflowEffector eff = new WorkflowEffector(ConfigBag.newInstance()
- .configure(WorkflowEffector.EFFECTOR_NAME, "myWorkflow")
- .configure(WorkflowEffector.STEPS, (List) steps)
- );
- eff.apply((EntityLocal)app);
- return app.invoke(app.getEntityType().getEffectorByName
("myWorkflow").get(), null).getUnchecked();
+ Pair<BasicApplication, Object> result =
WorkflowBasicTest.runStepsInNewApp(mgmt(), steps);
+ this.app = result.getLeft();
+ return result.getRight();
}
@Test
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowOperandsTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowOperandsTest.java
index 4f61339c9e..435348928b 100644
---
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowOperandsTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowOperandsTest.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.commons.lang3.tuple.Pair;
import org.testng.annotations.Test;
import java.util.List;
@@ -34,16 +35,9 @@ public class WorkflowOperandsTest extends
BrooklynMgmtUnitTestSupport {
private BasicApplication app;
Object runSteps(List<?> steps) {
- WorkflowBasicTest.addWorkflowStepTypes(mgmt);
-
- BasicApplication app =
mgmt().getEntityManager().createEntity(EntitySpec.create(BasicApplication.class));
- this.app = app;
- WorkflowEffector eff = new WorkflowEffector(ConfigBag.newInstance()
- .configure(WorkflowEffector.EFFECTOR_NAME, "myWorkflow")
- .configure(WorkflowEffector.STEPS, (List) steps)
- );
- eff.apply((EntityLocal)app);
- return
app.invoke(app.getEntityType().getEffectorByName("myWorkflow").get(),
null).getUnchecked();
+ Pair<BasicApplication, Object> result =
WorkflowBasicTest.runStepsInNewApp(mgmt(), steps);
+ this.app = result.getLeft();
+ return result.getRight();
}
public Object evaluate(String expression, String type) {
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowParsingEdgeCasesTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowParsingEdgeCasesTest.java
new file mode 100644
index 0000000000..1b2a646eda
--- /dev/null
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowParsingEdgeCasesTest.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.brooklyn.core.workflow;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.common.reflect.TypeToken;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext;
+import org.apache.brooklyn.api.objs.BrooklynObject;
+import org.apache.brooklyn.api.policy.Policy;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Dumper;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.resolve.jackson.BeanWithTypePlanTransformer;
+import org.apache.brooklyn.core.resolve.jackson.BeanWithTypeUtils;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.BrooklynMgmtUnitTestSupport;
+import org.apache.brooklyn.core.typereg.BasicTypeImplementationPlan;
+import org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer;
+import org.apache.brooklyn.core.typereg.RegisteredTypes;
+import org.apache.brooklyn.core.workflow.steps.CustomWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.AddEntityWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.AddPolicyWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ApplyInitializerWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ClearConfigWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ClearSensorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeleteEntityWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeletePolicyWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.DeployApplicationWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.InvokeEffectorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.ReparentEntityWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.SetConfigWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.SetEntityNameWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.appmodel.SetSensorWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.appmodel.UpdateChildrenWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.external.HttpWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.external.ShellWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.external.SshWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.FailWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.ForeachWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.GotoWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.LogWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.NoOpWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.RetryWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.ReturnWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.SleepWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.flow.SwitchWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.ClearVariableWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.variables.LoadWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.SetVariableWorkflowStep;
+import
org.apache.brooklyn.core.workflow.steps.variables.TransformVariableWorkflowStep;
+import org.apache.brooklyn.core.workflow.steps.variables.WaitWorkflowStep;
+import
org.apache.brooklyn.core.workflow.store.WorkflowStatePersistenceViaSensors;
+import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.ClassLogWatcher;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.json.BrooklynObjectsJsonMapper;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.commons.lang3.tuple.Pair;
+import org.testng.annotations.Test;
+
+
+public class WorkflowParsingEdgeCasesTest extends BrooklynMgmtUnitTestSupport {
+
+ private BasicApplication app;
+
+ Object runSteps(String ...steps) {
+ Pair<BasicApplication, Object> result =
WorkflowBasicTest.runStepsInNewApp(mgmt(), Arrays.asList(steps));
+ this.app = result.getLeft();
+ return result.getRight();
+ }
+
+ @Test
+ public void testBackslashEscaping() {
+ final String BS = "\\";
+
+ String UNQUOTED_INPUT = "double unquoted " + BS + BS;
+ String QUOTED_INPUT_UNQUOTED = "quoted " + BS + BS;
+ String QUOTED_INPUT = "\"" + QUOTED_INPUT_UNQUOTED + "\"";
+ String QUOTED_INPUT_UNQUOTED_UNESCAPED = "quoted " + BS;
+
+ // entire phrase quoted will be unquoted and unescaped
+ Asserts.assertEquals(runSteps("return " + QUOTED_INPUT),
QUOTED_INPUT_UNQUOTED_UNESCAPED);
+ // but unquoted won't be
+ Asserts.assertEquals(runSteps("return " + UNQUOTED_INPUT),
UNQUOTED_INPUT);
+ // and partial words won't be even if quoted
+ Asserts.assertEquals(runSteps("return " + UNQUOTED_INPUT + " and " +
QUOTED_INPUT),
+ UNQUOTED_INPUT + " and " + QUOTED_INPUT);
+
+ // however 'let' does do unquoting on word level (according to EP
words)
+ Asserts.assertEquals(runSteps("let x = "+UNQUOTED_INPUT+" and
"+QUOTED_INPUT, "return ${x}"),
+ UNQUOTED_INPUT + " and " + QUOTED_INPUT_UNQUOTED_UNESCAPED);
+ }
+
+}