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.util.Map;
24  import java.util.HashMap;
25  
26  import junit.framework.Test;
27  import junit.framework.TestCase;
28  import junit.framework.TestSuite;
29  
30  import org.apache.velocity.VelocityContext;
31  import org.apache.velocity.app.VelocityEngine;
32  import org.apache.velocity.exception.ParseErrorException;
33  
34  /**
35   *  More specific parser tests where just templating
36   *  isn't enough.
37   *
38   * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
39   * @version $Id: ParserTestCase.java 463298 2006-10-12 16:10:32Z henning $
40   */
41  public class ParserTestCase extends TestCase
42  {
43      public ParserTestCase(String testName)
44      {
45          super(testName);
46      }
47  
48      public static Test suite()
49      {
50         return new TestSuite(ParserTestCase.class);
51      }
52  
53      /**
54       *  Test to make sure that using '=' in #if() throws a PEE
55       */
56      public void testEquals()
57          throws Exception
58      {
59          VelocityEngine ve = new VelocityEngine();
60  
61          ve.init();
62  
63          /*
64           *  this should parse fine -> uses ==
65           */
66  
67          String template = "#if($a == $b) foo #end";
68  
69          ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
70  
71          /*
72           *  this should throw an exception
73           */
74  
75          template = "#if($a = $b) foo #end";
76  
77          try
78          {
79              ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
80              fail("Could evaluate template with errors!");
81          }
82          catch(ParseErrorException pe)
83          {
84              // Do nothing
85          }
86      }
87  
88      /**
89       *  Test to see if we force the first arg to #macro() to be a word
90       */
91      public void testMacro()
92          throws Exception
93      {
94          VelocityEngine ve = new VelocityEngine();
95  
96          ve.init();
97  
98          /*
99           * this should work
100          */
101 
102         String template = "#macro(foo) foo #end";
103 
104         ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
105 
106          /*
107           *  this should throw an exception
108           */
109 
110         template = "#macro($x) foo #end";
111 
112         try
113         {
114             ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
115             fail("Could evaluate macro with errors!");
116         }
117         catch(ParseErrorException pe)
118         {
119             // Do nothing
120         }
121     }
122 
123     /**
124      *  Test to see if don't tolerage passing word tokens in anything but the
125      *  0th arg to #macro() and the 1th arg to foreach()
126      */
127     public void testArgs()
128         throws Exception
129     {
130         VelocityEngine ve = new VelocityEngine();
131 
132         ve.init();
133 
134         /*
135          * this should work
136          */
137 
138         String template = "#macro(foo) foo #end";
139 
140         ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
141 
142          /*
143           *  this should work - spaces intentional
144           */
145 
146         template = "#foreach(  $i     in  $woogie   ) end #end";
147 
148         ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
149 
150         /*
151          *  this should bomb
152          */
153 
154        template = "#macro(   foo $a) $a #end #foo(woogie)";
155 
156         try
157         {
158             ve.evaluate(new VelocityContext(), new StringWriter(), "foo", template);
159             fail("Evaluation of macro with errors succeeded!");
160         }
161         catch(ParseErrorException pe)
162         {
163             // Do nothing
164         }
165     }
166 
167     /**
168      *  Test to see if we toString is called multiple times on references.
169      */
170     public void testASTReferenceToStringOnlyCalledOnce()
171         throws Exception
172     {
173         VelocityEngine ve = new VelocityEngine();
174 
175         ve.init();
176 
177         String template = "$counter";
178 
179         ToStringCounter counter = new ToStringCounter();
180         Map m = new HashMap();
181         m.put("counter", counter);
182 
183         ve.evaluate(new VelocityContext(m), new StringWriter(), "foo", template);
184 
185         assertEquals(1, counter.timesCalled);
186     }
187 
188     public static class ToStringCounter {
189         public int timesCalled = 0;
190         public String toString() {
191             this.timesCalled++;
192             return "foo";
193         }
194     }
195 
196 }