Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 990   Methods: 68
NCLOC: 768   Classes: 6
 
 Source file Conditionals Statements Methods TOTAL
ComponentReferenceTest.java 78.1% 94.9% 86.8% 93.1%
coverage coverage
 1   
 package abbot.script;
 2   
 
 3   
 import java.applet.*;
 4   
 import java.awt.*;
 5   
 import java.awt.event.*;
 6   
 import java.net.URL;
 7   
 import java.util.*;
 8   
 import java.util.List;
 9   
 
 10   
 import javax.swing.*;
 11   
 import javax.swing.border.*;
 12   
 
 13   
 import junit.extensions.abbot.*;
 14   
 import junit.extensions.abbot.Timer;
 15   
 import abbot.*;
 16   
 import abbot.finder.*;
 17   
 import abbot.finder.matchers.*;
 18   
 import abbot.i18n.Strings;
 19   
 
 20   
 /** 
 21   
  * Verify various ComponentReference requirements.
 22   
  */
 23   
 // TODO: test new refs aren't added to Resolver
 24   
 // TODO: new refs all get unique IDs
 25   
 // TODO: more clearly delineate rules instead of random tests
 26   
 public class ComponentReferenceTest
 27   
     extends ComponentTestFixture implements XMLConstants {
 28   
 
 29   
     private Map newRefs;
 30   
     private Resolver resolver;
 31  33
     protected void setUp() {
 32  33
         newRefs = new HashMap();
 33  33
         resolver = getResolver();
 34   
         // allow easy creation of references, but force initial lookups
 35  33
         ComponentReference.cacheOnCreation = false;
 36   
     }
 37  33
     protected void tearDown() {
 38  33
         newRefs = null;
 39  33
         resolver = null;
 40  33
         ComponentReference.cacheOnCreation = true;
 41   
     }
 42   
 
 43  1
     public void testInnerClassMatch() {
 44  1
         ComponentReference cr =
 45   
             new ComponentReference(resolver, Component.class, new HashMap());
 46  1
         assertTrue("Anonymous inner class not detected",
 47   
                    cr.expressionMatch(ComponentReference.ANON_INNER_CLASS,
 48   
                                       "my.class.Name$12"));
 49  1
         assertTrue("Anonymous inner class falsely detected",
 50   
                    !cr.expressionMatch(ComponentReference.ANON_INNER_CLASS,
 51   
                                        "my.class.Name$InnerClass"));
 52   
     }
 53   
 
 54   
     /** Saved class name should not be an anonymous or inner class. */
 55  1
     public void testUseCanonicalClass() {
 56  1
         ComponentReference cr =
 57   
             new ComponentReference(resolver, new Frame(getName()) {
 58  2
                 public String toString() { return getName(); }
 59   
             });
 60  1
         assertEquals("Wrong class saved", Frame.class.getName(),
 61   
                      cr.getRefClassName());
 62   
     }
 63   
 
 64   
     /** Any newly created reference should match against the component it was
 65   
      * created from.
 66   
      */
 67  1
     public void testAddComponent() throws Throwable {
 68  1
         JTextField tf = new JTextField();
 69  1
         tf.setColumns(20);
 70  1
         showFrame(tf);
 71  1
         ComponentReference ref = resolver.addComponent(tf);
 72  1
         assertEquals("Newly created component reference does not match",
 73   
                      tf, ref.getComponent());
 74   
     }
 75   
 
 76   
     /** Create a reference for a dialog child of a dialog.
 77   
         Bug reported by vladgur.
 78   
     */
 79  1
     public void testAddSubDialog() {
 80  1
         JFrame frame = new JFrame(getName());
 81  1
         JDialog d1 = new JDialog(frame, "Modal", true);
 82  1
         d1.getContentPane().add(new JLabel("Modal Dialog"));
 83  1
         JDialog d2 = new JDialog(d1, "Non-Modal", false);
 84  1
         d2.getContentPane().add(new JLabel("Non-Modal Dialog"));
 85  1
         showWindow(d1);
 86  1
         showWindow(d2);
 87  1
         ComponentReference ref =
 88   
             new ComponentReference(resolver, d2.getContentPane(), newRefs);
 89  1
         assertNotNull("Can't create subdialog reference", ref);
 90   
     }
 91   
 
 92   
     /**
 93   
      * Test to see if the label and index can identify a component
 94   
      */
 95  1
     public void testSiblings() {
 96  1
         JTextField tf1 = new JTextField();
 97  1
         JTextField tf2 = new JTextField();
 98  1
         tf1.setColumns(10);
 99  1
         tf2.setColumns(10);
 100  1
         JPanel pane = new JPanel();
 101  1
         pane.add(tf1);
 102  1
         pane.add(tf2);
 103   
 
 104  1
         showFrame(pane);
 105   
 
 106  1
         ComponentReference cr1 = resolver.addComponent(tf1);
 107  1
         ComponentReference cr2 = resolver.addComponent(tf2);
 108  1
         assertTrue("Should get two unique references", cr1 != cr2);
 109   
 
 110  1
         try {
 111  1
             assertEquals("Incorrect sibling 1 lookup with " + cr1,
 112   
                          tf1, cr1.getComponent());
 113  1
             assertEquals("Incorrect sibling 2 lookup with " + cr2,
 114   
                          tf2, cr2.getComponent());
 115   
         }
 116   
         catch(ComponentNotFoundException cnf) {
 117  0
             fail(cnf.toString());
 118   
         }
 119   
         catch(MultipleComponentsFoundException mcf) {
 120  0
             fail(mcf.toString());
 121   
         }
 122   
     }
 123   
 
 124   
 
 125   
     /**
 126   
      * Verify two identical sibling components can be distinguished.
 127   
      */
 128  1
     public void testIdenticalSiblings() {
 129  1
         JButton button1 = new JButton("Button");
 130  1
         JButton button2 = new JButton("Button");
 131  1
         JPanel pane = new JPanel();
 132  1
         pane.add(button1);
 133  1
         pane.add(button2);
 134   
 
 135  1
         showFrame(pane);
 136   
 
 137  1
         ComponentReference cr1 = resolver.addComponent(button1);
 138  1
         ComponentReference cr2 = resolver.addComponent(button2);
 139  1
         assertTrue("Should get two unique references", cr1 != cr2);
 140   
 
 141  1
         try {
 142  1
             assertEquals("Incorrect sibling button 1 lookup with " + cr1,
 143   
                          button1, cr1.getComponent());
 144  1
             assertEquals("Incorrect sibling button 2 lookup with " + cr2,
 145   
                          button2, cr2.getComponent());
 146   
         }
 147   
         catch(ComponentNotFoundException cnf) {
 148  0
             fail(cnf.toString());
 149   
         }
 150   
         catch(MultipleComponentsFoundException mcf) {
 151  0
             fail(mcf.toString());
 152   
         }
 153   
     }
 154   
 
 155   
     
 156   
     /**
 157   
      * Verify two identical cousin (sibling parents) components can be
 158   
      * distinguished. 
 159   
      */
 160  1
     public void testIdenticalCousins() {
 161  1
         JButton button1 = new JButton("Button");
 162  1
         JButton button2 = new JButton("Button");
 163  1
         JPanel  panel1 = new JPanel();
 164  1
         JPanel  panel2 = new JPanel();
 165  1
         panel1.add(button1);
 166  1
         panel2.add(button2);
 167   
 
 168  1
         JPanel pane = new JPanel();
 169  1
         pane.add(panel1);
 170  1
         pane.add(panel2);
 171   
 
 172  1
         showFrame(pane);
 173   
 
 174  1
         ComponentReference cr1 = resolver.addComponent(button1);
 175  1
         ComponentReference cr2 = resolver.addComponent(button2);
 176  1
         assertTrue("Should get two unique references", cr1 != cr2);
 177   
 
 178  1
         try {
 179  1
             assertEquals("Incorrect cousin button 1 lookup with " + cr1,
 180   
                          button1, cr1.getComponent());
 181  1
             assertEquals("Incorrect cousin button 2 lookup with " + cr2,
 182   
                          button2, cr2.getComponent());
 183   
         }
 184   
         catch(ComponentNotFoundException cnf) {
 185  0
             fail(cnf.toString());
 186   
         }
 187   
         catch(MultipleComponentsFoundException mcf) {
 188  0
             fail(mcf.toString());
 189   
         }
 190   
     }
 191   
 
 192   
     /**
 193   
      * Test to see if two buttons which are identical except for their name
 194   
      * and index can be found
 195   
      */
 196  1
     public void testTwoNamedButtons() {
 197  1
         JButton button1 = new JButton("Button");
 198  1
         JButton button2 = new JButton("Button");
 199  1
         JPanel  panel1 = new JPanel();
 200  1
         JPanel  panel2 = new JPanel();
 201   
         
 202  1
         button1.setName("Button1");
 203  1
         button2.setName("Button2");
 204   
 
 205  1
         panel1.add(button1);
 206  1
         panel2.add(button2);
 207  1
         JPanel pane = new JPanel();
 208  1
         pane.add(panel1);
 209  1
         pane.add(panel2);
 210   
 
 211  1
         showFrame(pane);
 212   
 
 213  1
         ComponentReference cr1 = resolver.addComponent(button1);
 214  1
         ComponentReference cr2 = resolver.addComponent(button2);
 215  1
         assertTrue("Should get two unique references", cr1 != cr2);
 216   
 
 217  1
         try {
 218  1
             assertEquals("Button 1 not found", button1, cr1.getComponent());
 219  1
             assertEquals("Button 2 not found", button2, cr2.getComponent());
 220   
         }
 221   
         catch(ComponentNotFoundException cnf) {
 222  0
             fail(cnf.toString());
 223   
         }
 224   
         catch(MultipleComponentsFoundException mcf) {
 225  0
             fail(mcf.toString());
 226   
         }
 227   
     }
 228   
 
 229   
     /**
 230   
      * Test to ensure that index can be used on otherwise indistingushable 
 231   
      * components
 232   
      */
 233  1
     public void testIdenticalLabelGroup() {
 234   
         
 235  1
         final int NUM_LABELS = 10;
 236   
 
 237  1
         ArrayList labels = new ArrayList();
 238  1
         ArrayList refs = new ArrayList();
 239   
 
 240  1
         JPanel pane = new JPanel();
 241  1
         showFrame(pane);
 242  1
         for (int i=0; i < NUM_LABELS; ++i){
 243  10
             JLabel label = new JLabel("Empty");
 244  10
             labels.add(label);
 245  10
             pane.add(label);
 246  10
             refs.add(resolver.addComponent(label));
 247   
         }
 248   
         
 249  1
         for (int i=0;i < NUM_LABELS - 1; ++i) {
 250  9
             for (int next=i+1;next < NUM_LABELS;next++) {
 251  45
                 Component c1 = (Component)labels.get(i);
 252  45
                 Component c2 = (Component)labels.get(next);
 253  45
                 ComponentReference cr1 = (ComponentReference)refs.get(i);
 254  45
                 ComponentReference cr2 = (ComponentReference)refs.get(next);
 255   
 
 256  45
                 try {
 257  45
                     assertEquals("label " + i + " not found", c1, cr1.getComponent());
 258  45
                     assertEquals("label " + next + " not found", c2, cr2.getComponent());
 259   
                 }
 260   
                 catch(ComponentNotFoundException cnf) {
 261  0
                     fail(cnf.toString());
 262   
                 }
 263   
                 catch(MultipleComponentsFoundException mcf) {
 264  0
                     fail(mcf.toString());
 265   
                 }
 266   
             }
 267   
         }
 268   
     }
 269   
 
 270   
     /** Ensure that find window works with JOptionPane-generated
 271   
      * components. */
 272  1
     public void testDuplicateJOptionPanes() throws Throwable {
 273  1
         JOptionPane pane = new JOptionPane("A message", JOptionPane.
 274   
                                            INFORMATION_MESSAGE);
 275  1
         JFrame frame = new JFrame(getName());
 276  1
         Dialog dialog = pane.createDialog(frame, "Dialog");
 277  1
         showWindow(dialog);
 278  1
         dialog.setVisible(false);
 279  1
         Timer timer = new Timer();
 280  1
         while (dialog.isShowing()) {
 281  0
             if (timer.elapsed() > 5000)
 282  0
                 throw new RuntimeException("Timed out waiting for dialog to hide");
 283  0
             getRobot().sleep();
 284   
         }
 285  1
         JOptionPane pane2 = new JOptionPane("A message", JOptionPane.
 286   
                                             INFORMATION_MESSAGE);
 287  1
         Dialog d2 = pane2.createDialog(frame, "Dialog 2");
 288  1
         showWindow(d2);
 289  1
         Component comp = getFinder().find(new WindowMatcher(d2.getTitle()));
 290  1
         assertEquals("Wrong JOptionPane found", d2, comp);
 291   
     }
 292   
 
 293   
     private class ButtonMatcher implements Matcher {
 294   
         private String text = null;
 295  2
         public ButtonMatcher() {
 296  2
             this(null);
 297   
         }
 298  2
         public ButtonMatcher(String text) {
 299  2
             this.text = text;
 300   
         }
 301  28
         public boolean matches(Component c) {
 302  28
             return c instanceof JButton
 303   
                 && (text == null || ((JButton)c).getText().equals(text));
 304   
         }
 305   
     }
 306   
 
 307   
     /** Component reference matching one dialog should match an identical
 308   
      * subsequent one using the same JOptionPane.
 309   
      */
 310  1
     public void testSubsequentDialogContentsLookup() throws Throwable {
 311  1
         ComponentReference ref =
 312   
             new ComponentReference(resolver, javax.swing.JButton.class,
 313   
                                    new String[][] {{
 314   
                                        XMLConstants.TAG_TEXT, "OK" }});
 315  1
         Dialog d1 = null;
 316  1
         Dialog d2 = null;
 317  1
         JFrame frame = new JFrame(getName());
 318  1
         JOptionPane pane = new JOptionPane("Dialog", JOptionPane.
 319   
                                            INFORMATION_MESSAGE);
 320  1
         d1 = pane.createDialog(frame, "Dialog");
 321  1
         showWindow(d1);
 322  1
         JButton button = (JButton)getFinder().find(d1, new ButtonMatcher());
 323  1
         assertNotNull("Button shouldn't be null", button);
 324  1
         assertEquals("Wrong component found",
 325   
                      button, ref.getComponent(getHierarchy()));
 326  1
         d1.setVisible(false);
 327   
 
 328  1
         d2 = pane.createDialog(frame, "Dialog");
 329  1
         showWindow(d2);
 330  1
         JButton button2 = (JButton)getFinder().find(d2, new ButtonMatcher());
 331  1
         assertNotNull("Second button lookup shouldn't be null", button2);
 332  1
         assertEquals("Same button should be used", button2, button);
 333  1
         assertEquals("Wrong component found with " + ref,
 334   
                      button2, ref.getComponent(getHierarchy()));
 335   
     }
 336   
 
 337  1
     public void testJFileChooserReferences() throws Exception {
 338  1
         final JFileChooser chooser = new JFileChooser();
 339  1
         final Frame frame = showFrame(new JLabel(getName()));
 340  1
         Dialog d1 = showModalDialog(new Runnable() {
 341  1
             public void run() {
 342  1
                 chooser.showOpenDialog(frame);
 343   
             }
 344   
         });
 345   
         // Don't care if we get Open or Cancel
 346  1
         JButton button = (JButton)getFinder().
 347   
             find(new ClassMatcher(JButton.class, true));
 348   
 
 349  1
         ComponentReference ref = resolver.addComponent(d1);
 350  1
         ComponentReference bref = resolver.addComponent(button);
 351   
                                                          
 352  1
         assertEquals("First file dialog not found", d1, ref.getComponent());
 353  1
         assertEquals("Dialog button not found", button, bref.getComponent());
 354   
         // must dispose, not hide; otherwise it will still match
 355  1
         disposeWindow(d1);
 356   
 
 357  1
         Dialog d2 = showModalDialog(new Runnable() {
 358  1
             public void run() {
 359  1
                 chooser.showOpenDialog(frame);
 360   
             }
 361   
         });
 362  1
         assertTrue("JFileChooser presented same dialog", d1 != d2);
 363  1
         assertEquals("Incorrect subsequent file dialog found with " + ref,
 364   
                      d2, ref.getComponent());
 365  1
         assertEquals("Same button should be used on both dialogs",
 366   
                      button, bref.getComponent());
 367   
     }
 368   
 
 369  1
     public void testFindMenuItem() throws Throwable {
 370  1
         JMenuItem mi = new JMenuItem("item");
 371  1
         JMenu menu = new JMenu("menu");
 372  1
         JMenuBar mb = new JMenuBar();
 373  1
         mb.add(menu);
 374  1
         menu.add(mi);
 375  1
         JFrame frame = new JFrame(getName());
 376  1
         frame.setJMenuBar(mb);
 377  1
         showWindow(frame);
 378  1
         ComponentReference ref = resolver.addComponent(mi);
 379  1
         assertEquals("Menu item not found: " + ref,
 380   
                      mi, ref.getComponent());
 381   
     }
 382   
 
 383  1
     public void testConsistentDefaultFrameReference() throws Throwable {
 384   
         // Default frame should always get the same reference
 385  1
         JOptionPane pane = new JOptionPane("Dialog", JOptionPane.
 386   
                                            INFORMATION_MESSAGE);
 387  1
         Dialog d1 = pane.createDialog(null, "Dialog");
 388  1
         showWindow(d1);
 389  1
         ComponentReference ref1 = resolver.addComponent(d1);
 390  1
         d1 = pane.createDialog(null, "Dialog2");
 391  1
         showWindow(d1);
 392  1
         ComponentReference ref2 = resolver.addComponent(d1);
 393  1
         assertEquals("Option pane dialogs should share same default frame",
 394   
                      ref1.getAttribute(TAG_PARENT),
 395   
                      ref2.getAttribute(TAG_PARENT));
 396  1
         assertEquals("Incorrect ID for shared frame instance",
 397   
                      ComponentReference.SHARED_FRAME_ID,
 398   
                      ref1.getAttribute(TAG_PARENT));
 399   
     }
 400   
 
 401  1
     public void testRootReference() {
 402  1
         JFrame frame = new JFrame(getName());
 403  1
         showWindow(frame);
 404  1
         Dialog d = new JDialog(frame, getName() + " Dialog");
 405  1
         showWindow(d);
 406  1
         ComponentReference ref = resolver.addComponent(frame);
 407  1
         ComponentReference ref1 = resolver.addComponent(d);
 408  1
         assertEquals("Component should be root",
 409   
                      "true", ref.getAttribute(TAG_ROOT));
 410  1
         assertNull("Component should not be root",
 411   
                    ref1.getAttribute(TAG_ROOT));
 412   
     }
 413   
 
 414  1
     public void testFindDialogWithHiddenFrame() throws Throwable {
 415  1
         JFrame frame = new JFrame(getName());
 416  1
         Dialog d1 = new JDialog(frame, getName() + " Dialog");
 417  1
         showWindow(d1);
 418  1
         ComponentReference ref = resolver.addComponent(d1);
 419  1
         assertEquals("Dialog not found", d1, ref.getComponent());
 420   
     }
 421   
 
 422  1
     public void testIndexlessHorizontalOrdering() throws Throwable {
 423   
         // Ensure that several components differing only by horizontal
 424   
         // location can be distinguished.  Use Frames, so that the parent
 425   
         // index does not come into play.
 426   
         // Note that this ordering is only really meaningful to embedded
 427   
         // frames (and thus applets) which can not otherwise be moved or
 428   
         // resized independengly of one another.
 429  1
         Component c1 = new InvisibleShowingFrame("Same");
 430  1
         Component c2 = new InvisibleShowingFrame("Same");
 431  1
         Component c3 = new InvisibleShowingFrame("Same");
 432  1
         c1.setLocation(100, 100); c1.setSize(100, 100);
 433  1
         c2.setLocation(200, 100); c2.setSize(100, 100);
 434  1
         c3.setLocation(300, 100); c3.setSize(100, 100);
 435   
 
 436  1
         ComponentReference cr1 = resolver.addComponent(c1);
 437  1
         ComponentReference cr2 = resolver.addComponent(c2);
 438  1
         ComponentReference cr3 = resolver.addComponent(c3);
 439   
 
 440  1
         assertNotNull("Leftmost frame not found", cr1.getComponent());
 441  1
         assertNotNull("Middle frame not found", cr2.getComponent());
 442  1
         assertNotNull("Rightmost frame not found", cr3.getComponent());
 443   
 
 444  1
         c1.setLocation(200, 100); 
 445  1
         c2.setLocation(300, 100); 
 446  1
         c3.setLocation(400, 100); 
 447   
 
 448  1
         assertNotNull("Leftmost frame not found", cr1.getComponent());
 449  1
         assertNotNull("Middle frame not found", cr2.getComponent());
 450  1
         assertNotNull("Rightmost frame not found", cr3.getComponent());
 451   
     }
 452   
 
 453  1
     public void testDescendentIndexlessHorizontalOrdering() throws Throwable {
 454   
         // Similar to the IndexlessHorizontalOrdering, except that children
 455   
         // are checked, where the only difference is the window reference.
 456  1
         Frame f1 = new InvisibleShowingFrame("Same");
 457  1
         Frame f2 = new InvisibleShowingFrame("Same");
 458  1
         Component c1 = new JLabel(getName());
 459  1
         Component c2 = new JLabel(getName());
 460  1
         f1.add(c1);
 461  1
         f2.add(c2);
 462  1
         f1.setLocation(100, 100); f1.setSize(100, 100);
 463  1
         f2.setLocation(200, 100); f2.setSize(100, 100);
 464  1
         ComponentReference cr1 = resolver.addComponent(c1);
 465  1
         ComponentReference cr2 = resolver.addComponent(c2);
 466  1
         assertNotNull("Leftmost component not found", cr1.getComponent());
 467  1
         assertNotNull("Rightmost component not found", cr2.getComponent());
 468   
     }
 469   
 
 470  1
     public void testIndexlessVerticalOrdering() throws Throwable {
 471   
         // Ensure that several components differing only by vertical
 472   
         // location can be distinguished.  Use Frames, so that the parent
 473   
         // index does not come into play.
 474   
         // Note that this ordering is only really meaningful to embedded
 475   
         // frames (and thus applets) which can not otherwise be moved or
 476   
         // resized independengly of one another.
 477  1
         Component c1 = new InvisibleShowingFrame("Same");
 478  1
         Component c2 = new InvisibleShowingFrame("Same");
 479  1
         Component c3 = new InvisibleShowingFrame("Same");
 480  1
         c1.setLocation(100, 100); c1.setSize(100, 100);
 481  1
         c2.setLocation(100, 200); c2.setSize(100, 100);
 482  1
         c3.setLocation(100, 300); c3.setSize(100, 100);
 483   
 
 484  1
         ComponentReference cr1 = resolver.addComponent(c1);
 485  1
         ComponentReference cr2 = resolver.addComponent(c2);
 486  1
         ComponentReference cr3 = resolver.addComponent(c3);
 487   
 
 488  1
         assertNotNull("Top frame not found", cr1.getComponent());
 489  1
         assertNotNull("Middle frame not found", cr2.getComponent());
 490  1
         assertNotNull("Bottom frame not found", cr3.getComponent());
 491   
 
 492  1
         c1.setLocation(100, 200); 
 493  1
         c2.setLocation(100, 300); 
 494  1
         c3.setLocation(100, 400); 
 495   
 
 496  1
         assertNotNull("Top frame not found", cr1.getComponent());
 497  1
         assertNotNull("Middle frame not found", cr2.getComponent());
 498  1
         assertNotNull("Bottom frame not found", cr3.getComponent());
 499   
     }
 500   
 
 501   
     private class InvisibleShowingFrame extends Frame {
 502   
         private Point location;
 503  15
         public InvisibleShowingFrame(String title) { super(title); }
 504  195
         public boolean isShowing() { return true; }
 505   
         // All other methods defer to this one
 506  47
         public void setBounds(int x, int y, int width, int height) {
 507  47
             super.setBounds(x, y, width, height);
 508  47
             if (location == null)
 509  15
                 location = new Point(x, y);
 510   
             else
 511  32
                 location.setLocation(x, y);
 512   
         }
 513  600
         public Point getLocationOnScreen() { return getLocation(); }
 514  620
         public Point getLocation() {
 515  620
             if (location == null)
 516  0
                 location = new Point(0, 0);
 517  620
             return location;
 518   
         }
 519   
     }
 520   
 
 521  1
     public void testOrder() {
 522  1
         Component c1 = new InvisibleShowingFrame("Same");
 523  1
         Component c2 = new InvisibleShowingFrame("Same");
 524  1
         Component c3 = new InvisibleShowingFrame("Same");
 525  1
         c1.setLocation(100, 100); c1.setSize(100, 100);
 526  1
         c2.setLocation(100, 200); c2.setSize(100, 100);
 527  1
         c3.setLocation(200, 200); c3.setSize(100, 100);
 528  1
         Component[] all = { c1, c2, c3 };
 529  1
         assertEquals("Wrong leftmost order",
 530   
                      "0", ComponentReference.getOrder(c1, all, true));
 531  1
         assertEquals("Wrong middle order",
 532   
                      "0", ComponentReference.getOrder(c2, all, true));
 533  1
         assertEquals("Wrong rightmost order",
 534   
                      "1", ComponentReference.getOrder(c3, all, true));
 535  1
         assertEquals("Wrong top order",
 536   
                      "0", ComponentReference.getOrder(c1, all, false));
 537  1
         assertEquals("Wrong middle order",
 538   
                      "1", ComponentReference.getOrder(c2, all, false));
 539  1
         assertEquals("Wrong bottom order",
 540   
                      "1", ComponentReference.getOrder(c3, all, false));
 541   
 
 542   
     }
 543   
 
 544   
     private static final int MAX_CREATION_TIME = 2000; //ms
 545  1
     public void testBasicReferenceCreationPerformance() throws Throwable {
 546   
         // Make sure caching is on, since that's what's being measured
 547  1
         ComponentReference.cacheOnCreation = true;
 548   
         // NOTE: need for this test was triggered by slowness in recording.
 549   
         // Scrollpanes (maybe w/all their buttons?) cause significant
 550   
         // slowdown. 
 551  1
         JPanel p1 = new JPanel(); 
 552  1
         JButton b1 = new JButton("Label");
 553  1
         p1.add(b1);
 554  1
         p1.add(new JScrollPane(new JButton("Label"))); 
 555  1
         p1.add(new JScrollPane(new JTextField("Label")));
 556  1
         p1.add(new JScrollPane(new JComboBox())); 
 557  1
         p1.add(new JScrollPane(new JTree())); 
 558  1
         Frame f1 = showFrame(p1);
 559  1
         getRobot().move(f1, 100, 100);
 560  1
         getRobot().waitForIdle();
 561   
 
 562  1
         Timer timer = new Timer();
 563  1
         ComponentReference ref1 = resolver.addComponent(b1);
 564  1
         long elapsed = timer.elapsed();
 565  1
         assertTrue("Too long to create reference: " + elapsed + "ms",
 566   
                    elapsed < MAX_CREATION_TIME);
 567   
 
 568  1
         JPanel p2 = new JPanel(); 
 569  1
         JButton b2 = new JButton("Label");
 570  1
         p2.add(b2);
 571  1
         p2.add(new JScrollPane(new JButton("Label")));
 572  1
         p2.add(new JScrollPane(new JTextField("Label")));
 573  1
         p2.add(new JScrollPane(new JComboBox()));
 574  1
         p2.add(new JScrollPane(new JTree()));
 575  1
         Frame f2 = showFrame(p2);
 576  1
         getRobot().move(f2, 101, 100);
 577  1
         getRobot().waitForIdle();
 578   
 
 579  1
         timer.reset();
 580  1
         ComponentReference ref2 = resolver.addComponent(b2);
 581  1
         elapsed = timer.elapsed();
 582  1
         assertTrue("Too long to create reference (using ordering): " 
 583   
                    + elapsed, elapsed < MAX_CREATION_TIME);
 584   
     }
 585   
 
 586   
     private static final int DEPTH = 10; 
 587   
     private class NestedPanel extends JPanel {
 588  330
         public NestedPanel(String name, int level) {
 589  330
             setBorder(new EmptyBorder(0,0,0,0));
 590  330
             if (level > 0)
 591  300
                 add(new NestedPanel(name, --level));
 592   
             else {
 593  30
                 JButton b = new JButton(name);
 594  30
                 add(b);
 595  30
                 b.addActionListener(new ActionListener() {
 596  0
                     public void actionPerformed(ActionEvent e) {
 597  0
                         JOptionPane.
 598   
                             showMessageDialog(null, "message", null,
 599   
                                               JOptionPane.PLAIN_MESSAGE);
 600   
                     }
 601   
                 });
 602   
             }
 603   
         }
 604   
     }
 605   
     private class MyFrame extends JFrame {
 606  6
         public MyFrame(String name) {
 607  6
             super(name);
 608  6
             JPanel p = new JPanel();
 609  6
             p.add(new NestedPanel("Submit " + name, DEPTH));
 610  6
             p.add(new NestedPanel("Retrieve " + name, DEPTH));
 611  6
             p.add(new NestedPanel("New " + name, DEPTH));
 612  6
             p.add(new NestedPanel("Edit " + name, DEPTH));
 613  6
             p.add(new NestedPanel("Search " + name, DEPTH));
 614  6
             setContentPane(p);
 615   
         }
 616   
     }
 617   
 
 618   
     /** Create a number of references which have no current match, then
 619   
         test creation of a new reference based on an existing component.
 620   
     */
 621  1
     public void testReferenceCreationPerformanceWithMatchFailures()
 622   
         throws Exception {
 623   
         // Make sure caching is on, since that's what's being measured
 624  1
         ComponentReference.cacheOnCreation = true;
 625   
 
 626   
         // Numbers in parens are with cacheing of unresolved ref results
 627   
         // enabled; cacheing multiple match failures as well as not found
 628   
         // failures results in a reasonable creation time. (winxp, 1.2GHz)
 629   
         // 0=19s (4s), gets exponentially worse
 630   
         // 1=70s (15s)
 631   
         // 2=176s (38s)
 632   
         //
 633   
         // With full cacheing enabled:
 634   
         //  N=time  component count
 635   
         // ------------------------
 636   
         // 10=<1s    197
 637   
         // 20=1.2s   347
 638   
         // 40=3.6s   647
 639   
         // 80=15s   1247 
 640   
         //
 641  1
         SwingUtilities.invokeLater(new Runnable() {
 642  1
             public void run() {
 643  1
                 JOptionPane.showMessageDialog(null, "cref", null, 
 644   
                                               JOptionPane.PLAIN_MESSAGE);
 645   
             }
 646   
         });
 647  1
         Timer timer = new Timer();
 648  1
         while (true) {
 649  1
             try {
 650  1
                 JButton button = (JButton)getFinder().
 651   
                     find(new ClassMatcher(JButton.class));
 652   
                 // Create a reference, then dispose of its match
 653  1
                 ComponentReference existing = getResolver().addComponent(button);
 654  1
                 getHierarchy().dispose(SwingUtilities.getWindowAncestor(button));
 655  1
                 break;
 656   
             }
 657   
             catch(ComponentNotFoundException e) {
 658  0
                 getRobot().waitForIdle();
 659   
             }
 660  0
             if (timer.elapsed() > 10000)
 661  0
                 fail("Timed out waiting for transient dialog to show");
 662   
         }
 663   
 
 664  1
         Frame fa = new MyFrame("A");
 665  1
         Frame fb = new MyFrame("B");
 666  1
         Frame fc = new MyFrame("C");
 667  1
         showWindow(fa);
 668  1
         showWindow(fb);
 669  1
         showWindow(fc);
 670   
 
 671   
         // find a button, any button will do
 672  1
         JButton button2 = (JButton)getFinder().
 673   
             find(fa, new ClassMatcher(JButton.class));
 674   
         
 675  1
         timer.reset();
 676  1
         ComponentReference cref = resolver.addComponent(button2);
 677   
 
 678  1
         assertTrue("Maximum reference creation time exceeded, elapsed time="
 679   
                    + timer.elapsed() + "ms",
 680   
                    timer.elapsed() < MAX_CREATION_TIME);
 681   
     }
 682   
 
 683   
     /** References which match a non-showing component still have to
 684   
      * re-match.
 685   
      */
 686  1
     public void testReferenceCreationPerformanceWithNonShowingMatches() 
 687   
         throws Exception {
 688   
         // Make sure caching is on, since that's what's being measured
 689  1
         ComponentReference.cacheOnCreation = true;
 690   
 
 691  1
         Frame fa = new MyFrame("A");
 692  1
         Frame fb = new MyFrame("B");
 693  1
         Frame fc = new MyFrame("C");
 694  1
         showWindow(fa);
 695  1
         showWindow(fb);
 696  1
         showWindow(fc);
 697   
 
 698   
         // find a button, any button will do
 699  1
         JButton button2 = (JButton)getFinder().
 700   
             find(fa, new ClassMatcher(JButton.class));
 701  1
         JButton button3 = (JButton)getFinder().
 702   
             find(fb, new ClassMatcher(JButton.class));
 703   
         
 704  1
         ComponentReference cref = resolver.addComponent(button2);
 705  1
         fa.setVisible(false);
 706  1
         Timer timer = new Timer();
 707  1
         ComponentReference cref2 = resolver.addComponent(button3);
 708   
 
 709  1
         assertTrue("Maximum reference creation time exceeded, elapsed time="
 710   
                    + timer.elapsed() + "ms",
 711   
                    timer.elapsed() < MAX_CREATION_TIME);
 712   
     }
 713   
 
 714   
     private static int appletCount = 0;
 715   
     private class InvisibleApplet extends Applet {
 716  4
         public InvisibleApplet(final URL url,
 717   
                                final String p1, final String p2) {
 718  4
             setStub(new AppletStub() {
 719  0
                 public void appletResize(int w, int h) { }
 720  0
                 public AppletContext getAppletContext() {
 721  0
                     return null;
 722   
                 }
 723  0
                 public URL getCodeBase() { return null; }
 724  20
                 public URL getDocumentBase() { return url; }
 725  40
                 public String getParameter(String name) {
 726  40
                     return "p1".equals(name) ? p1 : p2;
 727   
                 }
 728  0
                 public boolean isActive() { return true; }
 729   
             });
 730   
             // Install into a frame so that it can be found
 731   
             // Note that all applet frames have a unique location
 732  4
             Frame f = new InvisibleShowingFrame("Dummy Applet Frame");
 733  4
             f.add(InvisibleApplet.this);
 734  4
             f.setLocation(appletCount++, 0);
 735   
         }
 736  20
         public String[][] getParameterInfo() {
 737  20
             String[][] info = {
 738   
                 { "p1", "" },
 739   
                 { "p2", "" },
 740   
             };
 741  20
             return info;
 742   
         }
 743  8
         public boolean isShowing() { return true; }
 744   
     }
 745   
 
 746  1
     public void testFindAppletsByParameter() throws Throwable {
 747   
         // Several identical applets with different parameters
 748  1
         URL url = new URL("http://somewhere.com");
 749  1
         Component c1 = new InvisibleApplet(url, "true", "true");
 750  1
         Component c2 = new InvisibleApplet(url, "true", "false");
 751  1
         ComponentReference cr1 = resolver.addComponent(c1);
 752  1
         ComponentReference cr2 = resolver.addComponent(c2);
 753  1
         assertNotNull("Could not resolve applet 1 by parameter value",
 754   
                       cr1.getComponent());
 755  1
         assertNotNull("Could not resolve applet 2 by parameter value",
 756   
                       cr2.getComponent());
 757   
     }
 758   
 
 759  1
     public void testFindAppletsByDocumentBase() throws Throwable {
 760   
         // Several identical applets with different document base
 761  1
         URL url1 = new URL("http://somewhere.com");
 762  1
         URL url2 = new URL("http://somewhereelse.com");
 763  1
         Component c1 = new InvisibleApplet(url1, "true", "true");
 764  1
         Component c2 = new InvisibleApplet(url2, "true", "true");
 765  1
         ComponentReference cr1 = resolver.addComponent(c1);
 766  1
         ComponentReference cr2 = resolver.addComponent(c2);
 767  1
         assertNotNull("Could not resolve applet 1 by doc base", cr1.getComponent());
 768  1
         assertNotNull("Could not resolve applet 2 by doc base", cr2.getComponent());
 769   
     }
 770   
 
 771  1
     public void testDynamicButtonLabel() throws Throwable {
 772  1
         JPanel pane = new JPanel();
 773  1
         JPanel pane1 = new JPanel();
 774  1
         JPanel root = new JPanel();
 775  1
         final JButton button = new JButton("Open");
 776  1
         pane.add(button);
 777  1
         pane.add(new JButton("Wink"));
 778  1
         pane.add(new JButton("Yank"));
 779  1
         root.add(pane);
 780   
 
 781  1
         pane1.add(new JButton("This"));
 782  1
         pane1.add(new JButton("That"));
 783  1
         root.add(pane1);
 784  1
         showFrame(root);
 785  1
         ComponentReference ref = resolver.addComponent(button);
 786  1
         getRobot().click(button);
 787  1
         getRobot().waitForIdle();
 788  1
         button.setText("Close");
 789   
 
 790  1
         ref.setAttribute(XMLConstants.TAG_TEXT, "/Open|Close/");
 791  1
         assertNotNull("Could not find button after label change",
 792   
                       ref.getComponent());
 793   
     }
 794   
 
 795   
     // These factory-created methods check for factory-created components
 796   
     // where a subsequent version is shown without necessarily disposing the
 797   
     // previous one
 798   
 
 799  1
     public void testFactoryWithUnparentPrevious() throws Exception {
 800  1
         JButton ok1 = new JButton("ok") { public String toString() {
 801  1
             return "ok 1"; }};
 802  1
         ok1.setName("ok");
 803  0
         JButton ok2 = new JButton("ok") { public String toString() {
 804  0
             return "ok 2"; }};
 805  1
         ok2.setName("ok");
 806  1
         Frame f1 = showFrame(ok1);
 807  1
         ComponentReference ref = getResolver().addComponent(ok1);
 808  1
         assertEquals("Initial lookup failed for " + ref,
 809   
                      ok1, ref.getComponent());
 810   
         // disposal by removing references
 811  1
         hideWindow(f1);
 812  1
         f1.removeAll();
 813   
 
 814  1
         Frame f2 = showFrame(ok2);
 815  1
         assertEquals("Cached value should not be used if it has no Window",
 816   
                      ok2, ref.getComponent());
 817   
     }
 818   
 
 819  1
     public void testFactoryPreferShowing() throws Exception {
 820  1
         JButton ok1 = new JButton("ok") { public String toString() {
 821  1
             return "ok 1"; }};
 822  1
         ok1.setName("ok");
 823  0
         JButton ok2 = new JButton("ok") { public String toString() {
 824  0
             return "ok 2"; }};
 825  1
         ok2.setName("ok");
 826  1
         Frame f1 = showFrame(ok1);
 827  1
         ComponentReference ref = getResolver().addComponent(ok1);
 828  1
         assertEquals("Initial lookup failed for " + ref,
 829   
                      ok1, ref.getComponent());
 830   
         // simulate "I forgot to dispose"
 831  1
         hideWindow(f1);
 832   
 
 833  1
         Frame f2 = showFrame(ok2);
 834  1
         assertEquals("Showing component should be preferred for " + ref,
 835   
                      ok2, ref.getComponent());
 836   
     }
 837   
 
 838  1
     public void testFactorySelectAmongHidden() throws Exception {
 839  1
         JButton ok1 = new JButton("ok") { public String toString() {
 840  1
             return "ok 1"; }};
 841  1
         ok1.setName("ok");
 842  0
         JButton ok2 = new JButton("ok") { public String toString() {
 843  0
             return "ok 2"; }};
 844  1
         ok2.setName("ok");
 845  1
         Frame f1 = showFrame(ok1);
 846  1
         ComponentReference ref = getResolver().addComponent(ok1);
 847  1
         assertEquals("Initial lookup failed for " + ref,
 848   
                      ok1, ref.getComponent());
 849  1
         hideWindow(f1);
 850   
 
 851  1
         Frame f2 = showFrame(ok2);
 852  1
         hideWindow(f2);
 853   
 
 854  1
         assertEquals("Cached result should be used if all options are hidden",
 855   
                      ok1, ref.getComponent());
 856   
     }
 857   
 
 858   
     /** Thanks to jimdoyle@users.sf.net for tracking this down. */
 859  1
     public void testFindJTabbedPaneDescendant() {
 860  1
         JTabbedPane tabs = new JTabbedPane();
 861  1
         JButton button = null;
 862  1
         int NEST = 10; // 2->750ms, 3->1.4s, 4->7s, 5->142s
 863  1
         int TABS = 2;
 864  1
         for(int t=0;t < TABS;t++) {
 865  2
             Container parent = tabs;
 866  2
             JPanel panel;
 867  2
             for (int i=0;i < NEST;i++) {
 868  20
                 panel = new JPanel();
 869  20
                 parent.add(panel);
 870  20
                 parent = panel;
 871   
             }
 872  2
             parent.add(button = new JButton("tab " + t));
 873   
         }
 874  1
         showFrame(tabs);
 875  1
         Timer timer = new Timer();
 876  1
         ComponentReference ref = resolver.addComponent(button);
 877  1
         if (timer.elapsed() > 500) 
 878  0
             fail("Creation of non-visible tabbed pane component took "
 879   
                  + timer.elapsed() + "ms");
 880   
     }
 881   
 
 882  1
     public void testFindJScrollBar() {
 883  1
         JScrollPane pane = new JScrollPane(new JLabel(getName()));
 884  1
         pane.setHorizontalScrollBarPolicy(JScrollPane.
 885   
                                           HORIZONTAL_SCROLLBAR_NEVER);
 886  1
         showFrame(pane);
 887  1
         ComponentReference ref =resolver.addComponent(pane.getHorizontalScrollBar());
 888  1
         assertTrue("Could not create ref", ref != null);
 889   
     }
 890   
 
 891  1
     public void testBestExistingMatch() throws Exception {
 892  1
         JPanel panel1 = new JPanel();
 893  1
         JButton b1 = new JButton("b1");
 894  1
         panel1.add(b1);
 895  1
         JPanel panel2 = new JPanel();
 896  1
         JButton b2 = new JButton("b2");
 897  1
         panel2.add(b2);
 898  1
         JPanel top = new JPanel();
 899  1
         top.add(panel1); top.add(panel2);
 900  1
         showFrame(top);
 901   
 
 902  1
         ComponentReference ref1 = resolver.addComponent(b1);
 903  1
         ComponentReference ref2 = resolver.addComponent(b2);
 904   
 
 905  1
         Collection refs = resolver.getComponentReferences();
 906  1
         assertEquals("Incorrect first match", ref1, 
 907   
                      ComponentReference.matchExisting(b1, refs));
 908  1
         assertEquals("Incorrect second match", ref2, 
 909   
                      ComponentReference.matchExisting(b2, refs));
 910   
     }
 911   
 
 912   
 
 913  1
     public void testMatchOrphanedComponent() throws Exception {
 914  1
         final JPanel panel = new JPanel();
 915  1
         final ArrayList list = new ArrayList();
 916  1
         for (int i=0;i < 2;i++) {
 917  2
             list.add(new JButton("button " + i));
 918   
         }
 919  1
         Component c = (Component)list.get(0);
 920  1
         Component c2 = (Component)list.get(1);
 921  1
         JButton button = new JButton("Change");
 922  1
         button.addActionListener(new ActionListener() {
 923   
             private int index;
 924  2
             public void actionPerformed(ActionEvent e) {
 925  2
                 panel.remove((Component)list.get(index));
 926  2
                 if (++index == list.size())
 927  1
                     index = 0;
 928  2
                 panel.add((Component)list.get(index));
 929  2
                 panel.revalidate();
 930  2
                 panel.repaint();
 931   
             }
 932   
         });
 933  1
         panel.add(button);
 934  1
         panel.add((Component)list.get(0));
 935  1
         showFrame(panel);
 936   
 
 937  1
         ComponentReference ref = resolver.addComponent(c);
 938  1
         Collection refs = resolver.getComponentReferences();
 939  1
         assertEquals("Component should match existing reference", 
 940   
                      ref, ComponentReference.matchExisting(c, refs));
 941   
 
 942   
         // makes second button display
 943  1
         button.doClick();
 944   
         // components are not guaranteed to match if they are no longer in the
 945   
         // hierarchy. 
 946   
         /*
 947   
         assertEquals("First component should still match when excised",
 948   
                      ref, ComponentReference.matchExisting(c, refs));
 949   
         */
 950   
 
 951   
         // NOTE: force a reference creation; otherwise fuzzy matching will
 952   
         // cause the second component to match the first reference (as it
 953   
         // should). 
 954  1
         ComponentReference ref2 =
 955   
             new ComponentReference(resolver, c2, newRefs);
 956  1
         Iterator iter = newRefs.keySet().iterator();
 957  1
         while (iter.hasNext()) {
 958  1
             ComponentReference tmp = (ComponentReference)
 959   
                 newRefs.get(iter.next());
 960  1
             resolver.addComponentReference(tmp);
 961   
         }
 962   
 
 963   
         // NOTE: this is a slight variation of "best existing match".  Ensure
 964   
         // that we get the best match when more than one ref would pass a
 965   
         // fuzzy match.
 966  1
         refs = resolver.getComponentReferences();
 967  1
         assertEquals("Second component should match proper existing ref", 
 968   
                      ref2, ComponentReference.matchExisting(c2, refs));
 969   
 
 970   
         // Make first button display
 971  1
         button.doClick();
 972  1
         assertEquals("First component should match existing ref when restored",
 973   
                      ref, ComponentReference.matchExisting(c, refs));
 974   
         // components are not guaranteed to match if they are no longer in the
 975   
         // hierarchy. 
 976   
         /*
 977   
         assertEquals("Second component should still match when excised",
 978   
                      ref2, ComponentReference.matchExisting(c2, refs));
 979   
         */
 980   
     }
 981   
 
 982  33
     public ComponentReferenceTest(String name) {
 983  33
         super(name);
 984   
     }
 985   
 
 986  0
     public static void main(String[] args) {
 987  0
         TestHelper.runTests(args, ComponentReferenceTest.class);
 988   
     }
 989   
 }
 990