1   package org.apache.velocity.test;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.lang.reflect.Array;
23  import java.util.Arrays;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  /**
28   * Used to check that method calls on Array references work properly
29   * and that they produce the same results as the same methods would on
30   * a fixed-size {@link List}.
31   */
32  public class ArrayMethodsTestCase extends BaseEvalTestCase
33  {
34      private final static boolean PRINT_RESULTS = false;
35  
36      public ArrayMethodsTestCase(final String name)
37      {
38          super(name);
39      }
40  
41      /**
42       * Runs the test.
43       */
44      public void testArrayMethods() throws Exception
45      {
46          // test an array of string objects
47          Object array = new String[] { "foo", "bar", "baz" };
48          checkResults(array, "woogie", true);
49  
50          // test an array of primitive ints
51          array = new int[] { 1, 3, 7 };
52          checkResults(array, new Integer(11), false);
53  
54          // test an array of mixed objects, including null
55          array = new Object[] { new Double(2.2), null };
56          checkResults(array, "whatever", true);
57          // then set all the values to null
58          checkResults(array, null, true);
59  
60          // then try an empty array
61          array = new Object[] {};
62          checkResults(array, null, true);
63  
64          // while we have an empty array and list in the context,
65          // make sure $array.get(0) and $list.get(0) throw
66          // the same type of exception (MethodInvocationException)
67          Throwable lt = null;
68          Throwable at = null;
69          try
70          {
71              evaluate("$list.get(0)");
72          }
73          catch (Throwable t)
74          {
75              lt = t;
76          }
77          try
78          {
79              evaluate("$array.get(0)");
80          }
81          catch (Throwable t)
82          {
83              at = t;
84          }
85          assertEquals(lt.getClass(), at.getClass());
86      }
87  
88      private void checkResults(Object array, Object setme,
89                                boolean compareToList) throws Exception
90      {
91          context.put("array", array);
92          if (compareToList)
93          {
94              // create a list to match...
95              context.put("list", new ArrayList(Arrays.asList((Object[])array)));
96          }
97  
98          // if the object to be set is null, then remove instead of put
99          if (setme != null)
100         {
101             context.put("setme", setme);
102         }
103         else
104         {
105             context.remove("setme");
106         }
107 
108         if (PRINT_RESULTS)
109         {
110             System.out.println("Changing to an array of: " + array.getClass().getComponentType());
111             System.out.println("Changing setme to: " + setme);
112         }
113 
114         int size = Array.getLength(array);
115         checkResult("size()", String.valueOf(size), compareToList);
116 
117         boolean isEmpty = (size == 0);
118         checkResult("isEmpty()", String.valueOf(isEmpty), compareToList);
119 
120         // check that the wrapping doesn't apply to java.lang.Object methods
121         // such as toString() (for backwards compatibility).
122         assertFalse(evaluate("$array").equals(evaluate("$list")));
123 
124         for (int i=0; i < size; i++)
125         {
126             // put the index in the context, so we can try
127             // both an explicit index and a reference index
128             context.put("index", new Integer(i));
129 
130             Object value = Array.get(array, i);
131             String get = "get($index)";
132             String set = "set("+i+", $setme)";
133             if (value == null)
134             {
135                 checkEmptyResult(get, compareToList);
136                 // set should return null
137                 checkEmptyResult(set, compareToList);
138             }
139             else
140             {
141                 checkResult(get, value.toString(), compareToList);
142                 // set should return the old get value
143                 checkResult(set, value.toString(), compareToList);
144             }
145 
146             // check that set() actually changed the value
147             assertEquals(setme, Array.get(array, i));
148 
149             // and check that get() now returns setme
150             if (setme == null)
151             {
152                 checkEmptyResult(get, compareToList);
153             }
154             else
155             {
156                 checkResult(get, setme.toString(), compareToList);
157 
158                 // now check that contains() properly finds the new value
159                 checkResult("contains($setme)", "true", compareToList);
160             }
161         }
162     }
163 
164     private void checkEmptyResult(String method, boolean compareToList)
165         throws Exception
166     {
167         checkResult(method, "", compareToList);
168     }
169 
170     private void checkResult(String method, String expected,
171                              boolean compareToList) throws Exception
172     {
173         String result = evaluate("$!array."+method);
174         assertEquals(expected, result);
175 
176         String listResult = null;
177         if (compareToList)
178         {
179             listResult = evaluate("$!list."+method);
180             assertEquals(result, listResult);
181         }
182 
183         if (PRINT_RESULTS)
184         {
185             System.out.println("    <$!array."+method+"> resolved to <"+result+">");
186             if (compareToList)
187             {
188                 System.out.println("    <$!list."+method+"> resolved to "+listResult+">");
189             }
190         }
191     }
192 
193 }
194 
195