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.ArrayList; 24 import java.util.Arrays; 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 BaseTestCase 33 { ArrayMethodsTestCase(final String name)34 public ArrayMethodsTestCase(final String name) 35 { 36 super(name); 37 } 38 39 /** 40 * Runs the test. 41 */ testArrayMethods()42 public void testArrayMethods() throws Exception 43 { 44 // test an array of string objects 45 Object array = new String[] { "foo", "bar", "baz" }; 46 checkResults(array, "woogie", true); 47 48 // test an array of primitive ints 49 array = new int[] { 1, 3, 7 }; 50 checkResults(array, 11, false); 51 52 // test an array of mixed objects, including null 53 array = new Object[] { 2.2, null }; 54 checkResults(array, "whatever", true); 55 // then set all the values to null 56 checkResults(array, null, true); 57 58 // then try an empty array 59 array = new Object[] {}; 60 checkResults(array, null, true); 61 62 // while we have an empty array and list in the context, 63 // make sure $array.get(0) and $list.get(0) throw 64 // the same type of exception (MethodInvocationException) 65 Throwable lt = null; 66 Throwable at = null; 67 try 68 { 69 evaluate("$list.get(0)"); 70 } 71 catch (Throwable t) 72 { 73 lt = t; 74 } 75 try 76 { 77 evaluate("$array.get(0)"); 78 } 79 catch (Throwable t) 80 { 81 at = t; 82 } 83 assertEquals(lt.getClass(), at.getClass()); 84 } 85 checkResults(Object array, Object setme, boolean compareToList)86 private void checkResults(Object array, Object setme, 87 boolean compareToList) throws Exception 88 { 89 context.put("array", array); 90 if (compareToList) 91 { 92 // create a list to match... 93 context.put("list", new ArrayList(Arrays.asList((Object[])array))); 94 } 95 96 // if the object to be set is null, then remove instead of put 97 if (setme != null) 98 { 99 context.put("setme", setme); 100 } 101 else 102 { 103 context.remove("setme"); 104 } 105 106 info("Changing to an array of: " + array.getClass().getComponentType()); 107 info("Changing setme to: " + setme); 108 109 int size = Array.getLength(array); 110 checkResult("size()", String.valueOf(size), compareToList); 111 112 boolean isEmpty = (size == 0); 113 checkResult("isEmpty()", String.valueOf(isEmpty), compareToList); 114 115 checkPropertyResult("empty", String.valueOf(isEmpty), compareToList); 116 117 // Since 2.1, arrays are rendered the same way as lists 118 String renderArray = evaluate("$array"); 119 String renderList = evaluate("$list"); 120 System.err.println("<<< " + renderArray); 121 System.err.println(">>> " + renderList); 122 if (compareToList) assertTrue(renderArray.equals(renderList)); 123 else assertFalse(renderArray.equals(renderList)); 124 125 for (int i=0; i < size; i++) 126 { 127 // put the index in the context, so we can try 128 // both an explicit index and a reference index 129 context.put("index", i); 130 131 Object value = Array.get(array, i); 132 String get = "get($index)"; 133 String set = "set("+i+", $setme)"; 134 if (value == null) 135 { 136 checkEmptyResult(get, compareToList); 137 // set should return null 138 checkEmptyResult(set, compareToList); 139 } 140 else 141 { 142 checkResult(get, value.toString(), compareToList); 143 // set should return the old get value 144 checkResult(set, value.toString(), compareToList); 145 } 146 147 // check that set() actually changed the value 148 assertEquals(setme, Array.get(array, i)); 149 150 // and check that get() now returns setme 151 if (setme == null) 152 { 153 checkEmptyResult(get, compareToList); 154 } 155 else 156 { 157 checkResult(get, setme.toString(), compareToList); 158 159 // now check that contains() properly finds the new value 160 checkResult("contains($setme)", "true", compareToList); 161 } 162 } 163 } 164 checkEmptyResult(String method, boolean compareToList)165 private void checkEmptyResult(String method, boolean compareToList) 166 throws Exception 167 { 168 checkResult(method, "", compareToList); 169 } 170 checkResult(String method, String expected, boolean compareToList)171 private void checkResult(String method, String expected, 172 boolean compareToList) throws Exception 173 { 174 String result = evaluate("$!array."+method); 175 assertEquals(expected, result); 176 177 String listResult = null; 178 if (compareToList) 179 { 180 listResult = evaluate("$!list."+method); 181 assertEquals(result, listResult); 182 } 183 184 info(" <$!array." + method + "> resolved to <" + result + ">"); 185 if (compareToList) 186 { 187 info(" <$!list."+method+"> resolved to "+listResult+">"); 188 } 189 } 190 checkPropertyResult(String property, String expected, boolean compareToList)191 private void checkPropertyResult(String property, String expected, 192 boolean compareToList) throws Exception 193 { 194 String result = evaluate("$!array."+property); 195 assertEquals(expected, result); 196 197 String listResult = null; 198 if (compareToList) 199 { 200 listResult = evaluate("$!list."+property); 201 assertEquals(result, listResult); 202 } 203 204 info(" <$!array."+property+"> resolved to <"+result+">"); 205 if (compareToList) 206 { 207 info(" <$!list."+property+"> resolved to "+listResult+">"); 208 } 209 } 210 211 } 212