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.StringWriter;
23  import java.io.Writer;
24  
25  import junit.framework.Test;
26  import junit.framework.TestSuite;
27  
28  import org.apache.velocity.Template;
29  import org.apache.velocity.VelocityContext;
30  import org.apache.velocity.app.VelocityEngine;
31  import org.apache.velocity.exception.ParseErrorException;
32  
33  /**
34   * Test parser exception is generated with appropriate info.
35   *
36   * @author <a href="mailto:wglass@apache.org">Will Glass-Husain</a>
37   * @version $Id: ParseExceptionTestCase.java 736027 2009-01-20 14:19:54Z byron $
38   */
39  public class ParseExceptionTestCase extends BaseTestCase
40  {
41      /**
42       * Path for templates. This property will override the
43       * value in the default velocity properties file.
44       */
45      private final static String FILE_RESOURCE_LOADER_PATH = "test/parseexception";
46  
47  
48      /**
49       * Default constructor.
50       * @param name name of test
51       */
52      public ParseExceptionTestCase(String name)
53      {
54          super(name);
55      }
56  
57      public void setUp()
58              throws Exception
59      {
60  
61      }
62  
63      public static Test suite ()
64      {
65          return new TestSuite(ParseExceptionTestCase.class);
66      }
67  
68      /**
69       * Tests that parseException has useful info when called by template.marge()
70       * @throws Exception
71       */
72      public void testParseExceptionFromTemplate ()
73              throws Exception
74      {
75  
76          VelocityEngine ve = new VelocityEngine();
77  
78          ve.setProperty("file.resource.loader.cache", "true");
79          ve.setProperty("file.resource.loader.path", FILE_RESOURCE_LOADER_PATH);
80          ve.init();
81  
82  
83          Writer writer = new StringWriter();
84  
85          VelocityContext context = new VelocityContext();
86  
87          try
88          {
89              Template template = ve.getTemplate("badtemplate.vm");
90              template.merge(context, writer);
91              fail("Should have thown a ParseErrorException");
92          }
93          catch (ParseErrorException e)
94          {
95              assertEquals("badtemplate.vm",e.getTemplateName());
96              assertEquals(5,e.getLineNumber());
97              assertEquals(9,e.getColumnNumber());
98          }
99          finally
100         {
101             if (writer != null)
102             {
103                 writer.close();
104             }
105         }
106     }
107 
108     /**
109      * Tests that parseException has useful info when thrown in VelocityEngine.evaluate()
110      * @throws Exception
111      */
112     public void testParseExceptionFromEval ()
113             throws Exception
114     {
115 
116         VelocityEngine ve = new VelocityEngine();
117         ve.init();
118 
119         VelocityContext context = new VelocityContext();
120 
121         Writer writer = new StringWriter();
122 
123         try
124         {
125             ve.evaluate(context,writer,"test","   #set($abc)   ");
126             fail("Should have thown a ParseErrorException");
127         }
128         catch (ParseErrorException e)
129         {
130             assertEquals("test",e.getTemplateName());
131             assertEquals(1,e.getLineNumber());
132             assertEquals(13,e.getColumnNumber());
133         }
134         finally
135         {
136             if (writer != null)
137             {
138                 writer.close();
139             }
140         }
141     }
142 
143     /**
144      * Tests that parseException has useful info when thrown in VelocityEngine.evaluate()
145      * and the problem comes from a macro definition
146      * @throws Exception
147      */
148     public void testParseExceptionFromMacroDef ()
149             throws Exception
150     {
151         VelocityEngine ve = new VelocityEngine();
152         ve.init();
153 
154         VelocityContext context = new VelocityContext();
155 
156         Writer writer = new StringWriter();
157 
158         try
159         {
160             ve.evaluate(context,writer,"testMacro","#macro($blarg) foo #end");
161             fail("Should have thown a ParseErrorException");
162         }
163         catch (ParseErrorException e)
164         {
165             assertEquals("testMacro",e.getTemplateName());
166             assertEquals(1,e.getLineNumber());
167             assertEquals(7,e.getColumnNumber());
168         }
169         finally
170         {
171             if (writer != null)
172             {
173                 writer.close();
174             }
175         }
176     }
177 
178     /**
179      * Tests that parseException has useful info when thrown in VelocityEngine.evaluate()
180      * and the problem comes from a macro definition
181      * @throws Exception
182      */
183     public void testParseExceptionFromMacroDefBody ()
184             throws Exception
185     {
186         VelocityEngine ve = new VelocityEngine();
187         ve.init();
188 
189         VelocityContext context = new VelocityContext();
190         
191         Writer writer = new StringWriter();
192 
193         try
194         {
195             ve.evaluate(context,writer,"testMacro","#macro(aa $blarg) #set(!! = bb) #end #aa('aa')");
196             fail("Should have thown a ParseErrorException");
197         }
198         catch (ParseErrorException e)
199         {
200             assertEquals("testMacro",e.getTemplateName());
201             assertEquals(1,e.getLineNumber());
202             assertEquals(24,e.getColumnNumber());
203         }
204         finally
205         {
206             if (writer != null)
207             {
208                 writer.close();
209             }
210         }
211     }
212 
213     /**
214      * Tests that parseException has useful info when thrown in VelocityEngine.evaluate()
215      * and the problem comes from a macro invocation
216      * @throws Exception
217      */
218     public void testParseExceptionFromMacroInvoke ()
219             throws Exception
220     {
221         VelocityEngine ve = new VelocityEngine();
222         ve.init();
223 
224         VelocityContext context = new VelocityContext();
225 
226         Writer writer = new StringWriter();
227 
228         try
229         {
230             ve.evaluate(context,writer,"testMacroInvoke", "#macro(   foo $a) $a #end #foo(woogie)");
231             fail("Should have thown a ParseErrorException");
232         }
233         catch (org.apache.velocity.exception.TemplateInitException e)
234         {
235             assertEquals("testMacroInvoke",e.getTemplateName());
236             assertEquals(1,e.getLineNumber());
237             assertEquals(27,e.getColumnNumber());
238         }
239         finally
240         {
241             if (writer != null)
242             {
243                 writer.close();
244             }
245         }
246     }
247 
248 
249     /**
250      * Tests that parseException has useful info with macro calls with
251      * invalid number of arguments
252      * @throws Exception
253      */
254     public void testParseExceptionMacroInvalidArgumentCount ()
255             throws Exception
256     {
257         VelocityEngine ve = new VelocityEngine();
258         ve.setProperty("velocimacro.arguments.strict","true");
259         ve.init();
260         
261         VelocityContext context = new VelocityContext();
262         
263         Writer writer = new StringWriter();
264         
265         try 
266         {
267             ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')");     
268             fail("Should have thown a ParseErrorException");
269         } 
270         catch (ParseErrorException e) 
271         {
272             assertEquals("testMacroInvoke",e.getTemplateName());
273             assertEquals(1,e.getLineNumber());
274             assertEquals(24,e.getColumnNumber());
275         } 
276         finally
277         {
278             if (writer != null)
279             {
280                 writer.close();
281             }
282         }
283     }
284 
285     
286     /**
287      * Tests that parseException has useful info with macro calls with
288      * invalid number of arguments
289      * @throws Exception
290      */
291     public void testParseExceptionMacroInvalidArgumentCountNoException ()
292             throws Exception
293     {
294         VelocityEngine ve = new VelocityEngine();
295         ve.init();
296         
297         VelocityContext context = new VelocityContext();
298         
299         Writer writer = new StringWriter();
300 
301         // will not throw an exception
302         try 
303         {
304             ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')");     
305         }
306         finally
307         {
308             if (writer != null)
309             {
310                 writer.close();
311             }
312         }
313     }
314 
315     
316 }