View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.jexl3;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertInstanceOf;
22  import static org.junit.jupiter.api.Assertions.assertNotNull;
23  import static org.junit.jupiter.api.Assertions.assertThrows;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.IOException;
27  import java.io.UnsupportedEncodingException;
28  
29  import org.junit.jupiter.api.Disabled;
30  import org.junit.jupiter.api.Test;
31  
32  class TryCatchFinallyTest extends JexlTestCase {
33      public static class Circuit implements AutoCloseable {
34          boolean opened = true;
35  
36          @Override
37          public void close() throws IOException {
38              opened = false;
39          }
40  
41          public boolean isOpened() {
42              return opened;
43          }
44  
45          public void raiseError() {
46              throw new RuntimeException("raising error");
47          }
48      }
49  
50      public TryCatchFinallyTest() {
51          super(TryCatchFinallyTest.class.getSimpleName());
52      }
53  
54      @Test
55      void testCloseable0x2b() {
56          final String src = "try(let x = c) { c.isOpened()? 42 : -42; } finally { 169; }";
57          final JexlScript script = JEXL.createScript(src, "c");
58          final Circuit circuit = new Circuit();
59          assertNotNull(script);
60          final Object result = script.execute(null, circuit);
61          assertEquals(42, result);
62          assertFalse(circuit.isOpened());
63      }
64  
65      @Test
66      void testCloseable0x3b() {
67          final String src = "try(let x = c) { c.raiseError(); -42; } catch(const y) { 42; } finally { 169; }";
68          final JexlScript script = JEXL.createScript(src, "c");
69          final Circuit circuit = new Circuit();
70          assertNotNull(script);
71          final Object result = script.execute(null, circuit);
72          assertEquals(42, result);
73          assertFalse(circuit.isOpened());
74      }
75  
76      @Disabled
77      void testEdgeTry() throws Exception {
78          int i = 0;
79          while (i++ < 5) {
80              // System.out.println("i: " + i);
81              try {
82                  throw new JexlException.Continue(null);
83              } finally {
84                  continue;
85              }
86          }
87          // System.out.println("iii: " + i);
88  
89          // int x = 0;
90          try (AutoCloseable x = new Circuit()) {
91              // empty
92          }
93      }
94  
95      @Test
96      void testExceptionType() throws Exception {
97          final JexlScript e = JEXL.createScript("try { 'asb'.getBytes('NoSuchCharacterSet'); } catch (let ex) { ex }");
98          final JexlContext jc = new MapContext();
99          final Object o = e.execute(jc);
100         assertInstanceOf(UnsupportedEncodingException.class, o);
101     }
102 
103     @Test
104     void testForm0x2a() {
105         final String src = "try(let x = 42) { x; } finally { 169; }";
106         final JexlScript script = JEXL.createScript(src);
107         assertNotNull(script);
108         final Object result = script.execute(null);
109         assertEquals(42, result);
110     }
111 
112     @Test
113     void testForm0x2b() {
114         final String src = "try(let x = 19, y = 23) { x + y; } finally { 169; }";
115         final JexlScript script = JEXL.createScript(src);
116         assertNotNull(script);
117         final Object result = script.execute(null);
118         assertEquals(42, result);
119     }
120 
121     @Test
122     void testForm0x2c() {
123         final String src = "try(const x = 19; let y = 23; ) { x + y; } finally { 169; }";
124         final JexlScript script = JEXL.createScript(src);
125         assertNotNull(script);
126         final Object result = script.execute(null);
127         assertEquals(42, result);
128     }
129 
130     @Test
131     void testForm0x2d() {
132         final String src = "try(var x = 19; const y = 23;) { x + y; } finally { 169; }";
133         final JexlScript script = JEXL.createScript(src);
134         assertNotNull(script);
135         final Object result = script.execute(null);
136         assertEquals(42, result);
137     }
138 
139     @Test
140     void testRedefinition0() {
141         final String src = "try(let x = c) { let x = 3; -42; }";
142         final JexlException.Parsing xvar = assertThrows(JexlException.Parsing.class, () -> JEXL.createScript(src, "c"));
143         assertTrue(xvar.getMessage().contains("x: variable is already declared"));
144     }
145 
146     @Test
147     void testRedefinition1() {
148         final String src = "const x = 33; try(let x = c) { 169; }";
149         final JexlException.Parsing xvar = assertThrows(JexlException.Parsing.class, () -> JEXL.createScript(src, "c"));
150         assertTrue(xvar.getMessage().contains("x: variable is already declared"));
151     }
152 
153     @Test
154     void testStandard0x2() {
155         final String src = "try { 42; } finally { 169; }";
156         final JexlScript script = JEXL.createScript(src);
157         assertNotNull(script);
158         final Object result = script.execute(null);
159         assertEquals(42, result);
160     }
161 
162     @Test
163     void testThrow0x2a() {
164         final String src = "try(let x = 42) { throw x } finally { 169; }";
165         final JexlScript script = JEXL.createScript(src);
166         assertNotNull(script);
167         final JexlException.Throw xthrow = assertThrows(JexlException.Throw.class, () -> script.execute(null));
168         assertEquals(42, xthrow.getValue());
169     }
170 
171     @Test
172     void testThrow0x2b() {
173         final String src = "try(let x = 42) { throw x } finally { throw 169 }";
174         final JexlScript script = JEXL.createScript(src);
175         assertNotNull(script);
176         final JexlException.Throw xthrow = assertThrows(JexlException.Throw.class, () -> script.execute(null));
177         assertEquals(169, xthrow.getValue());
178     }
179 
180     @Test
181     void testThrowCatchBreakFinallyContinue() {
182         final String src = "let r = 0; for(let i : 37..42) { try(let x = 169) { r = i; throw -x } catch(const y) { break } finally { continue } } r";
183         final JexlScript script = JEXL.createScript(src);
184         assertNotNull(script);
185         final Object result = script.execute(null);
186         assertEquals(42, result);
187     }
188 
189     @Test
190     void testThrowCatchContinueFinallyBreak() {
191         final String src = "let r = 0; for(let i : 42..37) { try(let x = 169) { r = i; throw -x } catch(const y) { continue } finally { break } } r";
192         final JexlScript script = JEXL.createScript(src);
193         assertNotNull(script);
194         final Object result = script.execute(null);
195         assertEquals(42, result);
196     }
197 
198     @Test
199     void testThrowCatchThrow() {
200         final String src = "try(let x = 42) { throw x } catch(const y) { throw -(y.value) } ";
201         final JexlScript script = JEXL.createScript(src);
202         assertNotNull(script);
203         final JexlException.Throw xthrow = assertThrows(JexlException.Throw.class, () -> script.execute(null));
204         assertEquals(-42, xthrow.getValue());
205     }
206 
207     @Test
208     void testThrowCatchThrowFinallyThrow() {
209         final String src = "try(let x = 42) { throw x } catch(const y) { throw -(y.value) } finally { throw 169 }";
210         final JexlScript script = JEXL.createScript(src);
211         assertNotNull(script);
212         final JexlException.Throw xthrow = assertThrows(JexlException.Throw.class, () -> script.execute(null));
213         assertEquals(169, xthrow.getValue());
214     }
215 
216     @Test
217     void testThrowRecurse() {
218         final String src = "function fact(x, f) { if (x == 1) throw f; fact(x - 1, f * x); } fact(7, 1);";
219         final JexlScript script = JEXL.createScript(src);
220         assertNotNull(script);
221         final JexlException.Throw xthrow = assertThrows(JexlException.Throw.class, () -> script.execute(null));
222         assertEquals(5040, xthrow.getValue());
223     }
224 
225     @Test
226     void testTryReturn() {
227         final String src = "try(let x = 42) { return x } catch(const y) { throw -(y.value) } ";
228         final JexlScript script = JEXL.createScript(src);
229         assertNotNull(script);
230         final Object result = script.execute(null);
231         assertEquals(42, result);
232     }
233 
234     @Test
235     void testTryReturnFinallyReturn() {
236         final String src = "try(let x = 42) { return x } finally { return 169 } ";
237         final JexlScript script = JEXL.createScript(src);
238         assertNotNull(script);
239         final Object result = script.execute(null);
240         assertEquals(169, result);
241     }
242 }