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.assertTrue;
21  
22  import java.util.Map;
23  import java.util.TreeMap;
24  
25  import org.junit.jupiter.api.BeforeEach;
26  import org.junit.jupiter.api.Test;
27  
28  /**
29   * Test cases for synchronized calls.
30   * <p>May be a base for synchronized calls.
31   */
32  @SuppressWarnings({"boxing", "UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
33  class SynchronizedOverloadsTest extends JexlTestCase {
34      public SynchronizedOverloadsTest() {
35          super("SynchronizedOverloadsTest", null);
36      }
37  
38      @BeforeEach
39      @Override
40      public void setUp() throws Exception {
41          // ensure jul logging is only error to avoid warning in silent mode
42          java.util.logging.Logger.getLogger(JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE);
43      }
44  
45      @Test
46      void testSynchronized() throws Exception {
47          final Map<String, Object> ns = new TreeMap<>();
48          final JexlContext jc = new SynchronizedContext(new MapContext());
49          final JexlEngine jexl = new JexlBuilder().namespaces(ns).create();
50          final JexlScript js0 = jexl.createScript("@synchronized(y) {return y.size(); }", "y");
51          final Object size = js0.execute(jc, "foobar");
52          assertEquals(6, size);
53      }
54  
55      @Test
56      void testSynchronizer() throws Exception {
57          final Map<String, Object> ns = new TreeMap<>();
58          ns.put("synchronized", SynchronizedContext.class);
59          final JexlContext jc = new MapContext();
60          final JexlEngine jexl = new JexlBuilder().namespaces(ns).create();
61          final JexlScript js0 = jexl.createScript("synchronized:call(x, (y)->{y.size()})", "x");
62          final Object size = js0.execute(jc, "foobar");
63          assertEquals(6, size);
64      }
65  
66      @Test
67      void testUnsafeMonitor() throws Exception {
68          final SynchronizedArithmetic.AbstractMonitor abstractMonitor = new SynchronizedArithmetic.SafeMonitor();
69          final Map<String, Object> foo = new TreeMap<>();
70          foo.put("one", 1);
71          foo.put("two", 2);
72          foo.put("three", 3);
73          final JexlContext jc = new SynchronizedContext(new MapContext());
74          final JexlEngine jexl = new JexlBuilder().arithmetic(new SynchronizedArithmetic(abstractMonitor, true)).create();
75          final JexlScript js0 = jexl.createScript("x['four'] = 4; var t = 0.0; for(var z: x) { t += z; }; call(t, (y)->{return y});", "x");
76          Object t = js0.execute(jc, foo);
77          assertEquals(10.0d, t);
78          assertTrue(abstractMonitor.isBalanced());
79          assertEquals(2, abstractMonitor.getCount());
80          t = js0.execute(jc, foo);
81          assertEquals(10.0d, t);
82          assertTrue(abstractMonitor.isBalanced());
83          assertEquals(4, abstractMonitor.getCount());
84      }
85  }