1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.jexl3.scripting;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertNull;
23 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assertions.assertTrue;
25
26 import java.io.Reader;
27 import java.io.StringReader;
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.script.CompiledScript;
33 import javax.script.ScriptContext;
34 import javax.script.ScriptEngine;
35 import javax.script.ScriptEngineManager;
36 import javax.script.ScriptException;
37
38 import org.apache.commons.jexl3.JexlBuilder;
39 import org.apache.commons.jexl3.JexlException;
40 import org.apache.commons.jexl3.introspection.JexlPermissions;
41 import org.junit.jupiter.api.AfterEach;
42 import org.junit.jupiter.api.Test;
43
44 public class JexlScriptEngineTest {
45 public static class Errors {
46 public int illegal() {
47 throw new IllegalArgumentException("jexl");
48 }
49 public int npe() {
50 throw new NullPointerException("jexl");
51 }
52 }
53 private static final List<String> NAMES = Arrays.asList("JEXL", "Jexl", "jexl",
54 "JEXL2", "Jexl2", "jexl2",
55 "JEXL3", "Jexl3", "jexl3");
56 private static final List<String> EXTENSIONS = Arrays.asList("jexl", "jexl2", "jexl3");
57
58 private static final List<String> MIMES = Arrays.asList("application/x-jexl",
59 "application/x-jexl2",
60 "application/x-jexl3");
61
62 @AfterEach
63 public void tearDown() {
64 JexlBuilder.setDefaultPermissions(null);
65 JexlScriptEngine.setInstance(null);
66 JexlScriptEngine.setPermissions(null);
67 }
68
69 @Test
70 public void testCompile() throws Exception {
71 final ScriptEngineManager manager = new ScriptEngineManager();
72 final JexlScriptEngine engine = (JexlScriptEngine) manager.getEngineByName("JEXL");
73 final ScriptContext ctxt = engine.getContext();
74 final String str = null;
75 final Reader reader = null;
76 assertThrows(NullPointerException.class, () -> engine.compile(str));
77 assertThrows(NullPointerException.class, () -> engine.compile(reader));
78 final CompiledScript script0 = engine.compile(new StringReader("3 + 4"));
79 assertEquals(engine, script0.getEngine());
80 Object result = script0.eval();
81 assertEquals(7, result);
82 result = script0.eval();
83 assertEquals(7, result);
84 result = engine.eval(new StringReader("38 + 4"));
85 assertEquals(42, result);
86 result = engine.eval("38 + 4");
87 assertEquals(42, result);
88
89 final CompiledScript script1 = engine.compile("3 + 4");
90 assertEquals(engine, script1.getEngine());
91 Object result1 = script1.eval();
92 assertEquals(7, result1);
93 result1 = script1.eval();
94 assertEquals(7, result1);
95
96 ctxt.setAttribute("x", 20, ScriptContext.ENGINE_SCOPE);
97 ctxt.setAttribute("y", 22, ScriptContext.ENGINE_SCOPE);
98 final CompiledScript script2 = engine.compile("x + y");
99 Object result2 = script2.eval();
100 assertEquals(42, result2);
101 ctxt.setAttribute("x", -20, ScriptContext.ENGINE_SCOPE);
102 ctxt.setAttribute("y", -22, ScriptContext.ENGINE_SCOPE);
103 result2 = script2.eval();
104 assertEquals(-42, result2);
105 }
106
107 @Test
108 public void testDirectNew() throws Exception {
109 final ScriptEngine engine = new JexlScriptEngine();
110 final Integer initialValue = 123;
111 assertEquals(initialValue,engine.eval("123"));
112 }
113
114 @Test
115 public void testDottedNames() throws Exception {
116 final ScriptEngineManager manager = new ScriptEngineManager();
117 assertNotNull(manager, "Manager should not be null");
118 final ScriptEngine engine = manager.getEngineByName("JEXL");
119 assertNotNull(engine, "Engine should not be null (JEXL)");
120 engine.eval("this.is.a.test=null");
121 assertNull(engine.get("this.is.a.test"));
122 assertEquals(Boolean.TRUE, engine.eval("empty(this.is.a.test)"));
123 final Object mymap = engine.eval("testmap={ 'key1' : 'value1', 'key2' : 'value2' }");
124 assertTrue(mymap instanceof Map<?, ?>);
125 assertEquals(2,((Map<?, ?>)mymap).size());
126 }
127
128 @Test
129 public void testErrors() throws Exception {
130 final ScriptEngineManager manager = new ScriptEngineManager();
131 final JexlScriptEngine engine = (JexlScriptEngine) manager.getEngineByName("JEXL");
132 final ScriptContext ctxt = engine.getContext();
133 engine.put("errors", new Errors());
134 assertTrue(assertThrows(ScriptException.class, () -> engine.eval("errors.npe()")).getCause() instanceof NullPointerException);
135 assertTrue(assertThrows(ScriptException.class, () -> engine.eval("errors.illegal()")).getCause() instanceof IllegalArgumentException);
136 final CompiledScript script0 = engine.compile("errors.npe()");
137 assertTrue(assertThrows(ScriptException.class, () -> script0.eval()).getCause() instanceof NullPointerException);
138 final CompiledScript script1 = engine.compile("errors.illegal()");
139 assertTrue(assertThrows(ScriptException.class, () -> script1.eval()).getCause() instanceof IllegalArgumentException);
140 }
141
142 @Test
143 public void testNulls() throws Exception {
144 final ScriptEngineManager manager = new ScriptEngineManager();
145 assertNotNull(manager, "Manager should not be null");
146 final ScriptEngine engine = manager.getEngineByName("jexl3");
147 assertNotNull(engine, "Engine should not be null (name)");
148 assertNotNull(engine.getFactory());
149 assertThrows(NullPointerException.class, () -> engine.eval((String) null));
150 assertThrows(NullPointerException.class, () -> engine.eval((Reader) null));
151 final ScriptContext ctxt = null;
152 assertThrows(NullPointerException.class, () -> engine.eval((String) null, ctxt));
153 assertThrows(NullPointerException.class, () -> engine.eval((Reader) null, ctxt));
154 }
155
156 @Test
157 public void testScopes() throws Exception {
158 final ScriptEngineManager manager = new ScriptEngineManager();
159 assertNotNull(manager, "Manager should not be null");
160 final ScriptEngine engine = manager.getEngineByName("jexl3");
161 assertNotNull(engine, "Engine should not be null (name)");
162 manager.put("global", 1);
163 engine.put("local", 10);
164 manager.put("both", 7);
165 engine.put("both", 7);
166 engine.eval("local=local+1");
167 engine.eval("global=global+1");
168 engine.eval("both=both+1");
169 engine.eval("newvar=42;");
170 assertEquals(2,manager.get("global"));
171 assertEquals(11,engine.get("local"));
172 assertEquals(7,manager.get("both"));
173 assertEquals(8,engine.get("both"));
174 assertEquals(42,engine.get("newvar"));
175 assertNull(manager.get("newvar"));
176 }
177
178 @Test
179 public void testScriptEngineFactory() throws Exception {
180 final JexlScriptEngineFactory factory = new JexlScriptEngineFactory();
181 assertEquals("JEXL Engine", factory.getParameter(ScriptEngine.ENGINE));
182 assertEquals("3.4", factory.getParameter(ScriptEngine.ENGINE_VERSION));
183 assertEquals("JEXL", factory.getParameter(ScriptEngine.LANGUAGE));
184 assertEquals("3.4", factory.getParameter(ScriptEngine.LANGUAGE_VERSION));
185 assertNull(factory.getParameter("THREADING"));
186 assertEquals(NAMES, factory.getParameter(ScriptEngine.NAME));
187 assertEquals(EXTENSIONS, factory.getExtensions());
188 assertEquals(MIMES, factory.getMimeTypes());
189
190 assertEquals("42;", factory.getProgram("42"));
191 assertEquals("str.substring(3,4)", factory.getMethodCallSyntax("str", "substring", "3", "4"));
192 }
193
194 @Test
195 public void testScripting() throws Exception {
196 final ScriptEngineManager manager = new ScriptEngineManager();
197 assertNotNull(manager, "Manager should not be null");
198 final ScriptEngine engine = manager.getEngineByName("jexl3");
199 final Integer initialValue = 123;
200 assertEquals(initialValue, engine.eval("123"));
201 assertEquals(initialValue, engine.eval("0;123"));
202 final ScriptException xscript = assertThrows(ScriptException.class,
203 () -> engine.eval("sys=context.class.forName(\"java.lang.System\");now=sys.currentTimeMillis();"));
204 final JexlException.Method xjexl = (JexlException.Method) xscript.getCause();
205 assertEquals("forName", xjexl.getMethod());
206 engine.put("value", initialValue);
207 assertEquals(initialValue, engine.get("value"));
208 final Integer newValue = 124;
209 assertEquals(newValue, engine.eval("old=value;value=value+1"));
210 assertEquals(initialValue, engine.get("old"));
211 assertEquals(newValue, engine.get("value"));
212 assertEquals(engine.getContext(), engine.get(JexlScriptEngine.CONTEXT_KEY));
213
214 assertEquals(engine.getContext().getReader(), engine.eval("JEXL.in"));
215 assertEquals(engine.getContext().getWriter(), engine.eval("JEXL.out"));
216 assertEquals(engine.getContext().getErrorWriter(), engine.eval("JEXL.err"));
217 assertEquals(System.class, engine.eval("JEXL.System"));
218 }
219
220 @Test
221 public void testScriptingGetBy() throws Exception {
222 final ScriptEngineManager manager = new ScriptEngineManager();
223 assertNotNull(manager, "Manager should not be null");
224 for (final String name : NAMES) {
225 final ScriptEngine engine = manager.getEngineByName(name);
226 assertNotNull(engine, "Engine should not be null (name)");
227 }
228 for (final String extension : EXTENSIONS) {
229 final ScriptEngine engine = manager.getEngineByExtension(extension);
230 assertNotNull(engine, "Engine should not be null (extension)");
231 }
232 for (final String mime : MIMES) {
233 final ScriptEngine engine = manager.getEngineByMimeType(mime);
234 assertNotNull(engine, "Engine should not be null (mime)");
235 }
236 }
237 @Test
238 public void testScriptingInstance0() throws Exception {
239 JexlScriptEngine.setPermissions(JexlPermissions.UNRESTRICTED);
240 final ScriptEngineManager manager = new ScriptEngineManager();
241 final ScriptEngine engine = manager.getEngineByName("jexl3");
242 final Long time2 = (Long) engine.eval(
243 "sys=context.class.forName(\"java.lang.System\");"
244 + "now=sys.currentTimeMillis();");
245 assertTrue(time2 <= System.currentTimeMillis());
246 }
247
248 @Test
249 public void testScriptingPermissions1() throws Exception {
250 JexlBuilder.setDefaultPermissions(JexlPermissions.UNRESTRICTED);
251 JexlScriptEngine.setPermissions(null);
252 final ScriptEngineManager manager = new ScriptEngineManager();
253 final ScriptEngine engine = manager.getEngineByName("jexl3");
254 final Long time2 = (Long) engine.eval(
255 "sys=context.class.forName(\"java.lang.System\");"
256 + "now=sys.currentTimeMillis();");
257 assertTrue(time2 <= System.currentTimeMillis());
258 }
259 }