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.io.BufferedWriter;
23  import java.io.FileOutputStream;
24  import java.io.OutputStreamWriter;
25  import java.io.Writer;
26  
27  import junit.framework.Test;
28  import junit.framework.TestSuite;
29  
30  import org.apache.velocity.Template;
31  import org.apache.velocity.VelocityContext;
32  import org.apache.velocity.app.VelocityEngine;
33  import org.apache.velocity.context.Context;
34  import org.apache.velocity.runtime.RuntimeConstants;
35  import org.apache.velocity.runtime.RuntimeServices;
36  import org.apache.velocity.runtime.log.LogChute;
37  
38  /**
39   * Test a reported bug in which method overloading throws IllegalArgumentException 
40   * after a null return value.
41   * (VELOCITY-132).
42   * 
43   * @author <a href="mailto:wglass@forio.com">Will Glass-Husain</a>
44   * @version $Id: MethodOverloadingTestCase.java 463298 2006-10-12 16:10:32Z henning $
45   */
46  public class MethodOverloadingTestCase extends BaseTestCase implements LogChute
47  {
48      String logData;
49      
50      /**
51      * VTL file extension.
52      */
53     private static final String TMPL_FILE_EXT = "vm";
54  
55     /**
56      * Comparison file extension.
57      */
58     private static final String CMP_FILE_EXT = "cmp";
59  
60     /**
61      * Comparison file extension.
62      */
63     private static final String RESULT_FILE_EXT = "res";
64  
65     /**
66      * Path for templates. This property will override the
67      * value in the default velocity properties file.
68      */
69     private final static String FILE_RESOURCE_LOADER_PATH = TEST_COMPARE_DIR + "/methodoverloading";
70  
71     /**
72      * Results relative to the build directory.
73      */
74     private static final String RESULTS_DIR = TEST_RESULT_DIR + "/methodoverloading";
75  
76     /**
77      * Results relative to the build directory.
78      */
79     private static final String COMPARE_DIR = TEST_COMPARE_DIR + "/methodoverloading/compare";
80  
81      /**
82       * Default constructor.
83       */
84      public MethodOverloadingTestCase(String name)
85      {
86          super(name);
87      }
88  
89      public void setUp()
90      {
91          assureResultsDirectoryExists(RESULTS_DIR);
92      }
93  
94      public static Test suite()
95      {
96         return new TestSuite(MethodOverloadingTestCase.class);
97      }
98  
99      public void testMethodOverloading()
100     throws Exception
101     {
102         /**
103          * test overloading in a single template
104          */
105         testFile("single");
106 
107         assertTrue(logData.indexOf("IllegalArgumentException") == -1);
108     }
109 
110     public void testParsedMethodOverloading()
111     throws Exception
112     {
113         /**
114          * test overloading in a file included with #parse
115          */
116         testFile("main");
117         
118         assertTrue(logData.indexOf("IllegalArgumentException") == -1);
119         
120     }
121     
122     public void testFile(String basefilename)
123     throws Exception
124     {
125         
126         VelocityEngine ve = new VelocityEngine();
127         ve.addProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, FILE_RESOURCE_LOADER_PATH);
128         ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this );
129         ve.init();
130         
131         Template template;
132         FileOutputStream fos;
133         Writer fwriter;
134         Context context;
135         
136         template = ve.getTemplate( getFileName(null, basefilename, TMPL_FILE_EXT) );
137         
138         fos = new FileOutputStream (
139                 getFileName(RESULTS_DIR, basefilename, RESULT_FILE_EXT));
140         
141         fwriter = new BufferedWriter( new OutputStreamWriter(fos) );
142         
143         context = new VelocityContext();
144         setupContext(context);
145         template.merge(context, fwriter);
146         fwriter.flush();
147         fwriter.close();
148         
149         if (!isMatch(RESULTS_DIR, COMPARE_DIR, basefilename, RESULT_FILE_EXT, CMP_FILE_EXT))
150         {
151             fail("Output incorrect.");
152         }
153     }
154         
155     public void setupContext(Context context)
156     {
157       context.put("test", this);
158       context.put("nullValue", null);  
159     } 
160     
161     
162     public String overloadedMethod ( Integer s )
163     {
164         return "Integer";
165     }
166     
167     public String overloadedMethod ( String s )
168     {
169         return "String";
170     }
171     
172     
173     public String overloadedMethod2 ( Integer s )
174     {
175         return "Integer";
176     }
177     
178     public String overloadedMethod2 ( String i )
179     {
180         return "String";
181     }
182 
183 
184     public void log(int level, String message)
185     {
186         String out = "";
187 
188         /*
189          * Start with the appropriate prefix
190          */
191         switch( level )
192         {
193             case DEBUG_ID :
194                 out = DEBUG_PREFIX;
195                 break;
196             case INFO_ID :
197                 out = INFO_PREFIX;
198                 break;
199             case TRACE_ID :
200                 out = TRACE_PREFIX;
201                 break;
202             case WARN_ID :
203                 out = WARN_PREFIX;
204                 break;
205             case ERROR_ID :
206                 out = ERROR_PREFIX;
207                 break;
208             default :
209                 out = INFO_PREFIX;
210                 break;
211         }
212 
213         logData += "\n" + out + message;
214     }
215 
216     public void init( RuntimeServices rs )
217     {
218         // do nothing with it
219     }
220 
221     public void log(int level, String message, Throwable t)
222     {
223         // ignore the Throwable, we're not testing this method here
224         log(level, message);
225     }
226 
227     public boolean isLevelEnabled(int level)
228     {
229         return true;
230     }
231 }