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 471372 2006-11-05 06:02:20Z wglass $
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 invocation
181      * @throws Exception
182      */
183     public void testParseExceptionFromMacroInvoke ()
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,"testMacroInvoke", "#macro(   foo $a) $a #end #foo(woogie)");
196             fail("Should have thown a ParseErrorException");
197         }
198         catch (ParseErrorException e)
199         {
200             assertEquals("testMacroInvoke",e.getTemplateName());
201             assertEquals(1,e.getLineNumber());
202             assertEquals(31,e.getColumnNumber());
203         }
204         finally
205         {
206             if (writer != null)
207             {
208                 writer.close();
209             }
210         }
211     }
212 
213 
214     /**
215      * Tests that parseException has useful info with macro calls with
216      * invalid number of arguments
217      * @throws Exception
218      */
219     public void testParseExceptionMacroInvalidArgumentCount ()
220             throws Exception
221     {
222         VelocityEngine ve = new VelocityEngine();
223         ve.setProperty("velocimacro.arguments.strict","true");
224         ve.init();
225         
226         VelocityContext context = new VelocityContext();
227         
228         Writer writer = new StringWriter();
229         
230         try 
231         {
232             ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')");     
233             fail("Should have thown a ParseErrorException");
234         } 
235         catch (ParseErrorException e) 
236         {
237             assertEquals("testMacroInvoke",e.getTemplateName());
238             assertEquals(1,e.getLineNumber());
239             assertEquals(24,e.getColumnNumber());
240         } 
241         finally
242         {
243             if (writer != null)
244             {
245                 writer.close();
246             }
247         }
248     }
249 
250     
251     /**
252      * Tests that parseException has useful info with macro calls with
253      * invalid number of arguments
254      * @throws Exception
255      */
256     public void testParseExceptionMacroInvalidArgumentCountNoException ()
257             throws Exception
258     {
259         VelocityEngine ve = new VelocityEngine();
260         ve.init();
261         
262         VelocityContext context = new VelocityContext();
263         
264         Writer writer = new StringWriter();
265 
266         // will not throw an exception
267         try 
268         {
269             ve.evaluate(context,writer,"testMacroInvoke", "#macro(foo $a) $a #end #foo('test1' 'test2')");     
270         }
271         finally
272         {
273             if (writer != null)
274             {
275                 writer.close();
276             }
277         }
278     }
279 
280     
281 }