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.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import org.apache.velocity.runtime.RuntimeConstants;
27  import org.apache.velocity.test.provider.ForeachMethodCallHelper;
28  
29  /**
30   * This class tests the Foreach loop.
31   *
32   * @author Daniel Rall
33   * @author <a href="mailto:wglass@apache.org">Will Glass-Husain</a>
34   */
35  public class ForeachTestCase extends BaseTestCase
36  {
37      public ForeachTestCase(String name)
38      {
39          super(name);
40      }
41  
42      /**
43       * Tests limiting of the number of loop iterations.
44       */
45      public void testMaxNbrLoopsConstraint()
46          throws Exception
47      {
48          // Limit the loop to three iterations.
49          engine.setProperty(RuntimeConstants.MAX_NUMBER_LOOPS,
50                               new Integer(3));
51  
52          assertEvalEquals("1 2 3 ", "#foreach ($item in [1..10])$item #end");             
53      }
54  
55      /**
56       * Tests proper method execution during a Foreach loop over a Collection
57       * with items of varying classes.
58       */
59      public void testCollectionAndMethodCall()
60          throws Exception
61      {
62          List col = new ArrayList();
63          col.add(new Integer(100));
64          col.add("STRVALUE");
65          context.put("helper", new ForeachMethodCallHelper());
66          context.put("col", col);
67  
68          assertEvalEquals("int 100 str STRVALUE ", "#foreach ( $item in $col )$helper.getFoo($item) #end");             
69      }
70  
71      /**
72       * Tests that #foreach will be able to retrieve an iterator from
73       * an arbitrary object that happens to have an iterator() method.
74       * (With the side effect of supporting the new Java 5 Iterable interface)
75       */
76      public void testObjectWithIteratorMethod()
77          throws Exception
78      {
79          context.put("iterable", new MyIterable());
80  
81          assertEvalEquals("1 2 3 ", "#foreach ($i in $iterable)$i #end");             
82      }
83  
84      public void testNotReallyIterableIteratorMethod()
85          throws Exception
86      {
87          context.put("nri", new NotReallyIterable());
88  
89          assertEvalEquals("", "#foreach ($i in $nri)$i #end");             
90      }
91  
92      public void testVelocityHasNextProperty()
93          throws Exception
94      {
95          List list = new ArrayList();
96          list.add("test1");
97          list.add("test2");
98          list.add("test3");
99          context.put("list", list);
100         assertEvalEquals("test1 SEPARATOR test2 SEPARATOR test3 ", "#foreach ($value in $list)$value #if( $velocityHasNext )SEPARATOR #end#end");             
101     }    
102 
103     public void testNestedVelocityHasNextProperty()
104         throws Exception
105     {
106         List list = new ArrayList();
107         list.add("test1");
108         list.add("test2");
109         list.add("test3");
110         list.add("test4");
111         context.put("list", list);
112         List list2 = new ArrayList();
113         list2.add("a1");
114         list2.add("a2");
115         list2.add("a3");
116         context.put("list2", list2);
117 
118         assertEvalEquals("test1 (a1;a2;a3)-test2 (a1;a2;a3)-test3 (a1;a2;a3)-test4 (a1;a2;a3)", "#foreach ($value in $list)$value (#foreach ($val in $list2)$val#if( $velocityHasNext );#end#end)#if( $velocityHasNext )-#end#end");             
119     }    
120     
121     public static class MyIterable
122     {
123         private List foo;
124 
125         public MyIterable()
126         {
127             foo = new ArrayList();
128             foo.add(new Integer(1));
129             foo.add(new Long(2));
130             foo.add("3");
131         }
132         
133         public Iterator iterator()
134         {
135             return foo.iterator();
136         }
137     }
138 
139     public static class NotReallyIterable
140     {
141         public Object iterator()
142         {
143             return new Object();
144         }
145     }
146 
147 }