Hi,

Here is an addition to the Jelly tag library junit.  It includes the tag
<test:assertThrown/> which is used to assert that an exception is thrown by
its body.  The patch consists of the two attachments patch-java.txt and
patch-test.txt.  The first includes the class implementing the new tag and
the changes to the tag library class, whereas the second includes additions
to the junit tag library test suite to test the new tag.  For documentation
refer to the Javadoc and the examples in the test suite.

Cheers,

--
knut

Index: AssertThrownTag.java
===================================================================
RCS file: AssertThrownTag.java
diff -N AssertThrownTag.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ AssertThrownTag.java        28 Nov 2002 09:50:43 -0000
@@ -0,0 +1,160 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.commons.jelly.tags.junit;
+
+import org.apache.commons.jelly.XMLOutput;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Runs its body and asserts that an exception is thrown by it.  If no
+ * exception is thrown the tag fails.  By default all exceptions are caught.
+ * If however <code>expectedThrowable</code> was specified the body must throw
+ * an exception of the given class, otherwise the assertion fails.  The
+ * exception thrown by the body can also be of any subtype of the specified
+ * exception class.  The optional <code>var</code> attribute can be specified if
+ * the caught exception is to be exported to a variable.
+ */
+public class AssertThrownTag extends AssertTagSupport {
+
+       /** The Log to which logging calls will be made. */
+       private static final Log log = LogFactory.getLog(AssertThrownTag.class);
+
+       /**
+        * The variable name to export the caught exception to.
+        */
+       private String var;
+
+       /**
+        * The class name (fully qualified) of the exception expected to be thrown
+        * by the body.  Also a superclass of the expected exception can be given.
+        */
+       private String expectedThrowable;
+
+       // Tag interface
+       //-------------------------------------------------------------------------
+       public void doTag(XMLOutput output) throws Exception {
+               Class throwableClass = getThrowableClass();
+
+               try {
+                       invokeBody(output);
+               } catch (Throwable t) {
+                       if (var != null) {
+                               context.setVariable(var, t);
+                       }
+                       if (!throwableClass.isAssignableFrom(t.getClass())) {
+                               fail("Unexpected exception: " + t);
+                       } else {
+                               return;
+                       }
+               }
+               fail("No exception was thrown.");
+       }
+
+       // Properties
+       //-------------------------------------------------------------------------
+       /**
+        * Sets the class name of exception expected to be thrown by the body.  The
+        * class name must be fully qualified and can either be the expected
+        * exception class itself or any supertype of it, but must be a subtype of
+        * <code>java.lang.Throwable</code>.
+        */
+       public void setExpectedThrowable(String expectedThrowable) {
+               this.expectedThrowable = expectedThrowable;
+       }
+
+       /**
+        * Sets the variable name to define for this expression.
+        */
+       public void setVar(String var) {
+               this.var = var;
+       }
+
+       // Implementation methods
+       //-------------------------------------------------------------------------
+       /**
+        * Returns the <code>Class</code> corresponding to the class
+        * specified by <code>expectedThrowable</code>. If
+        * <code>expectedThrowable</code> was either not specified, couldn't be
+        * found or doesn't denote an exception class, then <code>java. lang.
+        * Throwable</code> is returned.
+        * 
+        * @return Class The class of the exception to expect
+        */
+       private Class getThrowableClass() {
+               if (expectedThrowable == null) {
+                       return Throwable.class;
+               }
+
+               Class throwableClass = null;
+               try {
+                       throwableClass = Class.forName(expectedThrowable);
+                       if (!Throwable.class.isAssignableFrom(throwableClass)) {
+                               log.warn(
+                                       "The class specified by expectedThrowable is 
+not an "
+                                               + "Exception class. Reverting to 
+java.lang.Throwable.");
+                               throwableClass = Throwable.class;
+                       }
+               } catch (ClassNotFoundException e) {
+                       log.warn(
+                               "The class specified by expectedThrowable could not be 
+found. "
+                                       + "Reverting to java.lang.Throwable.");
+                       throwableClass = Throwable.class;
+               }
+               return throwableClass;
+       }
+
+}
Index: JUnitTagLibrary.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/junit/JUnitTagLibrary.java,v
retrieving revision 1.5
diff -u -r1.5 JUnitTagLibrary.java
--- JUnitTagLibrary.java        8 Nov 2002 18:27:51 -0000       1.5
+++ JUnitTagLibrary.java        28 Nov 2002 09:50:43 -0000
@@ -90,6 +90,7 @@
     public JUnitTagLibrary() {
         registerTag("assert", AssertTag.class);
         registerTag("assertEquals", AssertEqualsTag.class);
+       registerTag("assertThrown", AssertThrownTag.class);
         registerTag("fail", FailTag.class);
         registerTag("run", RunTag.class );
         registerTag("case", CaseTag.class );
Index: suite.jelly
===================================================================
RCS file: 
/home/cvspublic/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/junit/suite.jelly,v
retrieving revision 1.6
diff -u -r1.6 suite.jelly
--- suite.jelly 13 Nov 2002 09:03:31 -0000      1.6
+++ suite.jelly 28 Nov 2002 09:52:16 -0000
@@ -50,6 +50,50 @@
        The exception was: ${ex.message}
   </test:case>
 
+
+  <test:case name="assertThrownTests">
+
+    <!-- test using var attribute -->
+    <test:assertThrown var="ex">
+      <test:fail message="This exeption should be exported"/>
+    </test:assertThrown>
+    <test:assertEquals actual="${ex.message}" expected="This exeption should be 
+exported">
+      Wrong message exported
+    </test:assertEquals>
+
+    <!-- test using superclass of expected throwable -->
+    <test:assertThrown expectedThrowable="java.lang.Error">
+      <test:fail message="This should always fail"/>
+    </test:assertThrown>
+
+    <!-- test using non exception class -->
+    <test:assertThrown expectedThrowable="java.lang.Class">
+      <test:fail message="This should always fail"/>
+    </test:assertThrown>
+
+    <!-- test using undefined class -->
+    <test:assertThrown expectedThrowable="foo.bar.Baz">
+      <test:fail message="This should always fail"/>
+    </test:assertThrown>
+
+    <!-- test using other exception class -->
+    <j:catch var="ex">
+      <test:assertThrown expectedThrowable="java.io.IOException">
+        <test:fail message="This should always fail"/>
+      </test:assertThrown>
+    </j:catch>
+       <test:assert test="${ex != null}">We should have created an 
+exception</test:assert>
+
+    <!-- test with no exception from body -->
+    <j:catch var="ex">
+      <test:assertThrown>
+      </test:assertThrown>
+    </j:catch>
+       <test:assert test="${ex != null}">We should have created an 
+exception</test:assert>
+    <test:assertEquals actual="${ex.message}" expected="No exception was thrown."/>
+
+  </test:case>
+
 <!--
        
        #### uncomment when assertEquals supports type conversions

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

Reply via email to