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.StringWriter;
023: import java.io.Writer;
024:
025: import junit.framework.Test;
026: import junit.framework.TestCase;
027: import junit.framework.TestSuite;
028:
029: import org.apache.velocity.VelocityContext;
030: import org.apache.velocity.app.VelocityEngine;
031: import org.apache.velocity.app.event.EventCartridge;
032: import org.apache.velocity.app.event.InvalidReferenceEventHandler;
033: import org.apache.velocity.context.Context;
034: import org.apache.velocity.runtime.RuntimeConstants;
035: import org.apache.velocity.runtime.RuntimeServices;
036: import org.apache.velocity.util.RuntimeServicesAware;
037: import org.apache.velocity.util.introspection.Info;
038:
039: /**
040: * Tests event handling for all event handlers except IncludeEventHandler. This is tested
041: * separately due to its complexity.
042: *
043: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
044: * @version $Id: InvalidEventHandlerTestCase.java 463298 2006-10-12 16:10:32Z henning $
045: */
046: public class InvalidEventHandlerTestCase extends TestCase {
047: /**
048: * Default constructor.
049: */
050: public InvalidEventHandlerTestCase(String name) {
051: super (name);
052: }
053:
054: public static Test suite() {
055: return new TestSuite(InvalidEventHandlerTestCase.class);
056: }
057:
058: public void testManualEventHandlers() throws Exception {
059: TestEventCartridge te = new TestEventCartridge();
060:
061: /**
062: * Test attaching the event cartridge to the context
063: */
064: VelocityEngine ve = new VelocityEngine();
065: ve.init();
066:
067: /*
068: * lets make a Context and add the event cartridge
069: */
070:
071: VelocityContext inner = new VelocityContext();
072:
073: /*
074: * Now make an event cartridge, register all the
075: * event handlers (at once) and attach it to the
076: * Context
077: */
078:
079: EventCartridge ec = new EventCartridge();
080: ec.addEventHandler(te);
081: ec.attachToContext(inner);
082:
083: doTestInvalidReferenceEventHandler1(ve, inner);
084: doTestInvalidReferenceEventHandler2(ve, inner);
085: doTestInvalidReferenceEventHandler3(ve, inner);
086: doTestInvalidReferenceEventHandler4(ve, inner);
087: }
088:
089: /**
090: * Test assigning the event handlers via properties
091: */
092:
093: public void testConfigurationEventHandlers() throws Exception {
094: VelocityEngine ve = new VelocityEngine();
095: ve.setProperty(RuntimeConstants.EVENTHANDLER_INVALIDREFERENCES,
096: TestEventCartridge.class.getName());
097:
098: ve.init();
099: doTestInvalidReferenceEventHandler1(ve, null);
100: doTestInvalidReferenceEventHandler2(ve, null);
101: doTestInvalidReferenceEventHandler3(ve, null);
102: doTestInvalidReferenceEventHandler4(ve, null);
103: }
104:
105: /**
106: * Test deeper structures
107: * @param ve
108: * @param vc
109: * @throws Exception
110: */
111: private void doTestInvalidReferenceEventHandler4(VelocityEngine ve,
112: VelocityContext vc) throws Exception {
113: VelocityContext context = new VelocityContext(vc);
114:
115: Tree test = new Tree();
116: test.setField("10");
117: Tree test2 = new Tree();
118: test2.setField("12");
119: test.setChild(test2);
120:
121: context.put("tree", test);
122: String s;
123: Writer w;
124:
125: // show work fine
126: s = "$tree.Field $tree.field $tree.child.Field";
127: w = new StringWriter();
128: ve.evaluate(context, w, "mystring", s);
129:
130: s = "$tree.x $tree.field.x $tree.child.y $tree.child.Field.y";
131: w = new StringWriter();
132: ve.evaluate(context, w, "mystring", s);
133:
134: }
135:
136: /**
137: * Test invalid #set
138: * @param ve
139: * @param vc
140: * @throws Exception
141: */
142: private void doTestInvalidReferenceEventHandler3(VelocityEngine ve,
143: VelocityContext vc) throws Exception {
144: VelocityContext context = new VelocityContext(vc);
145: context.put("a1", new Integer(5));
146: context.put("a4", new Integer(5));
147: context.put("b1", "abc");
148:
149: String s;
150: Writer w;
151:
152: // good object, bad right hand side
153: s = "#set($xx = $a1.afternoon())";
154: w = new StringWriter();
155: try {
156: ve.evaluate(context, w, "mystring", s);
157: fail("Expected exception.");
158: } catch (RuntimeException e) {
159: }
160:
161: // good object, bad right hand reference
162: s = "#set($yy = $q1)";
163: w = new StringWriter();
164: try {
165: ve.evaluate(context, w, "mystring", s);
166: fail("Expected exception.");
167: } catch (RuntimeException e) {
168: }
169:
170: }
171:
172: /**
173: * Test invalid method calls
174: * @param ve
175: * @param vc
176: * @throws Exception
177: */
178: private void doTestInvalidReferenceEventHandler2(VelocityEngine ve,
179: VelocityContext vc) throws Exception {
180: VelocityContext context = new VelocityContext(vc);
181: context.put("a1", new Integer(5));
182: context.put("a4", new Integer(5));
183: context.put("b1", "abc");
184:
185: String s;
186: Writer w;
187:
188: // good object, bad method
189: s = "$a1.afternoon()";
190: w = new StringWriter();
191: try {
192: ve.evaluate(context, w, "mystring", s);
193: fail("Expected exception.");
194: } catch (RuntimeException e) {
195: }
196:
197: // bad object, bad method -- fails on get
198: s = "$zz.daylight()";
199: w = new StringWriter();
200: try {
201: ve.evaluate(context, w, "mystring", s);
202: fail("Expected exception.");
203: } catch (RuntimeException e) {
204: }
205:
206: // change result
207: s = "$b1.baby()";
208: w = new StringWriter();
209: ve.evaluate(context, w, "mystring", s);
210: assertEquals("www", w.toString());
211: }
212:
213: /**
214: * Test invalid gets/references
215: * @param ve
216: * @param vc
217: * @throws Exception
218: */
219: private void doTestInvalidReferenceEventHandler1(VelocityEngine ve,
220: VelocityContext vc) throws Exception {
221: String result;
222:
223: VelocityContext context = new VelocityContext(vc);
224: context.put("a1", new Integer(5));
225: context.put("a4", new Integer(5));
226: context.put("b1", "abc");
227:
228: // normal - should be no calls to handler
229: String s = "$a1 $a1.intValue() $b1 $b1.length() #set($c1 = '5')";
230: Writer w = new StringWriter();
231: ve.evaluate(context, w, "mystring", s);
232:
233: // good object, bad property
234: s = "$a1.foobar";
235: w = new StringWriter();
236: try {
237: ve.evaluate(context, w, "mystring", s);
238: fail("Expected exception.");
239: } catch (RuntimeException e) {
240: }
241:
242: // bad object, bad property
243: s = "$a2.foobar";
244: w = new StringWriter();
245: try {
246: ve.evaluate(context, w, "mystring", s);
247: fail("Expected exception.");
248: } catch (RuntimeException e) {
249: }
250:
251: // bad object, no property
252: s = "$a3";
253: w = new StringWriter();
254: try {
255: ve.evaluate(context, w, "mystring", s);
256: fail("Expected exception.");
257: } catch (RuntimeException e) {
258: }
259:
260: // good object, bad property; change the value
261: s = "$a4.foobar";
262: w = new StringWriter();
263: ve.evaluate(context, w, "mystring", s);
264: result = w.toString();
265: assertEquals("zzz", result);
266:
267: }
268:
269: /**
270: * Test assigning the event handlers via properties
271: */
272:
273: public static class TestEventCartridge implements
274: InvalidReferenceEventHandler, RuntimeServicesAware {
275: private RuntimeServices rs;
276:
277: public TestEventCartridge() {
278: }
279:
280: /**
281: * Required by EventHandler
282: */
283: public void setRuntimeServices(RuntimeServices rs) {
284: // make sure this is only called once
285: if (this .rs == null)
286: this .rs = rs;
287:
288: else
289: fail("initialize called more than once.");
290: }
291:
292: public Object invalidGetMethod(Context context,
293: String reference, Object object, String property,
294: Info info) {
295: // as a test, make sure this EventHandler is initialized
296: if (rs == null)
297: fail("Event handler not initialized!");
298:
299: // good object, bad property
300: if (reference.equals("$a1.foobar")) {
301: assertEquals(new Integer(5), object);
302: assertEquals("foobar", property);
303: throw new RuntimeException("expected exception");
304: }
305:
306: // bad object, bad property
307: else if (reference.equals("$a2")) {
308: assertNull(object);
309: assertNull(property);
310: throw new RuntimeException("expected exception");
311: }
312:
313: // bad object, no property
314: else if (reference.equals("$a3")) {
315: assertNull(object);
316: assertNull(property);
317: throw new RuntimeException("expected exception");
318: }
319:
320: // good object, bad property; change the value
321: else if (reference.equals("$a4.foobar")) {
322: assertEquals(new Integer(5), object);
323: assertEquals("foobar", property);
324: return "zzz";
325: }
326:
327: // bad object, bad method -- fail on the object
328: else if (reference.equals("$zz")) {
329: assertNull(object);
330: assertNull(property);
331: throw new RuntimeException("expected exception");
332: }
333:
334: // pass q1 through
335: else if (reference.equals("$q1")) {
336:
337: }
338:
339: else if (reference.equals("$tree.x")) {
340: assertEquals("x", property);
341: }
342:
343: else if (reference.equals("$tree.field.x")) {
344: assertEquals("x", property);
345: }
346:
347: else if (reference.equals("$tree.child.y")) {
348: assertEquals("y", property);
349: }
350:
351: else if (reference.equals("$tree.child.Field.y")) {
352: assertEquals("y", property);
353: }
354:
355: else {
356: fail("invalidGetMethod: unexpected reference: "
357: + reference);
358: }
359: return null;
360: }
361:
362: public Object invalidMethod(Context context, String reference,
363: Object object, String method, Info info) {
364: // as a test, make sure this EventHandler is initialized
365: if (rs == null)
366: fail("Event handler not initialized!");
367:
368: // good reference, bad method
369: if (object.getClass().equals(Integer.class)) {
370: assertEquals("$a1.afternoon()", reference);
371: assertEquals("afternoon", method);
372: throw new RuntimeException("expected exception");
373: }
374:
375: else if (object.getClass().equals(String.class)
376: && "baby".equals(method)) {
377: return "www";
378: }
379:
380: else {
381: fail("Unexpected invalid method. " + method);
382: }
383:
384: return null;
385: }
386:
387: public boolean invalidSetMethod(Context context,
388: String leftreference, String rightreference, Info info) {
389:
390: // as a test, make sure this EventHandler is initialized
391: if (rs == null)
392: fail("Event handler not initialized!");
393:
394: // good object, bad method
395: if (leftreference.equals("xx")) {
396: assertEquals("q1.afternoon()", rightreference);
397: throw new RuntimeException("expected exception");
398: }
399: if (leftreference.equals("yy")) {
400: assertEquals("$q1", rightreference);
401: throw new RuntimeException("expected exception");
402: } else {
403: fail("Unexpected left hand side. " + leftreference);
404: }
405:
406: return false;
407: }
408:
409: }
410:
411: public static class Tree {
412: String field;
413: Tree child;
414:
415: public Tree() {
416:
417: }
418:
419: public String getField() {
420: return field;
421: }
422:
423: public void setField(String field) {
424: this .field = field;
425: }
426:
427: public Tree getChild() {
428: return child;
429: }
430:
431: public void setChild(Tree child) {
432: this .child = child;
433: }
434:
435: public String testMethod() {
436: return "123";
437: }
438: }
439:
440: }
|