Clover coverage report - JFCUnit Test Coverage
Coverage timestamp: Mon Dec 20 2004 23:38:10 MST
file stats: LOC: 484   Methods: 23
NCLOC: 231   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
JFCXMLTestCase.java 52.6% 63.9% 73.9% 62.7%
coverage coverage
 1   
 package junit.extensions.jfcunit.xml;
 2   
 
 3   
 import junit.extensions.jfcunit.JFCTestCase;
 4   
 import junit.extensions.jfcunit.JFCTestHelper;
 5   
 import junit.extensions.jfcunit.RobotTestHelper;
 6   
 
 7   
 import junit.extensions.xml.IXMLProcedure;
 8   
 import junit.extensions.xml.IXMLTest;
 9   
 import junit.extensions.xml.IXMLTestCase;
 10   
 import junit.extensions.xml.XMLException;
 11   
 import junit.extensions.xml.XMLObjectCache;
 12   
 import junit.extensions.xml.XMLTagResourceBundle;
 13   
 import junit.extensions.xml.XMLTestSuite;
 14   
 import junit.extensions.xml.XMLUtil;
 15   
 
 16   
 import junit.framework.Test;
 17   
 
 18   
 import org.w3c.dom.Attr;
 19   
 import org.w3c.dom.Element;
 20   
 import org.w3c.dom.NamedNodeMap;
 21   
 import org.w3c.dom.NodeList;
 22   
 
 23   
 import java.awt.AWTException;
 24   
 
 25   
 
 26   
 /**
 27   
  * This class will handle the processing of <test> nodes.
 28   
  *
 29   
  * <h3>Description</h3>
 30   
  * <p>
 31   
  *   This tag handler invokes the test case given.
 32   
  * </p>
 33   
  *
 34   
  * <h3>Attributes</h3>
 35   
  * <table border="1" cellpadding="2" cellspacing="0">
 36   
  *   <tr>
 37   
  *     <td valign="top"><b>Attribute</b></td>
 38   
  *     <td valign="top"><b>Description</b></td>
 39   
  *     <td align="center" valign="top"><b>Required</b></td>
 40   
  *     <td valign="top"><b>Default</b></td>
 41   
  *     <td valign="top"><b>Values</b></td>
 42   
  *   </tr>
 43   
  *   <tr>
 44   
  *     <td valign="top">name</td>
 45   
  *     <td valign="top">name of the test case</td>
 46   
  *     <td valign="top" align="center">Yes</td>
 47   
  *     <td valign="top">N/A</td>
 48   
  *     <td valign="top">Alpha Numeric Name</td>
 49   
  *   </tr>
 50   
  *   <tr>
 51   
  *     <td valign="top">robot</td>
 52   
  *     <td valign="top">Use a robot or send events directly to AWT Event queue.</td>
 53   
  *     <td valign="top" align="center">No</td>
 54   
  *     <td valign="top">false</td>
 55   
  *     <td valign="top">true if events are to be sent via the Robot</td>
 56   
  *   </tr>
 57   
  *   <tr>
 58   
  *     <td valign="top">assertexit</td>
 59   
  *     <td valign="top">
 60   
  *         Assert the System.exit() command, ExitException will be
 61   
  *         thrown by the security manager and the application will not exit.
 62   
  *     </td>
 63   
  *     <td valign="top" align="center">No</td>
 64   
  *     <td valign="top">false</td>
 65   
  *     <td valign="top">true if the system exist should be asserted.</td>
 66   
  *   </tr>
 67   
  * </table>
 68   
  * <h3>Example</h3>
 69   
  * <pre>
 70   
  * &lt;test name="Login"&gt
 71   
  * ...
 72   
  * &lt;/test&gt;
 73   
  * &lt;test name="Logout" assertexit="true"&gt;
 74   
  * ...
 75   
  * &lt;/test&gt;
 76   
  * </pre>
 77   
  * <p>
 78   
  * The above runs the defined testcase.
 79   
  * </p>
 80   
  * @author Kevin Wilson
 81   
  */
 82   
 public class JFCXMLTestCase extends JFCTestCase implements IXMLTestCase,
 83   
     JFCXMLConstants {
 84   
     /**
 85   
      * The element to be processed.
 86   
      */
 87   
     private Element m_element;
 88   
 
 89   
     /**
 90   
      * The name of the test xml script file - found from the classpath.
 91   
      */
 92   
     private String m_filename;
 93   
 
 94   
     /**
 95   
      * Parent test case.
 96   
      */
 97   
     private Test m_parent;
 98   
 
 99   
     /**
 100   
      * Map of procedures.
 101   
      */
 102   
     private XMLObjectCache m_procedures = new XMLObjectCache();
 103   
 
 104   
     /**
 105   
      * A Map of all objects that have been found - keyed by the string name.
 106   
      */
 107   
     private XMLObjectCache m_properties = new XMLObjectCache();
 108   
 
 109   
     /**
 110   
      * The default constructor that is needed to createa a test case.
 111   
      *
 112   
      * @param filename    The name of the test xml script file (found from the classpath)
 113   
      * @param element     The Element to be processed
 114   
      */
 115  614
     public JFCXMLTestCase(final String filename, final Element element) {
 116  614
         super(filename);
 117  614
         m_filename     = filename;
 118  614
         m_element      = element;
 119   
 
 120  614
         boolean robot  = XMLUtil.getBooleanAttributeValue(element, ROBOT);
 121   
 
 122  614
         if (robot) {
 123  9
             try {
 124  9
                 setHelper(new RobotTestHelper());
 125   
             } catch (AWTException ex) {
 126  0
                 throw new RuntimeException("Could not create robot." + ex);
 127   
             }
 128   
         } else {
 129  605
             setHelper(new JFCTestHelper());
 130   
         }
 131   
 
 132  614
         boolean assertExit = XMLUtil.getBooleanAttributeValue(element,
 133   
                 ASSERTEXIT);
 134  614
         setAssertExit(assertExit);
 135   
     }
 136   
 
 137   
     /**
 138   
      * Get the debug state.
 139   
      * @return boolean true if debugging has been enabled.
 140   
      */
 141  1209
     public final boolean getDebug() {
 142  1209
         return (m_properties.get(DEBUG) != null);
 143   
     }
 144   
 
 145   
     /**
 146   
      * Set the parent test case.
 147   
      * @param parent Parent test case.
 148   
      */
 149  614
     public final void setParent(final IXMLTest parent) {
 150  614
         this.m_parent = parent;
 151  614
         m_properties.setParent(((IXMLTest) parent).getPropertyCache());
 152  614
         m_procedures.setParent(((IXMLTest) parent).getProcedureCache());
 153   
     }
 154   
 
 155   
     /**
 156   
      * Get the procedure withthe given name.
 157   
      * @param name Name of the procedure to return.
 158   
      * @return IXMLProcedure referenced by name.
 159   
      */
 160  76
     public final IXMLProcedure getProcedure(final String name) {
 161  76
         return (IXMLProcedure) m_procedures.get(name);
 162   
     }
 163   
 
 164   
     /**
 165   
      * Returns the cahce of procedures.
 166   
      * @return XMLObjectCache cache of procedures.
 167   
      */
 168  0
     public final XMLObjectCache getProcedureCache() {
 169  0
         return m_procedures;
 170   
     }
 171   
 
 172   
     /**
 173   
      * Retrieve the object that was found previously.
 174   
      *
 175   
      * @param name    The name of the object that was found
 176   
      * @return    The object to be retrieved
 177   
      */
 178  869
     public final Object getProperty(final String name) {
 179  869
         return m_properties.get(name);
 180   
     }
 181   
 
 182   
     /**
 183   
      * Get the property cache.
 184   
      * @return XMLObjectCache used to hold the properties.
 185   
      */
 186  2
     public final XMLObjectCache getPropertyCache() {
 187  2
         return m_properties;
 188   
     }
 189   
 
 190   
     /**
 191   
      * Get the name of a component which has been found.
 192   
      * @param comp Component to locate
 193   
      * @return The name of the component.
 194   
      */
 195  0
     public final String getPropertyName(final Object comp) {
 196  0
         return m_properties.getName(comp);
 197   
     }
 198   
 
 199   
     /**
 200   
      * Get the names of the properties.
 201   
      * @return array containing the names of the properties.
 202   
      */
 203  0
     public final String[] getPropertyNames() {
 204  0
         return m_properties.getNames();
 205   
     }
 206   
 
 207   
     /**
 208   
      * Add a procedure to the test case.
 209   
      * @param proc Procedure to be added.
 210   
      */
 211  0
     public final void addProcedure(final IXMLProcedure proc) {
 212  0
         m_procedures.put(
 213   
             proc.getName(),
 214   
             proc);
 215   
     }
 216   
 
 217   
     /**
 218   
      * Call the procedure with the given name.
 219   
      * @param name Name of the procedure.
 220   
      * @param callElement Element which contains the attributes to
 221   
      * be passed to the procedures.
 222   
      * @throws XMLException is thrown if the element cannot be understood.
 223   
      */
 224  76
     public final void callProcedure(final String name, final Element callElement)
 225   
         throws XMLException {
 226  76
         XMLObjectCache cache = m_properties;
 227  76
         m_properties = new XMLObjectCache();
 228  76
         m_properties.setParent(cache);
 229   
 
 230  76
         if (callElement != null) {
 231  0
             NamedNodeMap atts = callElement.getAttributes();
 232  0
             int          size = atts.getLength();
 233   
 
 234  0
             for (int i = 0; i < size; i++) {
 235  0
                 Attr   node = (Attr) atts.item(i);
 236  0
                 String an = node.getName();
 237   
 
 238  0
                 if (!CALL.equals(an)) {
 239  0
                     String value = XMLUtil.getAttribute(callElement, an);
 240  0
                     value = this.resolveProperties(value);
 241  0
                     addProperty(an, value);
 242   
                 }
 243   
             }
 244   
         }
 245   
 
 246  76
         IXMLProcedure proc = getProcedure(name);
 247   
 
 248  76
         if (proc == null) {
 249  76
             m_properties.setParent(null);
 250  76
             m_properties = cache;
 251   
 
 252  76
             if ("setUp".equals(name) || "tearDown".equals(name)) {
 253  76
                 return;
 254   
             }
 255   
 
 256  0
             throw new XMLException("Procedure not found:" + name, null,
 257   
                 m_element,
 258   
                 getPropertyCache());
 259   
         }
 260   
 
 261  0
         this.processChildren(proc.getElement());
 262  0
         m_properties.setParent(null);
 263  0
         m_properties = cache;
 264   
     }
 265   
 
 266   
     /**
 267   
      * Process the child XML elements.
 268   
      * @param element Element which contains the children to
 269   
      * be processed.
 270   
      * @throws XMLException may be thrown.
 271   
      */
 272  42
     public final void processChildren(final Element element)
 273   
         throws XMLException {
 274   
         // Get the children and add to the suite.
 275  42
         NodeList children = element.getChildNodes();
 276  42
         Element  child;
 277   
 
 278  42
         for (int i = 0; i < children.getLength(); i++) {
 279  1278
             if (children.item(i) instanceof Element) {
 280  612
                 child = (Element) children.item(i);
 281   
 
 282  612
                 String name = child.getTagName();
 283   
 
 284  612
                 try {
 285  612
                     XMLTagResourceBundle.getTagHandler(child, this, name)
 286   
                                         .processElement();
 287   
                 } catch (XMLException xe) {
 288  0
                     throw xe;
 289   
                 } catch (Throwable t) {
 290   
                     // Wrap into a XMLException and throw.
 291  0
                     XMLException x = new XMLException("Exception ("
 292   
                             + t.toString() + " from tag: " + name, t, child,
 293   
                             getPropertyCache());
 294  0
                     throw x;
 295   
                 }
 296   
 
 297  612
                 if (child != children.item(i)) {
 298  0
                     for (;
 299  0
                             (child != children.item(i))
 300   
                             && (i < children.getLength()); i++) {
 301   
                         ;
 302   
                     }
 303   
 
 304  0
                     if (i == children.getLength()) {
 305  0
                         throw new junit.extensions.xml.XMLException("Lost where we were at current node was removed.",
 306   
                             null,
 307   
                             child,
 308   
                             getPropertyCache());
 309   
                     }
 310   
                 }
 311   
             }
 312   
         }
 313   
     }
 314   
 
 315   
     /**
 316   
      * This method is the one that actually performs the test by processing the elements.
 317   
      *
 318   
      * @exception  Exception   An instance of java.lang.Exception can be thrown.
 319   
      */
 320  38
     public final void runXMLTest() throws Exception {
 321  38
         boolean debug = XMLUtil.getBooleanAttributeValue(m_element, DEBUG);
 322   
 
 323  38
         if (debug) {
 324  0
             m_properties.put(DEBUG, Boolean.TRUE);
 325   
         } else {
 326  38
             m_properties.remove(DEBUG);
 327   
         }
 328   
 
 329  38
         processChildren(m_element);
 330   
     }
 331   
 
 332   
     /**
 333   
      * Returns an empty suite.
 334   
      *
 335   
      * @return Test   An empty XMLTestSuite is returned by default
 336   
      * @exception  Exception   An instance of java.lang.Exception can be thrown.
 337   
      */
 338  0
     public static Test suite() throws Exception {
 339  0
         return new XMLTestSuite();
 340   
     }
 341   
 
 342   
     /**
 343   
      * Add each found object into the cache map.
 344   
      *
 345   
      * @param name    The name of the found object
 346   
      * @param obj     The actual object that was found
 347   
      */
 348  165
     public final void addProperty(final String name, final Object obj) {
 349  165
         m_properties.put(name, obj);
 350   
     }
 351   
 
 352   
     /**
 353   
      * For each test (method) element, the found objects has to be cleared.
 354   
      */
 355  38
     public final void clearProperties() {
 356  38
         m_properties.clear();
 357   
     }
 358   
 
 359   
     /**
 360   
      * Remove the property with the name given.
 361   
      *
 362   
      * @param name Name of the object to be removed
 363   
      */
 364  0
     public final void removeProperty(final String name) {
 365  0
         m_properties.remove(name);
 366   
     }
 367   
 
 368   
     /**
 369   
      * Resolve embeded property names withing a string.
 370   
      * @param s String to be resolved.
 371   
      * @return String without property names.
 372   
      */
 373  5417
     public String resolveProperties(final String s) {
 374  5417
         if (s == null) {
 375  2628
             return null;
 376   
         }
 377   
 
 378  2789
         int    index = -1;
 379  2789
         String str = new String(s);
 380   
 
 381  2789
         do {
 382  2789
             index = str.lastIndexOf("${");
 383   
 
 384  2789
             if (index != -1) {
 385  0
                 int    lindex = str.indexOf("}", index);
 386   
 
 387  0
                 String variableName = str.substring(index + 2, lindex);
 388  0
                 assertTrue("Evaluation of \"" + str + "\" Null Variable name.",
 389   
                     variableName.length() > 0);
 390   
 
 391  0
                 Object value = getProperty(variableName);
 392   
 
 393  0
                 if (value == null) {
 394  0
                     System.err.println("WARNING: Evaluation of \"" + s
 395   
                         + "\" Variable not found assuming empty string for:"
 396   
                         + variableName);
 397  0
                     value = "";
 398   
                 }
 399   
 
 400  0
                 String valueString = value.toString();
 401  0
                 str = str.substring(0, index) + valueString
 402   
                     + str.substring(lindex + 1);
 403   
             }
 404  2789
         } while (index != -1);
 405   
 
 406  2789
         return str;
 407   
     }
 408   
 
 409   
     /**
 410   
      * Default setUp which does nothing. Override this to set up the environment
 411   
      * for your test
 412   
      *
 413   
      * @exception  Exception   An instance of java.lang.Exception can be thrown
 414   
      * @see junit.framework.TestCase#setUp()
 415   
      */
 416  38
     protected void setUp() throws Exception {
 417  38
         super.setUp();
 418  38
         clearProperties();
 419  38
         m_procedures.clear();
 420  38
         loadProcedures(m_element);
 421   
 
 422   
         // Call the startup procedure
 423  38
         callProcedure("setUp", null);
 424   
     }
 425   
 
 426   
     /**
 427   
      * Executes a test.
 428   
      *
 429   
      * @exception Throwable exceptions thrown by code.
 430   
      */
 431  38
     protected void runTest() throws Throwable {
 432  38
         runCode(
 433   
             new Runnable() {
 434  38
                 public void run() {
 435  38
                     try {
 436  38
                         runXMLTest();
 437  38
                         flushAWT();
 438   
                     } catch (Exception exc) {
 439  0
                         flushAWT();
 440  0
                         setError(exc);
 441   
                     }
 442   
                 }
 443   
             });
 444   
     }
 445   
 
 446   
     /**
 447   
      * Default tearDown which does nothing. Override this to tear down the
 448   
      * environment for your test.
 449   
      *
 450   
      * @exception  Exception   An instance of java.lang.Exception can be thrown
 451   
      * @see junit.framework.TestCase#setUp()
 452   
      */
 453  38
     protected void tearDown() throws Exception {
 454  38
         callProcedure("tearDown", null);
 455  38
         super.tearDown();
 456   
     }
 457   
 
 458   
     /**
 459   
      * Process the child XML elements.
 460   
      * @param element Element which contains the children to
 461   
      * be processed.
 462   
      * @throws XMLException is thrown if the element cannot be understood.
 463   
      */
 464  38
     private void loadProcedures(final Element element) throws XMLException {
 465   
         // Get the children and add to the suite.
 466  38
         NodeList children = element.getChildNodes();
 467  38
         Element  child;
 468   
 
 469  38
         for (int i = 0; i < children.getLength(); i++) {
 470  1266
             if (children.item(i) instanceof Element) {
 471  608
                 child = (Element) children.item(i);
 472   
 
 473  608
                 String name = child.getTagName();
 474  608
                 String call = child.getAttribute(CALL);
 475   
 
 476  608
                 if (PROCEDURE.equals(name) && (call.length() == 0)) {
 477  0
                     XMLTagResourceBundle.getTagHandler(child, this, name)
 478   
                                         .processElement();
 479   
                 }
 480   
             }
 481   
         }
 482   
     }
 483   
 }
 484