blob: ceba48f659954d80508f1afae3ae2def494d5bb5 [file] [log] [blame]
/*
* 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.commons.jexl3;
import org.apache.commons.jexl3.internal.Debugger;
import org.apache.commons.jexl3.internal.TemplateDebugger;
import org.apache.commons.jexl3.internal.TemplateScript;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
/**
* Test cases for the UnifiedEL.
*/
@SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
@RunWith(Parameterized.class)
public class JXLTTest extends JexlTestCase {
private static final Log LOGGER = LogFactory.getLog(JxltEngine.class);
private final MapContext vars = new MapContext();
private JexlEvalContext context = null;
private final JexlEngine ENGINE;
private final JxltEngine JXLT;
public JXLTTest(JexlEngine jexl) {
super("JXLTTest");
ENGINE = jexl;
JXLT = ENGINE.createJxltEngine();
}
@Parameterized.Parameters
public static List<JexlEngine> engines() {
JexlFeatures f = new JexlFeatures();
f.lexical(true).lexicalShade(true);
return Arrays.<JexlEngine>asList(new JexlEngine[] {
new JexlBuilder().silent(false)
.lexical(true).lexicalShade(true)
.cache(128).strict(true).create(),
new JexlBuilder().features(f).silent(false)
.cache(128).strict(true).create(),
new JexlBuilder().silent(false)
.cache(128).strict(true).create(),
});
}
@Before
@Override
public void setUp() throws Exception {
// ensure jul logging is only error
java.util.logging.Logger.getLogger(org.apache.commons.jexl3.JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE);
context = new JexlEvalContext(vars);
}
@After
@Override
public void tearDown() throws Exception {
debuggerCheck(ENGINE);
super.tearDown();
}
private boolean isLexicalShade() {
JexlOptions options = context.getEngineOptions();
if (options.isLexicalShade()) {
return true;
}
options = new JexlOptions().set(ENGINE);
return options.isLexicalShade();
}
private static String refactor(TemplateDebugger td, JxltEngine.Template ts) {
boolean dbg = td.debug((TemplateScript)ts);
if (dbg) {
return td.toString();
} else {
return "";
}
}
/** Extract the source from a toString-ed expression. */
private String getSource(String tostring) {
int len = tostring.length();
int sc = tostring.lastIndexOf(" /*= ");
if (sc >= 0) {
sc += " /*= ".length();
}
int ec = tostring.lastIndexOf(" */");
if (sc >= 0 && ec >= 0 && ec > sc && ec < len) {
return tostring.substring(sc, ec);
} else {
return tostring;
}
}
public static class Froboz {
int value;
public Froboz(int v) {
value = v;
}
public void setValue(int v) {
value = v;
}
public int getValue() {
return value;
}
public int plus10() {
int i = value;
value += 10;
return i;
}
}
@Test
public void testStatement() throws Exception {
Froboz froboz = new Froboz(32);
context.set("froboz", froboz);
JxltEngine.Expression check = JXLT.createExpression("${ froboz.plus10() }");
Object o = check.evaluate(context);
Assert.assertEquals("Result is not 32", new Integer(32), o);
Assert.assertEquals("Result is not 42", 42, froboz.getValue());
Set<List<String>> evars = check.getVariables();
Assert.assertEquals(1, evars.size());
}
@Test
public void testAssign() throws Exception {
Froboz froboz = new Froboz(32);
context.set("froboz", froboz);
JxltEngine.Expression assign = JXLT.createExpression("${froboz.value = 42}");
JxltEngine.Expression check = JXLT.createExpression("${froboz.value}");
Object o = assign.evaluate(context);
Assert.assertEquals("Result is not 10", new Integer(42), o);
o = check.evaluate(context);
Assert.assertEquals("Result is not 10", new Integer(42), o);
}
@Test
public void testComposite() throws Exception {
String source = "Dear ${p} ${name};";
JxltEngine.Expression expr = JXLT.createExpression(source);
context.set("p", "Mr");
context.set("name", "Doe");
Assert.assertTrue("expression should be immediate", expr.isImmediate());
Object o = expr.evaluate(context);
Assert.assertEquals("Dear Mr Doe;", o);
context.set("p", "Ms");
context.set("name", "Jones");
o = expr.evaluate(context);
Assert.assertEquals("Dear Ms Jones;", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
boolean contains(Set<List<String>> set, List<String> list) {
for (List<String> sl : set) {
if (sl.equals(list)) {
return true;
}
}
return false;
}
@Test
public void testPrepareEvaluate() throws Exception {
final String source = "Dear #{p} ${name};";
JxltEngine.Expression expr = JXLT.createExpression("Dear #{p} ${name};");
Assert.assertTrue("expression should be deferred", expr.isDeferred());
Set<List<String>> evars = expr.getVariables();
Assert.assertEquals(1, evars.size());
Assert.assertTrue(contains(evars, Arrays.asList("name")));
context.set("name", "Doe");
JxltEngine.Expression phase1 = expr.prepare(context);
String as = phase1.asString();
Assert.assertEquals("Dear ${p} Doe;", as);
Set<List<String>> evars1 = phase1.getVariables();
Assert.assertEquals(1, evars1.size());
Assert.assertTrue(contains(evars1, Arrays.asList("p")));
vars.clear();
context.set("p", "Mr");
context.set("name", "Should not be used in 2nd phase");
Object o = phase1.evaluate(context);
Assert.assertEquals("Dear Mr Doe;", o);
String p1 = getSource(phase1.toString());
Assert.assertEquals(source, getSource(phase1.toString()));
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testNested() throws Exception {
final String source = "#{${hi}+'.world'}";
JxltEngine.Expression expr = JXLT.createExpression(source);
Set<List<String>> evars = expr.getVariables();
Assert.assertEquals(1, evars.size());
Assert.assertTrue(contains(evars, Arrays.asList("hi")));
context.set("hi", "greeting");
context.set("greeting.world", "Hello World!");
Assert.assertTrue("expression should be deferred", expr.isDeferred());
Object o = expr.evaluate(context);
Assert.assertEquals("Hello World!", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testNestedTemplate() throws Exception {
final String source = "#{${hi}+'.world'}";
JxltEngine.Template expr = JXLT.createTemplate(source, "hi");
context.set("greeting.world", "Hello World!");
StringWriter strw = new StringWriter();
expr.evaluate(context, strw, "greeting");
String o = strw.toString();
Assert.assertEquals("Hello World!", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testImmediate() throws Exception {
JexlContext none = null;
final String source = "${'Hello ' + 'World!'}";
JxltEngine.Expression expr = JXLT.createExpression(source);
JxltEngine.Expression prepared = expr.prepare(none);
Assert.assertEquals("prepare should return same expression", "Hello World!", prepared.asString());
Object o = expr.evaluate(none);
Assert.assertTrue("expression should be immediate", expr.isImmediate());
Assert.assertEquals("Hello World!", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testConstant() throws Exception {
JexlContext none = null;
final String source = "Hello World!";
JxltEngine.Expression expr = JXLT.createExpression(source);
Assert.assertTrue("prepare should return same expression", expr.prepare(none) == expr);
Object o = expr.evaluate(none);
Assert.assertTrue("expression should be immediate", expr.isImmediate());
Assert.assertEquals("Hello World!", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testConstant2() throws Exception {
JexlContext none = null;
final String source = "${size({'map':123,'map2':456})}";
JxltEngine.Expression expr = JXLT.createExpression(source);
//Assert.assertTrue("prepare should return same expression", expr.prepare(none) == expr);
Object o = expr.evaluate(none);
Assert.assertTrue("expression should be immediate", expr.isImmediate());
Assert.assertEquals(2, o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testConstant3() throws Exception {
JexlContext none = null;
final String source = "#{size({'map':123,'map2':456})}";
JxltEngine.Expression expr = JXLT.createExpression(source);
//Assert.assertTrue("prepare should return same expression", expr.prepare(none) == expr);
Object o = expr.evaluate(none);
Assert.assertTrue("expression should be deferred", expr.isDeferred());
Assert.assertEquals(2, o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testConstant4() throws Exception {
JexlContext none = null;
final String source = "#{ ${size({'1':2,'2': 3})} }";
JxltEngine.Expression expr = JXLT.createExpression(source);
//Assert.assertTrue("prepare should return same expression", expr.prepare(none) == expr);
Object o = expr.evaluate(none);
Assert.assertTrue("expression should be deferred", expr.isDeferred());
Assert.assertEquals(2, o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testDeferred() throws Exception {
JexlContext none = null;
final String source = "#{'world'}";
JxltEngine.Expression expr = JXLT.createExpression(source);
Assert.assertTrue("expression should be deferred", expr.isDeferred());
String as = expr.prepare(none).asString();
Assert.assertEquals("prepare should return immediate version", "${'world'}", as);
Object o = expr.evaluate(none);
Assert.assertEquals("world", o);
Assert.assertEquals(source, getSource(expr.toString()));
}
@Test
public void testEscape() throws Exception {
JexlContext none = null;
JxltEngine.Expression expr;
Object o;
// $ and # are escapable in TemplateEngine
expr = JXLT.createExpression("\\#{'world'}");
o = expr.evaluate(none);
Assert.assertEquals("#{'world'}", o);
expr = JXLT.createExpression("\\${'world'}");
o = expr.evaluate(none);
Assert.assertEquals("${'world'}", o);
}
@Test
public void testEscapeString() throws Exception {
JxltEngine.Expression expr = JXLT.createExpression("\\\"${'world\\'s finest'}\\\"");
JexlContext none = null;
Object o = expr.evaluate(none);
Assert.assertEquals("\"world's finest\"", o);
}
@Test
public void testNonEscapeString() throws Exception {
JxltEngine.Expression expr = JXLT.createExpression("c:\\some\\windows\\path");
JexlContext none = null;
Object o = expr.evaluate(none);
Assert.assertEquals("c:\\some\\windows\\path", o);
}
@Test
public void testMalformed() throws Exception {
try {
JxltEngine.Expression expr = JXLT.createExpression("${'world'");
JexlContext none = null;
expr.evaluate(none);
Assert.fail("should be malformed");
} catch (JxltEngine.Exception xjexl) {
// expected
String xmsg = xjexl.getMessage();
LOGGER.warn(xmsg);
}
}
@Test
public void testMalformedNested() throws Exception {
try {
JxltEngine.Expression expr = JXLT.createExpression("#{${hi} world}");
JexlContext none = null;
expr.evaluate(none);
Assert.fail("should be malformed");
} catch (JxltEngine.Exception xjexl) {
// expected
String xmsg = xjexl.getMessage();
LOGGER.warn(xmsg);
}
}
@Test
public void testMalformedNested2() throws Exception {
try {
JxltEngine.Expression expr = JXLT.createExpression("#{${hi} world}");
JexlContext ctxt = new MapContext();
ctxt.set("hi", "hello");
expr.evaluate(ctxt);
Assert.fail("should be malformed");
} catch (JxltEngine.Exception xjexl) {
// expected
String xmsg = xjexl.getMessage();
LOGGER.warn(xmsg);
}
}
@Test
public void testBadContextNested() throws Exception {
try {
JxltEngine.Expression expr = JXLT.createExpression("#{${hi}+'.world'}");
JexlContext none = null;
expr.evaluate(none);
Assert.fail("should be malformed");
} catch (JxltEngine.Exception xjexl) {
// expected
String xmsg = xjexl.getMessage();
LOGGER.warn(xmsg);
}
}
@Test
public void testCharAtBug() throws Exception {
context.set("foo", "abcdef");
JexlOptions options = context.getEngineOptions();
JxltEngine.Expression expr = JXLT.createExpression("${foo.substring(2,4)/*comment*/}");
Object o = expr.evaluate(context);
Assert.assertEquals("cd", o);
context.set("bar", "foo");
try {
options.setSilent(true);
expr = JXLT.createExpression("#{${bar}+'.charAt(-2)'}");
expr = expr.prepare(context);
o = expr.evaluate(context);
Assert.assertEquals(null, o);
} finally {
options.setSilent(false);
}
}
@Test
public void testTemplate0() throws Exception {
String source = " $$ if(x) {\nx is ${x}\n $$ } else {\n${'no x'}\n$$ }\n";
StringWriter strw;
String output;
JxltEngine.Template t = JXLT.createTemplate(source);
context.set("x", 42);
strw = new StringWriter();
t.evaluate(context, strw);
output = strw.toString();
Assert.assertEquals("x is 42\n", output);
strw = new StringWriter();
context.set("x", "");
t.evaluate(context, strw);
output = strw.toString();
Assert.assertEquals("no x\n", output);
String dstr = t.toString();
Assert.assertNotNull(dstr);
}
@Test
public void testTemplate10() throws Exception {
String source = "$$(x)->{ if(x) {\nx is ${x}\n$$ } else {\n${'no x'}\n$$ } }\n";
StringWriter strw;
String output;
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(source), (String[]) null);
String dstr = t.asString();
Assert.assertNotNull(dstr);
String[] ps = t.getParameters();
Assert.assertTrue(Arrays.asList(ps).contains("x"));
strw = new StringWriter();
t.evaluate(context, strw, 42);
output = strw.toString();
Assert.assertEquals("x is 42\n", output);
}
@Test
public void testTemplate1() throws Exception {
String source = "$$ if(x) {\nx is ${x}\n$$ } else {\n${'no x'}\n$$ }\n";
StringWriter strw;
String output;
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(source), "x");
String dstr = t.asString();
Assert.assertNotNull(dstr);
strw = new StringWriter();
t.evaluate(context, strw, 42);
output = strw.toString();
Assert.assertEquals("x is 42\n", output);
strw = new StringWriter();
t.evaluate(context, strw, "");
output = strw.toString();
Assert.assertEquals("no x\n", output);
}
@Test
public void testTemplate2() throws Exception {
String source = "The answer: ${x}";
StringWriter strw;
String output;
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(source), "x");
String dstr = t.asString();
Assert.assertNotNull(dstr);
strw = new StringWriter();
t.evaluate(context, strw, 42);
output = strw.toString();
Assert.assertEquals("The answer: 42", output);
}
@Test
public void testPrepareTemplate() throws Exception {
String source
= "$$ for(var x : list) {\n"
+ "${l10n}=#{x}\n"
+ "$$ }\n";
int[] args = {42};
JxltEngine.Template tl10n = JXLT.createTemplate(source, "list");
String dstr = tl10n.asString();
Assert.assertNotNull(dstr);
Set<List<String>> vars = tl10n.getVariables();
Assert.assertFalse(vars.isEmpty());
context.set("l10n", "valeur");
JxltEngine.Template tpFR = tl10n.prepare(context);
context.set("l10n", "value");
JxltEngine.Template tpEN = tl10n.prepare(context);
context.set("l10n", null);
StringWriter strw;
strw = new StringWriter();
tpFR.evaluate(context, strw, args);
String outFR = strw.toString();
Assert.assertEquals("valeur=42\n", outFR);
context.set("l10n", null);
strw = new StringWriter();
tpEN.evaluate(context, strw, args);
String outEN = strw.toString();
Assert.assertEquals("value=42\n", outEN);
}
@Test
public void test42() throws Exception {
String test42
= "$$ for(var x : list) {\n"
+ "$$ if (x == 42) {\n"
+ "Life, the universe, and everything\n"
+ "$$ } else if (x > 42) {\n"
+ "The value ${x} is over fourty-two\n"
+ "$$ } else {\n"
+ "The value ${x} is under fourty-two\n"
+ "$$ }\n"
+ "$$ }\n";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(test42), "list");
StringWriter strw = new StringWriter();
int[] list = {1, 3, 5, 42, 169};
t.evaluate(context, strw, list);
String output = strw.toString();
String out42
= "The value 1 is under fourty-two\n"
+ "The value 3 is under fourty-two\n"
+ "The value 5 is under fourty-two\n"
+ "Life, the universe, and everything\n"
+ "The value 169 is over fourty-two\n";
Assert.assertEquals(out42, output);
String dstr = t.asString();
Assert.assertNotNull(dstr);
TemplateDebugger td = new TemplateDebugger();
String refactored = refactor(td, (TemplateScript) t);
Assert.assertNotNull(refactored);
Assert.assertEquals(test42, refactored);
}
@Test
public void testInheritedDebugger() throws Exception {
String src = "if ($A) { $B + 1; } else { $C - 2 }";
JexlEngine jexl = JXLT.getEngine();
JexlScript script = jexl.createScript(src);
Debugger sd = new Debugger();
String rscript = sd.debug(script)? sd.toString() : null;
Assert.assertNotNull(rscript);
TemplateDebugger td = new TemplateDebugger();
String refactored = td.debug(script)? td.toString() : null;
Assert.assertNotNull(refactored);
Assert.assertEquals(refactored, rscript);
}
public static class FrobozWriter extends PrintWriter {
public FrobozWriter(Writer w) {
super(w);
}
public void print(Froboz froboz) {
super.print("froboz{");
super.print(froboz.value);
super.print("}");
}
@Override
public String toString() {
return out.toString();
}
}
@Test
public void testWriter() throws Exception {
Froboz froboz = new Froboz(42);
Writer writer = new FrobozWriter(new StringWriter());
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader("$$$jexl.print(froboz)"), "froboz");
t.evaluate(context, writer, froboz);
Assert.assertEquals("froboz{42}", writer.toString());
}
@Test
public void testReport() throws Exception {
String rpt
= "<report>\n"
+ "\n"
+ "\n$$ var a = 1;"
+ "\n$$ var x = 2;"
+ "\n"
+ "\n$$ var y = 9;"
+ "\n"
+ "\n ${x + y}"
+ "\n</report>\n";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(context, strw);
String output = strw.toString();
String ctl = "<report>\n\n\n\n\n 11\n</report>\n";
Assert.assertEquals(ctl, output);
TemplateDebugger td = new TemplateDebugger();
String refactored = refactor(td, (TemplateScript) t);
Assert.assertNotNull(refactored);
Assert.assertEquals(rpt, refactored);
}
@Test
public void testReport1() throws Exception {
String rpt
= "<report>\n"
+ "this is ${x}\n"
+ "${x + 1}\n"
+ "${x + 2}\n"
+ "${x + 3}\n"
+ "</report>\n";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
context.set("x", 42);
t.evaluate(context, strw, 42);
String output = strw.toString();
int count = 0;
for (int i = 0; i < output.length(); ++i) {
char c = output.charAt(i);
if ('\n' == c) {
count += 1;
}
}
Assert.assertEquals(6, count);
Assert.assertTrue(output.indexOf("42") > 0);
Assert.assertTrue(output.indexOf("43") > 0);
Assert.assertTrue(output.indexOf("44") > 0);
Assert.assertTrue(output.indexOf("45") > 0);
}
@Test
public void testReport2() throws Exception {
String rpt
= "<report>\n"
+ "this is ${x}\n"
+ "${x + 1}\n"
+ "${x + 2}\n"
+ "${x + 3}\n"
+ "</report>\n";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt), "x");
StringWriter strw = new StringWriter();
t.evaluate(context, strw, 42);
String output = strw.toString();
int count = 0;
for (int i = 0; i < output.length(); ++i) {
char c = output.charAt(i);
if ('\n' == c) {
count += 1;
}
}
Assert.assertEquals(6, count);
Assert.assertTrue(output.indexOf("42") > 0);
Assert.assertTrue(output.indexOf("43") > 0);
Assert.assertTrue(output.indexOf("44") > 0);
Assert.assertTrue(output.indexOf("45") > 0);
TemplateDebugger td = new TemplateDebugger();
String xxx = refactor(td, (TemplateScript) t);
Assert.assertNotNull(xxx);
Assert.assertEquals(rpt, xxx);
}
@Test
public void testOneLiner() throws Exception {
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader("fourty-two"));
StringWriter strw = new StringWriter();
t.evaluate(context, strw);
String output = strw.toString();
Assert.assertEquals("fourty-two", output);
}
@Test
public void testOneLinerVar() throws Exception {
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader("fourty-${x}"));
StringWriter strw = new StringWriter();
context.set("x", "two");
t.evaluate(context, strw);
String output = strw.toString();
Assert.assertEquals("fourty-two", output);
}
@Test
public void testInterpolation() throws Exception {
String expr = "`Hello \n${user}`";
JexlScript script = ENGINE.createScript(expr);
context.set("user", "Dimitri");
Object value = script.execute(context);
Assert.assertEquals(expr, "Hello \nDimitri", value);
context.set("user", "Rahul");
value = script.execute(context);
Assert.assertEquals(expr, "Hello \nRahul", value);
}
@Test
public void testInterpolationGlobal() throws Exception {
if (isLexicalShade()) {
context.set("user", null);
}
String expr = "user='Dimitri'; `Hello \n${user}`";
Object value = ENGINE.createScript(expr).execute(context);
Assert.assertEquals(expr, "Hello \nDimitri", value);
}
@Test
public void testInterpolationLocal() throws Exception {
String expr = "var user='Henrib'; `Hello \n${user}`";
Object value = ENGINE.createScript(expr).execute(context);
Assert.assertEquals(expr, "Hello \nHenrib", value);
}
@Test
public void testInterpolationLvsG() throws Exception {
if (isLexicalShade()) {
context.set("user", null);
}
String expr = "user='Dimitri'; var user='Henrib'; `H\\\"ello \n${user}`";
Object value = ENGINE.createScript(expr).execute(context);
Assert.assertEquals(expr, "H\"ello \nHenrib", value);
}
@Test
public void testInterpolationLvsG2() throws Exception {
if (isLexicalShade()) {
context.set("user", null);
}
String expr = "user='Dimitri'; var user='Henrib'; `H\\`ello \n${user}`";
Object value = ENGINE.createScript(expr).execute(context);
Assert.assertEquals(expr, "H`ello \nHenrib", value);
}
@Test
public void testInterpolationParameter() throws Exception {
String expr = "(user)->{`Hello \n${user}`}";
Object value = ENGINE.createScript(expr).execute(context, "Henrib");
Assert.assertEquals(expr, "Hello \nHenrib", value);
value = ENGINE.createScript(expr).execute(context, "Dimitri");
Assert.assertEquals(expr, "Hello \nDimitri", value);
}
@Test
public void testImmediateTemplate() throws Exception {
context.set("tables", new String[]{"table1", "table2"});
context.set("w" ,"x=1");
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(
"select * from \n"+
"$$var comma = false; \n"+
"$$for(var c : tables) { \n"+
"$$ if (comma) $jexl.write(','); else comma = true;\n"+
"${c}"+
"\n$$}\n"+
"where ${w}\n"
));
StringWriter strw = new StringWriter();
//vars.clear();
t.evaluate(context, strw);
String output = strw.toString();
Assert.assertTrue(output.contains("table1") && output.contains("table2"));
}
public static class Executor311 {
private final String name;
public Executor311(String name) {
this.name = name;
}
// Injects name as first arg of any called script
public Object execute(JexlScript script, Object ...args) {
Object[] actuals;
if (args != null && args.length > 0) {
actuals = new Object[args.length + 1] ;
System.arraycopy(args, 0, actuals, 1, args.length);
actuals[0] = name;
} else {
actuals = new Object[]{name};
}
return script.execute(JexlEngine.getThreadContext(), actuals);
}
}
public static class Context311 extends MapContext
implements JexlContext.OptionsHandle, JexlContext.ThreadLocal {
private JexlOptions options = null;
public void setOptions(JexlOptions o) {
options = o;
}
public Executor311 exec(String name) {
return new Executor311(name);
}
@Override
public JexlOptions getEngineOptions() {
return options;
}
JexlOptions newOptions() {
options = new JexlOptions();
return options;
}
}
@Test
public void test311a() throws Exception {
JexlContext ctx = null;
String rpt
= "$$((a)->{\n"
+ "<p>Universe ${a}</p>\n"
+ "$$})(42)";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(ctx, strw);
String output = strw.toString();
Assert.assertEquals("<p>Universe 42</p>\n", output);
}
@Test
public void test311b() throws Exception {
JexlContext ctx311 = new Context311();
String rpt
= "$$ exec('42').execute(()->{\n"
+ "<p>Universe 42</p>\n"
+ "$$})";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(ctx311, strw, 42);
String output = strw.toString();
Assert.assertEquals("<p>Universe 42</p>\n", output);
}
@Test
public void test311c() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt
= "$$ exec('42').execute((a)->{"
+ "\n<p>Universe ${a}</p>"
+ "\n$$})";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(ctx311, strw, 42);
String output = strw.toString();
Assert.assertEquals("<p>Universe 42</p>\n", output);
}
@Test
public void test311d() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt
= "$$ exec('4').execute((a, b)->{"
+ "\n<p>Universe ${a}${b}</p>"
+ "\n$$}, '2')";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(ctx311, strw, 42);
String output = strw.toString();
Assert.assertEquals("<p>Universe 42</p>\n", output);
}
@Test
public void test311e() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt
= "exec('4').execute((a, b)->{"
+ " '<p>Universe ' + a + b + '</p>'"
+ "}, '2')";
JexlScript script = JEXL.createScript(rpt);
String output = script.execute(ctx311, 42).toString();
Assert.assertEquals("<p>Universe 42</p>", output);
}
@Test
public void test311f() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt
= "exec('4').execute((a, b)->{"
+ " `<p>Universe ${a}${b}</p>`"
+ "}, '2')";
JexlScript script = JEXL.createScript(rpt);
String output = script.execute(ctx311, 42).toString();
Assert.assertEquals("<p>Universe 42</p>", output);
}
@Test
public void test311g() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt
= "(a, b)->{"
+ " `<p>Universe ${a}${b}</p>`"
+ "}";
JexlScript script = JEXL.createScript(rpt);
String output = script.execute(ctx311, "4", "2").toString();
Assert.assertEquals("<p>Universe 42</p>", output);
}
@Test
public void test311h() throws Exception {
Context311 ctx311 = new Context311();
ctx311.newOptions().setLexical(true);
String rpt= " `<p>Universe ${a}${b}</p>`";
JexlScript script = JEXL.createScript(rpt, "a", "b");
String output = script.execute(ctx311, "4", "2").toString();
Assert.assertEquals("<p>Universe 42</p>", output);
}
@Test
public void test311i() throws Exception {
JexlContext ctx311 = new Context311();
String rpt
= "$$var u = 'Universe'; exec('4').execute((a, b)->{"
+ "\n<p>${u} ${a}${b}</p>"
+ "\n$$}, '2')";
JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(rpt));
StringWriter strw = new StringWriter();
t.evaluate(ctx311, strw, 42);
String output = strw.toString();
Assert.assertEquals("<p>Universe 42</p>\n", output);
}
@Test
public void test315() throws Exception {
String s315;
StringWriter strw;
JxltEngine.Template t315;
String output;
s315 = "<report/>$";
t315 = JXLT.createTemplate("$$", new StringReader(s315));
strw = new StringWriter();
t315.evaluate(context, strw);
output = strw.toString();
Assert.assertEquals(s315, output);
s315 = "<foo/>#";
t315 = JXLT.createTemplate("$$", new StringReader(s315));
strw = new StringWriter();
t315.evaluate(context, strw);
output = strw.toString();
Assert.assertEquals(s315, output);
s315 = "<bar/>\\";
t315 = JXLT.createTemplate("$$", new StringReader(s315));
strw = new StringWriter();
t315.evaluate(context, strw);
output = strw.toString();
Assert.assertEquals(s315, output);
}
// define mode pro50
static final JexlOptions MODE_PRO50 = new JexlOptions();
static {
MODE_PRO50.setFlags( "+strict +cancellable +lexical +lexicalShade -safe".split(" "));
}
public static class PragmaticContext extends MapContext implements JexlContext.PragmaProcessor, JexlContext.OptionsHandle {
private final JexlOptions options;
public PragmaticContext(JexlOptions o) {
this.options = o;
}
@Override
public void processPragma(String key, Object value) {
if ("script.mode".equals(key) && "pro50".equals(value)) {
options.set(MODE_PRO50);
}
}
@Override
public Object get(String name) {
if ("$options".equals(name)) {
return options;
}
return super.get(name);
}
@Override
public JexlOptions getEngineOptions() {
return options;
}
}
@Test
public void testLexicalTemplate() throws Exception {
JexlOptions opts = new JexlOptions();
JexlContext ctxt = new PragmaticContext(opts);
opts.setCancellable(false);
opts.setStrict(false);
opts.setSafe(true);
opts.setLexical(false);
opts.setLexicalShade(false);
String src0 = "${$options.strict?'+':'-'}strict"
+ " ${$options.cancellable?'+':'-'}cancellable"
+ " ${$options.lexical?'+':'-'}lexical"
+ " ${$options.lexicalShade?'+':'-'}lexicalShade"
+ " ${$options.safe?'+':'-'}safe";
JxltEngine.Template tmplt0 = JXLT.createTemplate("$$", new StringReader(src0));
Writer strw0 = new StringWriter();
tmplt0.evaluate(ctxt, strw0);
String output0 = strw0.toString();
Assert.assertEquals( "-strict -cancellable -lexical -lexicalShade +safe", output0);
String src = "$$ #pragma script.mode pro50\n" + src0;
JxltEngine.Template tmplt = JXLT.createTemplate("$$", new StringReader(src));
Writer strw = new StringWriter();
tmplt.evaluate(ctxt, strw);
String output = strw.toString();
Assert.assertEquals("+strict +cancellable +lexical +lexicalShade -safe", output);
}
@Test
public void testTemplatePragmaPro50() throws Exception {
JexlOptions opts = new JexlOptions();
opts.setCancellable(false);
opts.setStrict(false);
opts.setSafe(true);
opts.setLexical(false);
opts.setLexicalShade(false);
opts.setSharedInstance(true);
JexlContext ctxt = new PragmaticContext(opts);
String src = "$$ #pragma script.mode pro50\n"
+ "$$ var tab = null;\n"
+ "$$ tab.dummy();";
JxltEngine.Template tmplt = JXLT.createTemplate("$$", new StringReader(src));
Writer strw = new StringWriter();
try {
tmplt.evaluate(ctxt, strw);
Assert.fail("tab var is null");
} catch (JexlException.Variable xvar) {
Assert.assertTrue("tab".equals(xvar.getVariable()));
Assert.assertFalse(xvar.isUndefined());
}
}
}