You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2020/02/11 16:30:24 UTC
[commons-jexl] branch master updated: JEXL-302: added a test for
JexBuilder.captureAll() and JexlScript.getVariables().
This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new 09db242 JEXL-302: added a test for JexBuilder.captureAll() and JexlScript.getVariables().
09db242 is described below
commit 09db242b8cffbf63ad4a59d4e62f3ac358d4be24
Author: henrib <he...@apache.org>
AuthorDate: Tue Feb 11 17:29:28 2020 +0100
JEXL-302: added a test for JexBuilder.captureAll() and JexlScript.getVariables().
---
.../java/org/apache/commons/jexl3/VarTest.java | 180 +++++++++++++++++++++
1 file changed, 180 insertions(+)
diff --git a/src/test/java/org/apache/commons/jexl3/VarTest.java b/src/test/java/org/apache/commons/jexl3/VarTest.java
index 7586e77..04d4859 100644
--- a/src/test/java/org/apache/commons/jexl3/VarTest.java
+++ b/src/test/java/org/apache/commons/jexl3/VarTest.java
@@ -16,12 +16,19 @@
*/
package org.apache.commons.jexl3;
+import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Collections;
+import java.util.Date;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.TimeZone;
+import org.apache.commons.jexl3.parser.JexlParser;
import org.junit.Assert;
import org.junit.Test;
import org.apache.commons.logging.Log;
@@ -33,6 +40,10 @@ import org.apache.commons.logging.LogFactory;
@SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
public class VarTest extends JexlTestCase {
static final Log LOGGER = LogFactory.getLog(VarTest.class.getName());
+ public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
+ static {
+ SDF.setTimeZone(TimeZone.getTimeZone("UTC"));
+ }
public VarTest() {
super("VarTest");
@@ -366,6 +377,163 @@ public class VarTest extends JexlTestCase {
Assert.assertEquals("z", locals[0]);
}
+ /**
+ * Dates that can return multiple properties in one call.
+ */
+ public static class VarDate {
+ private final Calendar cal;
+
+ public VarDate(String date) throws Exception {
+ this(SDF.parse(date));
+ }
+ public VarDate(Date date) {
+ cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ cal.setTime(date);
+ cal.setLenient(true);
+ }
+
+ /**
+ * Gets a date property
+ * @param property yyyy or MM or dd
+ * @return the string representation of year, month or day
+ */
+ public String get(String property) {
+ if ("yyyy".equals(property)) {
+ return Integer.toString(cal.get(Calendar.YEAR));
+ }
+ if ("MM".equals(property)) {
+ return Integer.toString(cal.get(Calendar.MONTH) + 1);
+ }
+
+ if ("dd".equals(property)) {
+ return Integer.toString(cal.get(Calendar.DAY_OF_MONTH));
+ }
+ return null;
+ }
+
+ /**
+ * Gets a list of properties.
+ * @param keys the property names
+ * @return the property values
+ */
+ public List<String> get(String[] keys) {
+ return get(Arrays.asList(keys));
+ }
+
+ /**
+ * Gets a list of properties.
+ * @param keys the property names
+ * @return the property values
+ */
+ public List<String> get(List<String> keys) {
+ List<String> values = new ArrayList<String>();
+ for(String key : keys) {
+ String value = get(key);
+ if (value != null) {
+ values.add(value);
+ }
+ }
+ return values;
+ }
+
+ /**
+ * Gets a map of properties.
+ * <p>Uses each map key as a property name and each value as an alias
+ * used to key the resulting property value.
+ * @param map a map of property name to alias
+ * @return the alia map
+ */
+ public Map<String,Object> get(Map<String,String> map) {
+ Map<String,Object> values = new LinkedHashMap<String,Object>();
+ for(Map.Entry<String,String> entry : map.entrySet()) {
+ String value = get(entry.getKey());
+ if (value != null) {
+ values.put(entry.getValue(), value);
+ }
+ }
+ return values;
+ }
+ }
+
+ /**
+ * Getting properties from an array, set or map.
+ * @param str the stringified source
+ * @return the properties array
+ */
+ private static String[] readIdentifiers(String str) {
+ List<String> ids = new ArrayList<String>();
+ StringBuilder strb = null;
+ String id = null;
+ char kind = 0; // array, set or map kind using first char
+ for (int i = 0; i < str.length(); ++i) {
+ char c = str.charAt(i);
+ // strb != null when array,set or map deteced
+ if (strb == null) {
+ if (c == '{' || c == '(' || c == '[') {
+ strb = new StringBuilder();
+ kind = c;
+ }
+ continue;
+ }
+ // identifier pending to be added (only add map keys)
+ if (id != null && c == ']' || c == ')'
+ || (kind != '{' && c == ',') // array or set
+ || (kind == '{' && c == ':')) // map key
+ {
+ ids.add(id);
+ id = null;
+ }
+ else if (c == '\'' || c == '"') {
+ strb.append(c);
+ int l = JexlParser.readString(strb, str, i + 1, c);
+ if (l > 0) {
+ id = strb.substring(1, strb.length() - 1);
+ strb.delete(0, l + 1);
+ i = l;
+ }
+ }
+ // discard all chars not in identifier
+ }
+ return ids.toArray(new String[ids.size()]);
+ }
+
+ @Test
+ public void testReferenceLiteral() throws Exception {
+ JexlScript script;
+ List<String> result;
+ Set<List<String>> vars;
+ // in collectAll mode, the collector grabs all syntactic variations of
+ // constant variable references including map/arry/set literals
+ JexlContext ctxt = new MapContext();
+ //d.yyyy = 1969; d.MM = 7; d.dd = 20
+ ctxt.set("moon.landing", new VarDate("1969-07-20"));
+
+ script = JEXL.createScript("moon.landing[['yyyy', 'MM', 'dd']]");
+ result = (List<String>) script.execute(ctxt);
+ Assert.assertEquals(Arrays.asList("1969", "7", "20"), result);
+
+ vars = script.getVariables();
+ Assert.assertEquals(1, vars.size());
+ List<String> var = vars.iterator().next();
+ Assert.assertEquals("moon", var.get(0));
+ Assert.assertEquals("landing", var.get(1));
+ Assert.assertArrayEquals(new String[]{"yyyy", "MM", "dd"}, readIdentifiers(var.get(2)));
+
+ script = JEXL.createScript("moon.landing[ { 'yyyy' : 'year', 'MM' : 'month', 'dd' : 'day' } ]");
+ Map<String, String> mapr = (Map<String, String>) script.execute(ctxt);
+ Assert.assertEquals(3, mapr.size());
+ Assert.assertEquals("1969", mapr.get("year"));
+ Assert.assertEquals("7", mapr.get("month"));
+ Assert.assertEquals("20", mapr.get("day"));
+
+ vars = script.getVariables();
+ Assert.assertEquals(1, vars.size());
+ var = vars.iterator().next();
+ Assert.assertEquals("moon", var.get(0));
+ Assert.assertEquals("landing", var.get(1));
+ Assert.assertArrayEquals(new String[]{"yyyy", "MM", "dd"}, readIdentifiers(var.get(2)));
+ }
+
@Test
public void testLiteral() throws Exception {
JexlScript e = JEXL.createScript("x.y[['z', 't']]");
@@ -377,10 +545,22 @@ public class VarTest extends JexlTestCase {
vars = e.getVariables();
Assert.assertEquals(1, vars.size());
Assert.assertTrue(eq(mkref(new String[][]{{"x", "y", "{ 'z' : 't' }"}}), vars));
+
e = JEXL.createScript("x.y.'{ \\'z\\' : \\'t\\' }'");
vars = e.getVariables();
Assert.assertEquals(1, vars.size());
Assert.assertTrue(eq(mkref(new String[][]{{"x", "y", "{ 'z' : 't' }"}}), vars));
+
+ JexlEngine jexld = new JexlBuilder().collectAll(false).create();
+ e = jexld.createScript("x.y[{'z': 't'}]");
+ vars = e.getVariables();
+ Assert.assertEquals(1, vars.size());
+ Assert.assertTrue(eq(mkref(new String[][]{{"x", "y"}}), vars));
+
+ e = jexld.createScript("x.y[['z', 't']]");
+ vars = e.getVariables();
+ Assert.assertEquals(1, vars.size());
+ Assert.assertTrue(eq(mkref(new String[][]{{"x", "y"}}), vars));
}
@Test