Clover coverage report - JFCUnit Test Coverage
Coverage timestamp: Mon Dec 20 2004 23:38:10 MST
file stats: LOC: 577   Methods: 27
NCLOC: 271   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractEventData.java 62.5% 55.9% 85.2% 60.8%
coverage coverage
 1   
 package junit.extensions.jfcunit.eventdata;
 2   
 
 3   
 import junit.extensions.jfcunit.JFCTestCase;
 4   
 import junit.extensions.jfcunit.xml.JFCXMLConstants;
 5   
 
 6   
 import java.applet.Applet;
 7   
 
 8   
 import java.awt.AWTEvent;
 9   
 import java.awt.Component;
 10   
 import java.awt.Point;
 11   
 import java.awt.Rectangle;
 12   
 import java.awt.Window;
 13   
 import java.awt.event.KeyEvent;
 14   
 
 15   
 import javax.swing.JComponent;
 16   
 
 17   
 
 18   
 /**
 19   
  * Abstract data container class that holds most of the
 20   
  * data necessary for jfcUnit to fire events.
 21   
  *
 22   
  * @author <a href="mailto:vraravam@thoughtworks.com">Vijay Aravamudhan : ThoughtWorks Inc.</a>
 23   
  */
 24   
 public abstract class AbstractEventData implements EventDataConstants {
 25   
     /**
 26   
      * The {@link JFCTestCase} on whose thread <code>awtSleep()</code>
 27   
      * has to be invoked.
 28   
      */
 29   
     private JFCTestCase m_testCase;
 30   
 
 31   
     /**
 32   
      * The reference point to place the mouse. Either custom set or
 33   
      * derived from the screen location.
 34   
      */
 35   
     private Point m_referencePoint;
 36   
 
 37   
     /**
 38   
      * The screen location to place the mouse.
 39   
      */
 40   
     private Point m_screenLocation;
 41   
 
 42   
     /**
 43   
      * State of event data. If invalid then data has not been loaded
 44   
      * into the event yet.
 45   
      */
 46   
     private boolean m_valid;
 47   
 
 48   
     /**
 49   
      * The modifier key values that need to be passed onto the event.
 50   
      */
 51   
     private int m_modifiers;
 52   
 
 53   
     /**
 54   
      * The position to place the mouse within the component.
 55   
      */
 56   
     private int m_position;
 57   
 
 58   
     /**
 59   
      * The wait time in ms between each event.
 60   
      */
 61   
     private long m_sleepTime;
 62   
 
 63   
     /**
 64   
      * Set the attribute value.
 65   
      *
 66   
      * @param testCase The new value of the attribute
 67   
      */
 68  2193
     public final void setTestCase(final JFCTestCase testCase) {
 69  2193
         m_testCase = testCase;
 70   
     }
 71   
 
 72   
     /**
 73   
      * Get the attribute value.
 74   
      *
 75   
      * @return JFCTestCase    The value of the attribute
 76   
      */
 77  8179
     public final JFCTestCase getTestCase() {
 78  8179
         return m_testCase;
 79   
     }
 80   
 
 81   
     /**
 82   
      * The source {@link java.awt.Component} on which the event has
 83   
      * to be fired.
 84   
      *
 85   
      * @return The source {@link java.awt.Component}
 86   
      */
 87   
     public abstract Component getComponent();
 88   
 
 89   
     /**
 90   
      * Get the default position.
 91   
      * @return Default position.
 92   
      */
 93  0
     public int getDefaultPosition() {
 94  0
         return EventDataConstants.DEFAULT_POSITION;
 95   
     }
 96   
 
 97   
     /**
 98   
      * Get the default sleep time.
 99   
      * @return ms sleep time.
 100   
      */
 101  1144
     public long getDefaultSleepTime() {
 102  1144
         return EventDataConstants.DEFAULT_SLEEPTIME;
 103   
     }
 104   
 
 105   
     /**
 106   
      * Get the screen location for the event.
 107   
      * @return Point screen location for the event.
 108   
      */
 109  1818
     public final Point getLocationOnScreen() {
 110  1818
         return m_screenLocation;
 111   
     }
 112   
 
 113   
     /**
 114   
      * Returns true if the keyCode refers to a meta character.
 115   
      *
 116   
      * @param keyCode code to be checked.
 117   
      * @return boolean true if the keyCode is a meta key.
 118   
      */
 119  1223
     public final boolean isMetaChar(final int keyCode) {
 120  1223
         switch (keyCode) {
 121  11
         case KeyEvent.VK_ALT:
 122  0
         case KeyEvent.VK_ALT_GRAPH:
 123  0
         case KeyEvent.VK_CAPS_LOCK:
 124  2
         case KeyEvent.VK_CONTROL:
 125  0
         case KeyEvent.VK_NUM_LOCK:
 126  0
         case KeyEvent.VK_META:
 127  24
         case KeyEvent.VK_SHIFT:
 128  37
             return true;
 129   
 
 130  1186
         default:
 131  1186
             return false;
 132   
         }
 133   
     }
 134   
 
 135   
     /**
 136   
      * Set the attribute value.
 137   
      *
 138   
      * @param modifiers The new value of the attribute
 139   
      */
 140  3195
     public void setModifiers(final int modifiers) {
 141  3195
         m_modifiers = modifiers;
 142   
     }
 143   
 
 144   
     /**
 145   
      * Get the attribute value.
 146   
      *
 147   
      * @return int    The value of the attribute
 148   
      */
 149  4311
     public final int getModifiers() {
 150  4311
         return m_modifiers;
 151   
     }
 152   
 
 153   
     /**
 154   
      * Get the default modifiers.
 155   
      * @return default modifiers for the event.
 156   
      */
 157   
     public abstract int getDefaultModifiers();
 158   
 
 159   
     /**
 160   
      * Set the attribute value.
 161   
      * @param position The value of the attribute
 162   
      */
 163  2908
     public void setPosition(final int position) {
 164  2908
         m_position = position;
 165   
     }
 166   
 
 167   
     /**
 168   
      * Get the attribute value.
 169   
      * @return int The value of the attribute
 170   
      */
 171  638
     public int getPosition() {
 172  638
         return m_position;
 173   
     }
 174   
 
 175   
     /**
 176   
      * Set the attribute value.
 177   
      * @param referencePoint The value of the attribute
 178   
      */
 179  2817
     public void setReferencePoint(final Point referencePoint) {
 180  2817
         m_referencePoint = referencePoint;
 181   
     }
 182   
 
 183   
     /**
 184   
      * Get the attribute value.
 185   
      * @return Point The value of the attribute
 186   
      */
 187  332
     public Point getReferencePoint() {
 188  332
         return m_referencePoint;
 189   
     }
 190   
 
 191   
     /**
 192   
      * Return the root {@link java.awt.Container} of the
 193   
      * current {@link java.awt.Component}.
 194   
      *
 195   
      * @return The root {@link java.awt.Container}.
 196   
      */
 197  3164
     public Component getRoot() {
 198  3164
         return getRoot(getComponent());
 199   
     }
 200   
 
 201   
     /**
 202   
      * Return the root {@link java.awt.Container} of the
 203   
      * specified {@link java.awt.Component}.
 204   
      *
 205   
      * @param c The {@link java.awt.Component} to obtain the root for.
 206   
      * @return The root {@link java.awt.Container}.
 207   
      */
 208  5226
     public Component getRoot(final Component c) {
 209  5226
         Component applet = null;
 210   
 
 211  5226
         for (Component p = c; p != null; p = p.getParent()) {
 212  31881
             if (p instanceof Window || !p.isLightweight()) {
 213  5164
                 return p;
 214   
             }
 215   
 
 216  26717
             if (p instanceof Applet) {
 217  0
                 applet = p;
 218   
             }
 219   
         }
 220   
 
 221  62
         return applet;
 222   
     }
 223   
 
 224   
     /**
 225   
      * Set the attribute value.
 226   
      *
 227   
      * @param sleepTime The new value of the attribute
 228   
      */
 229  3339
     public void setSleepTime(final long sleepTime) {
 230  3339
         m_sleepTime = sleepTime;
 231   
     }
 232   
 
 233   
     /**
 234   
      * Get the attribute value.
 235   
      *
 236   
      * @return long    The value of the attribute
 237   
      */
 238  265
     public long getSleepTime() {
 239  265
         return m_sleepTime;
 240   
     }
 241   
 
 242   
     // The next set of API's deal with creating event data
 243   
     // Based upon a AWT Event for recording.
 244   
 
 245   
     /**
 246   
      * Consume the {@link java.awt.Event}.
 247   
      *
 248   
      * @param ae Event to be consumed.
 249   
      * @return boolean true if the event was consumed.
 250   
      */
 251   
     public abstract boolean consume(final AWTEvent ae);
 252   
 
 253   
     /**
 254   
      * Set valid state.
 255   
      *
 256   
      * @param valid true if the event has data configured.
 257   
      */
 258  4762
     public final void setValid(final boolean valid) {
 259  4762
         this.m_valid = valid;
 260   
     }
 261   
 
 262   
     /**
 263   
      * Get the valid state.
 264   
      *
 265   
      * @return boolean true if the event is valid.
 266   
      */
 267  7078
     public final boolean isValid() {
 268  7078
         return m_valid;
 269   
     }
 270   
 
 271   
     /**
 272   
      * Compare to event datas and deterime if they are equal.
 273   
      *
 274   
      * @param o Object to be compared.
 275   
      * @return true if the events are the same.
 276   
      */
 277  134
     public boolean equals(final Object o) {
 278  134
         if (o == null) {
 279  12
             return false;
 280   
         }
 281   
 
 282  122
         if (o.getClass() != getClass()) {
 283  12
             return false;
 284   
         }
 285   
 
 286   
         // isValid
 287  110
         AbstractEventData data = (AbstractEventData) o;
 288   
 
 289  110
         return (data.isValid() == isValid())
 290   
         && (data.getComponent() == getComponent())
 291   
         && (data.getModifiers() == getModifiers())
 292   
         && (data.getPosition() == getPosition())
 293   
         && (data.getReferencePoint() == getReferencePoint());
 294   
     }
 295   
 
 296   
     /**
 297   
      * Returns the hashCode of the contained component.
 298   
      * @return int hashCode.
 299   
      */
 300  0
     public int hashCode() {
 301  0
         Component comp = getComponent();
 302   
 
 303  0
         if (comp != null) {
 304  0
             return comp.hashCode();
 305   
         }
 306   
 
 307  0
         return 1;
 308   
     }
 309   
 
 310   
     /**
 311   
      * Populate the Element with the attributes to recreate this
 312   
      * event data.
 313   
      * @param e Element to be populated.
 314   
      */
 315  0
     public void populate(final org.w3c.dom.Element e) {
 316  0
         if (getPosition() != getDefaultPosition()) {
 317  0
             String position;
 318   
 
 319  0
             switch (getPosition()) {
 320  0
             case NORTH:
 321  0
                 position = "north";
 322   
 
 323  0
                 break;
 324   
 
 325  0
             case SOUTH:
 326  0
                 position = "south";
 327   
 
 328  0
                 break;
 329   
 
 330  0
             case EAST:
 331  0
                 position = "east";
 332   
 
 333  0
                 break;
 334   
 
 335  0
             case WEST:
 336  0
                 position = "west";
 337   
 
 338  0
                 break;
 339   
 
 340  0
             case NORTH_WEST:
 341  0
                 position = "northwest";
 342   
 
 343  0
                 break;
 344   
 
 345  0
             case NORTH_EAST:
 346  0
                 position = "northeast";
 347   
 
 348  0
                 break;
 349   
 
 350  0
             case SOUTH_WEST:
 351  0
                 position = "southwest";
 352   
 
 353  0
                 break;
 354   
 
 355  0
             case SOUTH_EAST:
 356  0
                 position = "southeast";
 357   
 
 358  0
                 break;
 359   
 
 360  0
             case CENTER:
 361  0
                 position = "center";
 362   
 
 363  0
                 break;
 364   
 
 365  0
             case CUSTOM:
 366  0
                 position = "custom";
 367   
 
 368  0
                 break;
 369   
 
 370  0
             case PERCENT:
 371  0
                 position = "percent";
 372   
 
 373  0
                 break;
 374   
 
 375  0
             case OFFSET:
 376  0
                 position = "offset";
 377   
 
 378  0
                 break;
 379   
 
 380  0
             default:
 381  0
                 position = "" + getPosition();
 382   
 
 383  0
                 break;
 384   
             }
 385   
 
 386  0
             e.setAttribute(JFCXMLConstants.POSITION, position);
 387   
         }
 388   
 
 389  0
         if (getModifiers() != getDefaultModifiers()) {
 390  0
             String txt = getModifierText();
 391   
 
 392  0
             if ((txt != null) && (txt.length() > 0)) {
 393  0
                 e.setAttribute(JFCXMLConstants.MODIFIERS, txt);
 394   
             }
 395   
         }
 396   
 
 397  0
         if (getSleepTime() != getDefaultSleepTime()) {
 398  0
             e.setAttribute(JFCXMLConstants.SLEEPTIME, "" + getSleepTime());
 399   
         }
 400   
 
 401  0
         Point p = getReferencePoint();
 402   
 
 403  0
         if (p != null) {
 404  0
             e.setAttribute(JFCXMLConstants.REFERENCE, "" + p.x + "," + p.y);
 405   
         }
 406   
     }
 407   
 
 408   
     /**
 409   
      * Prepare the component to receive the {@link java.awt.Event}
 410   
      * by calling <code>requestFocus()</code> on the {@link java.awt.Component}
 411   
      * and calculating the screen location.
 412   
      *
 413   
      * @return true if the component is ready to receive
 414   
      * the {@link java.awt.Event}.
 415   
      */
 416  82
     public boolean prepareComponent() {
 417  82
         if (!isValidForProcessing(getComponent())) {
 418  8
             return false;
 419   
         }
 420   
 
 421  74
         JFCTestCase testCase = getTestCase();
 422   
 
 423  74
         if (testCase != null) {
 424   
             // try to clear the event queue
 425  74
             testCase.flushAWT();
 426   
         }
 427   
 
 428  74
         Rectangle compRect = getComponent().getBounds();
 429   
 
 430  74
         if (testCase != null) {
 431   
             // try to clear the event queue
 432  74
             testCase.flushAWT();
 433  74
             testCase.pauseAWT();
 434   
         }
 435   
 
 436  74
         Point p = calculatePoint(compRect);
 437   
 
 438  74
         if (getComponent() instanceof JComponent) {
 439  44
             JComponent c   = (JComponent) getComponent();
 440  44
             Rectangle  vis = c.getVisibleRect();
 441   
 
 442  44
             if (!vis.contains(p)) {
 443  3
                 Rectangle newView = new Rectangle(p.x - (int) (vis.width / 2),
 444   
                     p.y - (int) (vis.height / 2), vis.width, vis.height);
 445  3
                 c.scrollRectToVisible(newView);
 446   
             }
 447   
         }
 448   
 
 449  74
         Point screen = getComponent().getLocationOnScreen();
 450  74
         screen.translate(p.x, p.y);
 451  74
         setLocationOnScreen(screen);
 452   
 
 453  74
         return true;
 454   
     }
 455   
 
 456   
     /**
 457   
      * Get the String description of the abstract event.
 458   
      *
 459   
      * @return String description of the event.
 460   
      */
 461  141
     public String toString() {
 462  141
         StringBuffer buf = new StringBuffer(1000);
 463  141
         buf.append(getClass().getName());
 464   
 
 465  141
         if (!isValid()) {
 466  0
             buf.append(" invalid");
 467   
 
 468  0
             return buf.toString();
 469   
         }
 470   
 
 471  141
         buf.append(" testCase: " + getTestCase());
 472  141
         buf.append(" modifiers: " + getModifierText());
 473  141
         buf.append(" sleepTime: " + m_sleepTime);
 474  141
         buf.append(" position:" + POSITIONSTRINGS[m_position]);
 475  141
         buf.append(" refPoint: " + m_referencePoint);
 476  141
         buf.append(" screenLoc: " + m_screenLocation);
 477  141
         buf.append(" component: " + getComponent());
 478   
 
 479  141
         return buf.toString();
 480   
     }
 481   
 
 482   
     /**
 483   
      * Set the screen location for the event.
 484   
      * @param screenLocation screenLocation for event.
 485   
      */
 486  2392
     protected final void setLocationOnScreen(final Point screenLocation) {
 487  2392
         m_screenLocation = screenLocation;
 488   
     }
 489   
 
 490   
     /**
 491   
      * Checks whether a component is valid for processing using jfcUnit.
 492   
      *
 493   
      * @param comp   The {@link java.awt.Component} to be tested.
 494   
      * @return boolean specifying whether this component is not
 495   
      * null and is showing.
 496   
      */
 497  1711
     protected boolean isValidForProcessing(final Component comp) {
 498  1711
         return ((comp != null) && comp.isShowing());
 499   
     }
 500   
 
 501   
     /**
 502   
      * A utility method to calculate the {@link java.awt.Point}
 503   
      * at which the events are to be fired based on the position
 504   
      * and reference-point specified.
 505   
      *
 506   
      * @param rect  The {@link java.awt.Rectangle} containing the
 507   
      * source component.
 508   
      * @return The new {@link java.awt.Point} at which the mouse
 509   
      * events have to be fired.
 510   
      */
 511  2180
     protected final Point calculatePoint(final Rectangle rect) {
 512   
         // if the user has set a specific point or if this
 513   
         // calculation has already been done once, then just return.
 514  2180
         if (m_position == CUSTOM) {
 515  59
             return new Point(rect.x + m_referencePoint.x,
 516   
                 rect.y + m_referencePoint.y);
 517   
         }
 518   
 
 519  2121
         int x = 0;
 520  2121
         int y = 0;
 521   
 
 522  2121
         if (m_position == PERCENT) {
 523  54
             x     = rect.x + (int) ((rect.width * m_referencePoint.x) / 100);
 524  54
             y     = rect.y + (int) ((rect.height * m_referencePoint.y) / 100);
 525   
         } else {
 526   
             // Calculate the Y position
 527  2067
             if ((m_position == NORTH)
 528   
                     || (m_position == NORTH_WEST)
 529   
                     || (m_position == NORTH_EAST)) {
 530  8
                 y = rect.y;
 531  2059
             } else if ((m_position == SOUTH)
 532   
                     || (m_position == SOUTH_WEST)
 533   
                     || (m_position == SOUTH_EAST)) {
 534  9
                 y = rect.y + rect.height;
 535   
             } else {
 536  2050
                 y = rect.y + (int) (rect.height / 2);
 537   
             }
 538   
 
 539   
             // Calculate the X position
 540  2067
             if ((m_position == WEST)
 541   
                     || (m_position == NORTH_WEST)
 542   
                     || (m_position == SOUTH_WEST)) {
 543  8
                 x = rect.x;
 544  2059
             } else if ((m_position == EAST)
 545   
                     || (m_position == NORTH_EAST)
 546   
                     || (m_position == SOUTH_EAST)) {
 547  247
                 x = rect.x + rect.width;
 548   
             } else {
 549  1812
                 x = rect.x + (int) (rect.width / 2);
 550   
             }
 551   
         }
 552   
 
 553  2121
         return new Point(x, y);
 554   
     }
 555   
 
 556   
     /**
 557   
      * Check if this event can consume the {@link java.awt.AWTEvent}.
 558   
      *
 559   
      * @param ae Event to be consumed.
 560   
      * @return boolean true if the event can be consumed.
 561   
      */
 562  0
     protected boolean canConsume(final AWTEvent ae) {
 563  0
         if (!isValid()) {
 564  0
             return true;
 565   
         }
 566   
 
 567  0
         return (ae.getSource().equals(getComponent()));
 568   
     }
 569   
 
 570   
     /**
 571   
      * Get the modifier text for the current modifiers.
 572   
      * @return String with modifiers separated by
 573   
      * the +. Ex: Alt+Shift
 574   
      */
 575   
     abstract String getModifierText();
 576   
 }
 577