001: package org.apache.velocity.test;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.BufferedWriter;
023: import java.io.FileOutputStream;
024: import java.io.OutputStreamWriter;
025: import java.io.Writer;
026: import java.util.ArrayList;
027: import java.util.HashMap;
028: import java.util.Hashtable;
029: import java.util.Vector;
030:
031: import org.apache.velocity.Template;
032: import org.apache.velocity.VelocityContext;
033: import org.apache.velocity.app.FieldMethodizer;
034: import org.apache.velocity.runtime.RuntimeSingleton;
035: import org.apache.velocity.test.provider.BoolObj;
036: import org.apache.velocity.test.provider.NullToStringObject;
037: import org.apache.velocity.test.provider.TestNumber;
038: import org.apache.velocity.test.provider.TestProvider;
039:
040: /**
041: * Easily add test cases which evaluate templates and check their output.
042: *
043: * NOTE:
044: * This class DOES NOT extend RuntimeTestCase because the TemplateTestSuite
045: * already initializes the Velocity runtime and adds the template
046: * test cases. Having this class extend RuntimeTestCase causes the
047: * Runtime to be initialized twice which is not good. I only discovered
048: * this after a couple hours of wondering why all the properties
049: * being setup were ending up as Vectors. At first I thought it
050: * was a problem with the Configuration class, but the Runtime
051: * was being initialized twice: so the first time the property
052: * is seen it's stored as a String, the second time it's seen
053: * the Configuration class makes a Vector with both Strings.
054: * As a result all the getBoolean(property) calls were failing because
055: * the Configurations class was trying to create a Boolean from
056: * a Vector which doesn't really work that well. I have learned
057: * my lesson and now have to add some code to make sure the
058: * Runtime isn't initialized more then once :-)
059: *
060: * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
061: * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
062: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
063: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
064: * @version $Id: TemplateTestCase.java 463298 2006-10-12 16:10:32Z henning $
065: */
066: public class TemplateTestCase extends BaseTestCase implements
067: TemplateTestBase {
068: /**
069: * The base file name of the template and comparison file (i.e. array for
070: * array.vm and array.cmp).
071: */
072: protected String baseFileName;
073:
074: private TestProvider provider;
075: private ArrayList al;
076: private Hashtable h;
077: private VelocityContext context;
078: private VelocityContext context1;
079: private VelocityContext context2;
080: private Vector vec;
081:
082: /**
083: * Creates a new instance.
084: *
085: * @param baseFileName The base name of the template and comparison file to
086: * use (i.e. array for array.vm and array.cmp).
087: */
088: public TemplateTestCase(String baseFileName) {
089: super (getTestCaseName(baseFileName));
090: this .baseFileName = baseFileName;
091: }
092:
093: public static junit.framework.Test suite() {
094: return new TemplateTestSuite();
095: }
096:
097: /**
098: * Sets up the test.
099: */
100: protected void setUp() {
101: provider = new TestProvider();
102: al = provider.getCustomers();
103: h = new Hashtable();
104:
105: h.put("Bar", "this is from a hashtable!");
106: h.put("Foo", "this is from a hashtable too!");
107:
108: /*
109: * lets set up a vector of objects to test late introspection. See ASTMethod.java
110: */
111:
112: vec = new Vector();
113:
114: vec.addElement(new String("string1"));
115: vec.addElement(new String("string2"));
116:
117: /*
118: * set up 3 chained contexts, and add our data
119: * throught the 3 of them.
120: */
121:
122: context2 = new VelocityContext();
123: context1 = new VelocityContext(context2);
124: context = new VelocityContext(context1);
125:
126: context.put("provider", provider);
127: context1.put("name", "jason");
128: context1.put("name2", new StringBuffer("jason"));
129: context1.put("name3", new StringBuffer("geoge"));
130: context2.put("providers", provider.getCustomers2());
131: context.put("list", al);
132: context1.put("hashtable", h);
133: context2.put("hashmap", new HashMap());
134: context2.put("search", provider.getSearch());
135: context.put("relatedSearches", provider.getRelSearches());
136: context1.put("searchResults", provider.getRelSearches());
137: context2.put("stringarray", provider.getArray());
138: context.put("vector", vec);
139: context.put("mystring", new String());
140: context.put("runtime", new FieldMethodizer(
141: "org.apache.velocity.runtime.RuntimeSingleton"));
142: context.put("fmprov", new FieldMethodizer(provider));
143: context.put("Floog", "floogie woogie");
144: context.put("boolobj", new BoolObj());
145:
146: /*
147: * we want to make sure we test all types of iterative objects
148: * in #foreach()
149: */
150:
151: Object[] oarr = { "a", "b", "c", "d" };
152: int intarr[] = { 10, 20, 30, 40, 50 };
153:
154: context.put("collection", vec);
155: context2.put("iterator", vec.iterator());
156: context1.put("map", h);
157: context.put("obarr", oarr);
158: context.put("enumerator", vec.elements());
159: context.put("intarr", intarr);
160:
161: // Add some Numbers
162: context.put("int1", new Integer(1000));
163: context.put("long1", new Long(10000000000l));
164: context.put("float1", new Float(1000.1234));
165: context.put("double1", new Double(10000000000d));
166:
167: // Add a TemplateNumber
168: context.put("templatenumber1", new TestNumber(999.125));
169:
170: /**
171: * Test #foreach() with a list containing nulls
172: */
173: ArrayList nullList = new ArrayList();
174: nullList.add("a");
175: nullList.add("b");
176: nullList.add(null);
177: nullList.add("d");
178: context.put("nullList", nullList);
179:
180: // test silent references with a null tostring
181: context.put("nullToString", new NullToStringObject());
182: }
183:
184: /**
185: * Runs the test.
186: */
187: public void runTest() throws Exception {
188: Template template = RuntimeSingleton.getTemplate(getFileName(
189: null, baseFileName, TMPL_FILE_EXT));
190:
191: assureResultsDirectoryExists(RESULT_DIR);
192:
193: /* get the file to write to */
194: FileOutputStream fos = new FileOutputStream(getFileName(
195: RESULT_DIR, baseFileName, RESULT_FILE_EXT));
196:
197: Writer writer = new BufferedWriter(new OutputStreamWriter(fos));
198:
199: /* process the template */
200: template.merge(context, writer);
201:
202: /* close the file */
203: writer.flush();
204: writer.close();
205:
206: if (!isMatch(RESULT_DIR, COMPARE_DIR, baseFileName,
207: RESULT_FILE_EXT, CMP_FILE_EXT)) {
208: fail("Processed template did not match expected output");
209: }
210: }
211: }
|