1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3;
18
19 import org.apache.commons.jexl3.internal.Engine;
20 import org.junit.Assert;
21 import org.junit.Test;
22
23
24
25
26 @SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
27 public class ExceptionTest extends JexlTestCase {
28
29 public ExceptionTest() {
30 super("ExceptionTest");
31 }
32
33 public static class ThrowNPE {
34 boolean doThrow = false;
35 public String npe() {
36 throw new NullPointerException("ThrowNPE");
37 }
38
39 public void setFail(final boolean f) {
40 doThrow = f;
41 if (f) {
42 throw new NullPointerException("ThrowNPE/set");
43 }
44 }
45
46 public boolean getFail() {
47 if (doThrow) {
48 throw new NullPointerException("ThrowNPE/get");
49 }
50 return doThrow;
51 }
52 }
53
54 @Test
55 public void testWrappedEx() throws Exception {
56 final JexlEngine jexl = new Engine();
57 final JexlExpression e = jexl.createExpression("npe()");
58 final JexlContext jc = new ObjectContext<>(jexl, new ThrowNPE());
59 try {
60 e.evaluate(jc);
61 Assert.fail("Should have thrown NPE");
62 } catch (final JexlException xany) {
63 final Throwable xth = xany.getCause();
64 Assert.assertEquals(NullPointerException.class, xth.getClass());
65 }
66 }
67
68 @Test
69 public void testWrappedExmore() throws Exception {
70 final JexlEngine jexl = new Engine();
71 final ThrowNPE npe = new ThrowNPE();
72 try {
73 final Object r = jexl.getProperty(npe, "foo");
74 Assert.fail("Should have thrown JexlException.Property");
75 } catch (final JexlException.Property xany) {
76 final Throwable xth = xany.getCause();
77 Assert.assertNull(xth);
78 }
79 try {
80 jexl.setProperty(npe, "foo", 42);
81 Assert.fail("Should have thrown JexlException.Property");
82 } catch (final JexlException.Property xany) {
83 final Throwable xth = xany.getCause();
84 Assert.assertNull(xth);
85 }
86
87 final boolean b = (Boolean) jexl.getProperty(npe, "fail");
88 Assert.assertFalse(b);
89 try {
90 jexl.setProperty(npe, "fail", false);
91 jexl.setProperty(npe, "fail", true);
92 Assert.fail("Should have thrown JexlException.Property");
93 } catch (final JexlException.Property xany) {
94 final Throwable xth = xany.getCause();
95 Assert.assertEquals(NullPointerException.class, xth.getClass());
96 }
97 try {
98 jexl.getProperty(npe, "fail");
99 Assert.fail("Should have thrown JexlException.Property");
100 } catch (final JexlException.Property xany) {
101 final Throwable xth = xany.getCause();
102 Assert.assertEquals(NullPointerException.class, xth.getClass());
103 }
104
105 try {
106 jexl.invokeMethod(npe, "foo", 42);
107 Assert.fail("Should have thrown JexlException.Method");
108 } catch (final JexlException.Method xany) {
109 final Throwable xth = xany.getCause();
110 Assert.assertNull(xth);
111 }
112 try {
113 jexl.invokeMethod(npe, "npe");
114 Assert.fail("Should have thrown NullPointerException");
115 } catch (final JexlException.Method xany) {
116 final Throwable xth = xany.getCause();
117 Assert.assertEquals(NullPointerException.class, xth.getClass());
118 }
119 }
120
121
122
123 @Test
124 public void testEx() throws Exception {
125 final JexlEngine jexl = createEngine(false);
126 final JexlExpression e = jexl.createExpression("c.e * 6");
127 final JexlEvalContext ctxt = new JexlEvalContext();
128 final JexlOptions options = ctxt.getEngineOptions();
129
130 options.setSilent(false);
131
132 options.setStrict(true);
133
134 try {
135 e.evaluate(ctxt);
136 Assert.fail("c not defined as variable should throw");
137 } catch (final JexlException.Variable xjexl) {
138 final String msg = xjexl.getMessage();
139 Assert.assertTrue(msg.indexOf("variable 'c.e'") > 0);
140 }
141
142
143 options.setStrictArithmetic(true);
144 ctxt.set("c.e", null);
145 try {
146 e.evaluate(ctxt);
147 Assert.fail("c.e as null operand should throw");
148 } catch (final JexlException.Variable xjexl) {
149 final String msg = xjexl.getMessage();
150 Assert.assertTrue(msg.indexOf("variable 'c.e'") > 0);
151 }
152
153
154 options.setStrictArithmetic(false);
155 try {
156 e.evaluate(ctxt);
157
158 } catch (final JexlException xjexl) {
159 Assert.fail("c.e in expr should not throw");
160 }
161
162
163 ctxt.set("c", "{ 'a' : 3, 'b' : 5}");
164 ctxt.set("e", Integer.valueOf(2));
165 try {
166 e.evaluate(ctxt);
167 Assert.fail("c.e not accessible as property should throw");
168 } catch (final JexlException.Property xjexl) {
169 final String msg = xjexl.getMessage();
170 Assert.assertTrue(msg.indexOf("property 'e") > 0);
171 }
172 }
173
174
175 @Test
176 public void testExVar() throws Exception {
177 final JexlEngine jexl = createEngine(false);
178 final JexlScript e = jexl.createScript("(x)->{ x * 6 }");
179 final JexlEvalContext ctxt = new JexlEvalContext();
180 final JexlOptions options = ctxt.getEngineOptions();
181
182 options.setSilent(false);
183
184 options.setStrict(true);
185 options.setStrictArithmetic(true);
186
187 try {
188 e.execute(ctxt);
189 Assert.fail("x is null, should throw");
190 } catch (final JexlException xjexl) {
191 final String msg = xjexl.getMessage();
192 Assert.assertTrue(msg.indexOf("null") > 0);
193 }
194
195
196 options.setStrictArithmetic(false);
197 try {
198 final Object o = e.execute(ctxt, (Object) null);
199 } catch (final JexlException.Variable xjexl) {
200 Assert.fail("arithmetic allows null operands, should not throw");
201 }
202 }
203
204
205 @Test
206 public void testExMethod() throws Exception {
207 final JexlEngine jexl = createEngine(false);
208 final JexlExpression e = jexl.createExpression("c.e.foo()");
209 final JexlEvalContext ctxt = new JexlEvalContext();
210 final JexlOptions options = ctxt.getEngineOptions();
211
212 options.setSilent(false);
213
214 options.setStrict(true);
215
216 try {
217 e.evaluate(ctxt);
218 Assert.fail("c not declared as variable should throw");
219 } catch (final JexlException.Variable xjexl) {
220 final String msg = xjexl.getMessage();
221 Assert.assertTrue(msg.indexOf("variable 'c.e'") > 0);
222 }
223
224
225 options.setStrictArithmetic(true);
226 ctxt.set("c.e", null);
227 try {
228 e.evaluate(ctxt);
229 Assert.fail("c.e as null operand should throw");
230 } catch (final JexlException xjexl) {
231 final String msg = xjexl.getMessage();
232 Assert.assertTrue(msg.indexOf("variable 'c.e'") > 0);
233 }
234 }
235
236 @Test
237 public void test206() throws Exception {
238 String src = "null.1 = 2; return 42";
239 doTest206(src, false, false);
240 doTest206(src, false, true);
241 doTest206(src, true, false);
242 doTest206(src, true, true);
243 src = "x = null.1; return 42";
244 doTest206(src, false, false);
245 doTest206(src, false, true);
246 doTest206(src, true, false);
247 doTest206(src, true, true);
248 src = "x = y.1; return 42";
249 doTest206(src, false, false);
250 doTest206(src, false, true);
251 doTest206(src, true, false);
252 doTest206(src, true, true);
253 }
254 private void doTest206(final String src, final boolean strict, final boolean silent) throws Exception {
255 final CaptureLog l = new CaptureLog();
256 final JexlContext jc = new MapContext();
257 final JexlEngine jexl = new JexlBuilder().logger(l).strict(strict).silent(silent).create();
258 JexlScript e;
259 Object r = -1;
260 e = jexl.createScript(src);
261 try {
262 r = e.execute(jc);
263 if (strict && !silent) {
264 Assert.fail("should have thrown an exception");
265 }
266 } catch(final JexlException xjexl) {
267 if (!strict || silent) {
268 Assert.fail(src + ": should not have thrown an exception");
269 }
270 }
271 if (strict) {
272 if (silent && l.count("warn") == 0) {
273 Assert.fail(src + ": should have generated a warning");
274 }
275 } else {
276 if (l.count("debug") == 0) {
277 Assert.fail(src + ": should have generated a debug");
278 }
279 Assert.assertEquals(42, r);
280 }
281 }
282 }