vmassol     2002/11/26 01:22:47

  Modified:    framework/src/java/j2ee13/org/apache/cactus/extension/jsp
                        JspTagLifecycle.java
               sample-servlet/src/unit/j2ee13/org/apache/cactus/unit
                        TestJspTagLifecycle.java
  Added:       framework/src/java/j2ee13/org/apache/cactus/extension/jsp
                        package.html
  Log:
  Patch from Chris Lenz for JspTagLifeCycle: fixed coding style, added lots of javadoc 
comments, some bug fixes.
  
  Revision  Changes    Path
  1.2       +122 -18   
jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/extension/jsp/JspTagLifecycle.java
  
  Index: JspTagLifecycle.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/extension/jsp/JspTagLifecycle.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JspTagLifecycle.java      24 Nov 2002 21:44:56 -0000      1.1
  +++ JspTagLifecycle.java      26 Nov 2002 09:22:47 -0000      1.2
  @@ -70,6 +70,109 @@
    * Convenience class that supports the testing of JSP tag by managing the tag's
    * lifecycle as required by the JSP specification.
    * 
  + * <p>
  + *   This class is basically a stub implementation of the tag management
  + *   facilities that an actual JSP container would provide. The implementation
  + *   attempts to follow the specification as closely as possible, but the tag
  + *   handling functionality of real JSP implementations may vary in some
  + *   details.
  + * </p>
  + * 
  + * <p>
  + *   Although this class works quite well when used in the test methods of a 
  + *   {@link org.apache.cactus.JspTestCase JspTestCase}, it can also safely be
  + *   used outside of the Cactus testing framework, for example when following
  + *   a mock objects approach.
  + * </p>
  + * 
  + * <h4>Testing Simple Tags</h4>
  + * <p>
  + *   This is how you would use this class when testing the
  + *   <code>&lt;c:set&gt;</code>-tag of the JSTL reference implementation:
  + *   <blockquote><pre>
  +  SetTag tag = new SetTag();
  +  JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +  tag.setVar("name");
  +  tag.setValue("value");
  +  lifecycle.invoke();
  +  assertEquals("value", pageContext.findAttribute("name"));</pre>
  + *   </blockquote>
  + *   The order is important:
  + *   <ol>
  + *     <li>
  + *       Instantiation of the tag under test
  + *     </li>
  + *     <li>
  + *       Instantiation of the lifecycle helper, passing in the page context,
  + *       the tag instance and optionally the parent tag
  + *     </li>
  + *     <li>
  + *       Set the tag's attributes
  + *     </li>
  + *     <li>
  + *       Start the tag's lifecycle by calling
  + *       {@link #invoke() JspTagLifecycle.invoke()}
  + *     </li>
  + *     <li>
  + *       Make assertions
  + *     </li>
  + *   </ol>
  + * </p>
  + * 
  + * <h4>Testing Iteration and Body Tags with Lifecycle Interceptors</h4>
  + * <p>
  + *   In the example above, the tag's lifecycle is simply run through from start
  + *   to finish. However, <code>JspTagLifecycle</code> also let's you get
  + *   <em>inside</em> significant phases of the tag's lifecycle. For this you
  + *   need to use the method
  + *   {@link #invoke(JspTagLifecycle.Interceptor) invoke(Interceptor)}
  + *   supplying a custom
  + *   {@link JspTagLifecycle.Interceptor Interceptor} implementation.
  + * </p>
  + * 
  + * <p>
  + *   This feature can be used to test iteration and body tags. The following 
  + *   code snippet is a simple example for testing the
  + *   <code>&lt;c:forEach&gt;</code>-tag of the JSTL reference implementation:
  + *   <blockquote><pre>
  +  ForEachTag tag = new ForEachTag();
  +  JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +  tag.setVar("item");
  +  tag.setItems("one,two,three");
  +  lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  +    public void evalBody(int iteration, BodyContent body) {
  +      String item = (String)pageContext.findAttribute("item");
  +      if (iteration == 0) {
  +        assertEquals("one", item);
  +      } else if (iteration == 1) {
  +        assertEquals("two", item);
  +      } else if (iteration == 2) {
  +        assertEquals("three", item);
  +      } else {
  +        fail("More iterations than expected!");
  +      }
  +    }
  +  });</pre>
  + * </blockquote></p>
  + * 
  + * <p>
  + *   To test a tag that does buffered evaluation of its body content, the 
  + *   {@link JspTagLifecycle.Interceptor#evalBody Interceptor.evalBody()} method
  + *   can be overridden to write the content that the tag will see. The following
  + *   example demonstrates this using the <code>&lt;c:out&gt;</code> tag:
  + *   <blockquote><pre>
  +  OutTag tag = new OutTag();
  +  JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +  tag.setValue(null);
  +  lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  +    public void evalBody(int iteration, BodyContent body)
  +        throws IOException {
  +        body.print("Default Value");
  +    }
  +  });
  +  </blockquote>
  + * </p>
  + * 
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christopher Lenz</a>
    * 
    * @version $Id$
  @@ -80,7 +183,10 @@
       // Inner Classes -----------------------------------------------------------
       
       /**
  -     *  
  +     * Abstract class for intercepting the tag lifecycle. You can override any
  +     * of the methods to insert assertions that verify the tag's behaviour while
  +     * it is being executed.
  +     * 
        * @author <a href="mailto:[EMAIL PROTECTED]";>Christopher Lenz</a>
        */
       public abstract static class Interceptor
  @@ -161,17 +267,19 @@
       public JspTagLifecycle(PageContext thePageContext, Tag theTag, 
           Tag theParent)
       {
  -        this.pageContext = thePageContext;
           this.tag = theTag;
  +        this.pageContext = thePageContext;
  +        tag.setPageContext(pageContext);
           this.parent = theParent;
  +        tag.setParent(parent);
       }
       
       // Public Methods ----------------------------------------------------------
       
       /**
  -     * Invokes the tag in the provided page context. The tag should have been
  -     * populated with its properties before calling this method. The tag is not
  -     * released after the tag's lifecycle is over.
  +     * Invokes the tag. The tag should have been populated with its properties
  +     * before calling this method. The tag is not released after the tag's
  +     * lifecycle is over.
        * 
        * @throws JspException If the tag throws an exception
        * @throws IOException If an error occurs when reading or writing the body
  @@ -183,12 +291,12 @@
       }
       
       /**
  -     * Invokes the tag in the provided page context. The tag should have been
  +     * Invokes the tag with the provided interceptor. The tag should have been
        * populated with its properties before calling this method. The tag is not
        * released after the tag's lifecycle is over.
        * 
        * @param theInterceptor The interceptor that will be notified about 
  -     *        lifecycle events
  +     *        important lifecycle events
        * @throws JspException If the tag throws an exception
        * @throws IOException If an error occurs when reading or writing the body
        *         content
  @@ -200,11 +308,7 @@
           {
               throw new NullPointerException();
           }
  -
  -        tag.setPageContext(pageContext);
  -        tag.setParent(parent);
           BodyContent body = null;
  -
           if (tag instanceof TryCatchFinally)
           {
               TryCatchFinally tryCatchFinally = (TryCatchFinally) tag;
  @@ -268,9 +372,9 @@
       {
           BodyContent body = null;
           int status = tag.doStartTag();
  -        if (status != Tag.SKIP_BODY)
  +        if (tag instanceof IterationTag)
           {
  -            if (tag instanceof IterationTag)
  +            if (status != Tag.SKIP_BODY)
               {
                   IterationTag iterationTag = (IterationTag) tag;
                   if ((status == BodyTag.EVAL_BODY_BUFFERED)
  @@ -289,10 +393,10 @@
                       iteration++;
                   } while (status == IterationTag.EVAL_BODY_AGAIN);
               }
  -        }
  -        else
  -        {
  -            theInterceptor.skipBody();
  +            else
  +            {
  +                theInterceptor.skipBody();
  +            }
           }
           status = tag.doEndTag();
           return body;
  
  
  
  1.1                  
jakarta-cactus/framework/src/java/j2ee13/org/apache/cactus/extension/jsp/package.html
  
  Index: package.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
  <html>
  <head>
  <title></title>
  </head>
  
  <body>
  
  <p>
    Contains utility classes to support unit testing of JSP tag libraries.
  </p>
  
  </body>
  </html>
  
  
  
  1.2       +164 -97   
jakarta-cactus/sample-servlet/src/unit/j2ee13/org/apache/cactus/unit/TestJspTagLifecycle.java
  
  Index: TestJspTagLifecycle.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-cactus/sample-servlet/src/unit/j2ee13/org/apache/cactus/unit/TestJspTagLifecycle.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestJspTagLifecycle.java  24 Nov 2002 21:44:55 -0000      1.1
  +++ TestJspTagLifecycle.java  26 Nov 2002 09:22:47 -0000      1.2
  @@ -71,21 +71,29 @@
   import org.apache.taglibs.standard.tag.el.core.WhenTag;
   
   /**
  + * Tests for the <code>JspTagLifecycle</code> extension.
    * 
  + * <p>
  + *   The lifecycle helper is tested here by testing the reference implementation
  + *   of the JSP standard tag library (JSTL), available at
  + *   <a href="http://jakarta.apache.org/taglibs/";>.
  + * </p>
    * 
    * @author <a href="mailto:[EMAIL PROTECTED]";>Christopher Lenz</a>
    */
   public class TestJspTagLifecycle
  -    extends JspTestCase {
  +    extends JspTestCase
  +{
       
       // Constructors ------------------------------------------------------------
       
       /**
  -     * Defines the testcase name for JUnit.
  -     *
  -     * @param theName the testcase's name.
  +     * Constructor.
  +     * 
  +     * @param theName The name of the test case
        */
  -    public TestJspTagLifecycle(String theName) {
  +    public TestJspTagLifecycle(String theName)
  +    {
           super(theName);
       }
       
  @@ -104,123 +112,153 @@
       // Test Methods ------------------------------------------------------------
       
       /**
  +     * Tests the <code>&lt;c:out&gt;</code>-tag with a proper, literal value for
  +     * it's <code>value</code> attribute.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testOutTag()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           OutTag tag = new OutTag();
  -        tag.setValue("TEST");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void evalBody(int iteration, BodyContent body) {
  -                assertEquals("TEST", body.getString());
  -            }
  -        });
  +        tag.setValue("Value");
  +        lifecycle.invoke();
       }
       
       /**
  +     * Verifies that the response has been correctly rendered by the 
  +     * <code>&lt;c:out&gt;</code>-tag.
        * 
  -     * @param theResponse
  +     * @param theResponse The HTTP response
        */
  -    public void endOutTag(WebResponse theResponse) {
  -        
  +    public void endOutTag(WebResponse theResponse)
  +    {
           String output = theResponse.getText();
  -        assertEquals("TEST", output);
  +        assertEquals("Value", output);
       }
       
       /**
  +     * Tests the <code>&lt;c:out&gt;</code>-tag with <code>null</code> for
  +     * it's <code>value</code> attribute, and a proper, literal value for it's
  +     * <code>default</code> attribute.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testOutTagDefaultAttribute()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           OutTag tag = new OutTag();
  -        tag.setValue(null);
  -        tag.setDefault("Default Value");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +        tag.setValue(null);
  +        tag.setDefault("Default");
           lifecycle.invoke();
       }
       
       /**
  -     * 
  -     * @param theResponse
  +     * Verifies that the response has been correctly rendered by the 
  +     * <code>&lt;c:out&gt;</code>-tag.
  +     *  
  +     * @param theResponse The HTTP response
        */
  -    public void endOutTagWithDefaultAttribute(WebResponse theResponse) {
  -        
  +    public void endOutTagWithDefaultAttribute(WebResponse theResponse)
  +    {
           String output = theResponse.getText();
  -        assertEquals("Default Value", output);
  +        assertEquals("Default", output);
       }
       
       /**
  +     * Tests the &lt;c:out&gt;-Tag with a value that evaluates to
  +     * <code>null</code>, and the default value specified in the tag's body.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testOutTagDefaultBody()
  -        throws JspException, IOException {
  -/*      
  +        throws JspException, IOException
  +    {
           OutTag tag = new OutTag();
  +        JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
           tag.setValue(null);
  -        new JspTagLifecycle(tag) {
  -            protected void evalBody(int iteration, BodyContent body)
  -                throws IOException {
  -                body.print("Default Value");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void evalBody(int iteration, BodyContent body)
  +                throws IOException
  +            {
  +                body.print("Default");
               }
  -        }.invoke(pageContext, null);*/
  +        });
       }
       
       /**
  +     * Verifies that the response has been correctly rendered by the 
  +     * <code>&lt;c:out&gt;</code>-tag.
        * 
  -     * @param theResponse
  +     * @param theResponse The HTTP response
  +     * @todo This test currently fails if commented in
        */
  -    public void endOutTagDefaultBody(WebResponse theResponse) {
  -/*        
  +    public void endOutTagDefaultBody(WebResponse theResponse)
  +    {
           String output = theResponse.getText();
  -        assertEquals("Default Value", output);*/
  +        //assertEquals("Default", output);
       }
       
       /**
  +     * Tests the &lt;c:set&gt;-tag with a proper, literal values for it's
  +     * <code>var</code> and <code>value</code> attributes. Verification is done
  +     * by checking the scoped variable stored by the tag.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testSetTag()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           SetTag tag = new SetTag();
  -        tag.setVar("name");
  -        tag.setValue("value");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +        tag.setVar("Var");
  +        tag.setValue("Value");
           lifecycle.invoke();
  -        assertEquals("value", pageContext.findAttribute("name"));
  +        assertEquals("Value", pageContext.findAttribute("Var"));
       }
       
       /**
  +     * Tests the tag &lt;c:forEach&gt; by providing a comma-delimited list of 
  +     * string to it's <code>items</code> attributes, and checking the exposed
  +     * scoped variable on every iteration step.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testForEachTag()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           ForEachTag tag = new ForEachTag();
  -        tag.setVar("item");
  -        tag.setItems("uno,dos,tres");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void evalBody(int iteration, BodyContent body) {
  -                if (iteration == 0) {
  -                    assertEquals("uno", pageContext.findAttribute("item"));
  -                } else if (iteration == 1) {
  -                    assertEquals("dos", pageContext.findAttribute("item"));
  -                } else if (iteration == 2) {
  -                    assertEquals("tres", pageContext.findAttribute("item"));
  -                } else {
  +        tag.setVar("Item");
  +        tag.setItems("One,Two,Three");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void evalBody(int iteration, BodyContent body)
  +            {
  +                String item = (String)pageContext.findAttribute("Item");
  +                assertNotNull(item);
  +                if (iteration == 0)
  +                {
  +                    assertEquals("One", item);
  +                }
  +                else if (iteration == 1)
  +                {
  +                    assertEquals("Two", item);
  +                }
  +                else if (iteration == 2)
  +                {
  +                    assertEquals("Three", item);
  +                }
  +                else
  +                {
                       fail("More iterations than expected!");
                   }
               }
  @@ -228,95 +266,124 @@
       }
       
       /**
  +     * Tests the conditional tag &lt;c:if&gt; by providing a proper, literal 
  +     * value to it's <code>test</code> attribute that evaluates to
  +     * the boolean value <code>true</code>. The test verifies the correct
  +     * behaviour by asserting that the tag's body is not skipped.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testIfTagTrue()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           IfTag tag = new IfTag();
  -        tag.setTest("true");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void skipBody() {
  +        tag.setTest("true");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void skipBody()
  +            {
                   fail("Body should have been evaluated!");
               }
           });
       }
       
       /**
  +     * Tests the conditional tag &lt;c:if&gt; by providing a proper, literal 
  +     * value to it's <code>test</code> attribute that evaluates to
  +     * the boolean value <code>false</code>. The test verifies the correct
  +     * behaviour by asserting that the tag's body is not evaluated.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testIfTagFalse()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           IfTag tag = new IfTag();
  -        tag.setTest("false");
           JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void evalBody(int iteration, BodyContent body) {
  +        tag.setTest("false");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void evalBody(int iteration, BodyContent body)
  +            {
                   fail("Body should have been skipped!");
               }
           });
       }
       
       /**
  +     * Tests the &lt;c:when&gt;-tag correctly nested inside a &lt;c:choose&gt;
  +     * tag, and providing a proper, literal value to it's <code>test</code>
  +     * attribute that evaluates to the boolean value <code>true</code>. The test
  +     * verifies the correct behaviour by asserting that the tag's body is not
  +     * skipped.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testWhenTag()
           throws JspException, IOException
       {
  -        
           WhenTag tag = new WhenTag();
  -        tag.setTest("true");
           JspTagLifecycle lifecycle =
               new JspTagLifecycle(pageContext, tag, new ChooseTag());
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void skipBody() {
  +        tag.setTest("true");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void skipBody()
  +            {
                   fail("Body should have been evaluated!");
               }
           });
       }
       
       /**
  +     * Tests the &lt;c:when&gt;-tag correctly nested inside a &lt;c:choose&gt;
  +     * tag, and providing a proper, literal value to it's <code>test</code>
  +     * attribute that evaluates to the boolean value <code>true</code>. However,
  +     * an earlier instance of the <code>&lt;c:when&gt;</code> tag nested in the
  +     * parent has already succeeded, so this test asserts that the body of the
  +     * later <code>&lt;c:when&gt;</code> does not get evaluated.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testWhenTagNoPermission()
           throws JspException, IOException
       {
  -        
           ChooseTag parent = new ChooseTag();
           parent.subtagSucceeded();
           WhenTag tag = new WhenTag();
  -        tag.setTest("true");
           JspTagLifecycle lifecycle =
               new JspTagLifecycle(pageContext, tag, parent);
  -        lifecycle.invoke(new JspTagLifecycle.Interceptor() {
  -            public void evalBody(int iteration, BodyContent body) {
  +        tag.setTest("true");
  +        lifecycle.invoke(new JspTagLifecycle.Interceptor()
  +        {
  +            public void evalBody(int iteration, BodyContent body)
  +            {
                   fail("Body should have been skipped!");
               }
           });
       }
       
       /**
  +     * Tests te <code>&lt;c:when&gt;</code> tag not nested inside a 
  +     * <code>&lt;c:choose&gt;</code> tag. The test expects a
  +     * <code>JspException</code> to be thrown.
        * 
  -     * @throws JspException
  -     * @throws IOException
  +     * @throws JspException If the tag throws a JSPException
  +     * @throws IOException If the tag throws an IOException
        */
       public void testWhenTagWithoutChooseTag()
  -        throws JspException, IOException {
  -        
  +        throws JspException, IOException
  +    {
           WhenTag tag = new WhenTag();
  +        JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
           tag.setTest("true");
  -        try {
  -            JspTagLifecycle lifecycle = new JspTagLifecycle(pageContext, tag);
  +        try
  +        {
               lifecycle.invoke();
               fail("Expected JSPTagException");
           } catch (JspTagException je) {
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to