0001: package abbot.script;
0002:
0003: import java.applet.*;
0004: import java.awt.*;
0005: import java.awt.event.*;
0006: import java.net.URL;
0007: import java.util.*;
0008: import javax.swing.*;
0009: import javax.swing.border.*;
0010:
0011: import junit.extensions.abbot.*;
0012: import junit.extensions.abbot.Timer;
0013: import abbot.Log;
0014: import abbot.finder.*;
0015: import abbot.finder.matchers.*;
0016:
0017: /**
0018: * Verify various ComponentReference requirements.
0019: */
0020: // TODO: test new refs aren't added to Resolver
0021: // TODO: new refs all get unique IDs
0022: // TODO: more clearly delineate rules instead of random tests
0023: public class ComponentReferenceTest extends ResolverFixture implements
0024: XMLConstants {
0025:
0026: private Map newRefs;
0027: private Resolver resolver;
0028:
0029: protected void setUp() {
0030: newRefs = new HashMap();
0031: resolver = getResolver();
0032: // allow easy creation of references, but force initial lookups
0033: ComponentReference.cacheOnCreation = false;
0034: }
0035:
0036: protected void tearDown() {
0037: newRefs = null;
0038: resolver = null;
0039: ComponentReference.cacheOnCreation = true;
0040: }
0041:
0042: public void testInnerClassMatch() {
0043: ComponentReference cr = new ComponentReference(resolver,
0044: Component.class, new HashMap());
0045: assertTrue("Anonymous inner class not detected", cr
0046: .expressionMatch(ComponentReference.ANON_INNER_CLASS,
0047: "my.class.Name$12"));
0048: assertTrue("Anonymous inner class falsely detected", !cr
0049: .expressionMatch(ComponentReference.ANON_INNER_CLASS,
0050: "my.class.Name$InnerClass"));
0051: }
0052:
0053: /** Saved class name should not be an anonymous or inner class. */
0054: public void testUseCanonicalClass() {
0055: ComponentReference cr = new ComponentReference(resolver,
0056: new Frame(getName()) {
0057: public String toString() {
0058: return getName();
0059: }
0060: });
0061: assertEquals("Wrong class saved", Frame.class.getName(), cr
0062: .getRefClassName());
0063: }
0064:
0065: /** Any newly created reference should match against the component it was
0066: * created from.
0067: */
0068: public void testAddComponent() throws Throwable {
0069: JTextField tf = new JTextField();
0070: tf.setColumns(20);
0071: showFrame(tf);
0072: ComponentReference ref = resolver.addComponent(tf);
0073: assertEquals(
0074: "Newly created component reference does not match", tf,
0075: ref.getComponent());
0076: }
0077:
0078: /** Create a reference for a dialog child of a dialog.
0079: Bug reported by vladgur.
0080: */
0081: public void testAddSubDialog() {
0082: JFrame frame = new JFrame(getName());
0083: JDialog d1 = new JDialog(frame, "Modal", true);
0084: d1.getContentPane().add(new JLabel("Modal Dialog"));
0085: JDialog d2 = new JDialog(d1, "Non-Modal", false);
0086: d2.getContentPane().add(new JLabel("Non-Modal Dialog"));
0087: showWindow(d1);
0088: showWindow(d2);
0089: ComponentReference ref = new ComponentReference(resolver, d2
0090: .getContentPane(), newRefs);
0091: assertNotNull("Can't create subdialog reference", ref);
0092: }
0093:
0094: /**
0095: * Test to see if the label and index can identify a component
0096: */
0097: public void testSiblings() {
0098: JTextField tf1 = new JTextField();
0099: JTextField tf2 = new JTextField();
0100: tf1.setColumns(10);
0101: tf2.setColumns(10);
0102: JPanel pane = new JPanel();
0103: pane.add(tf1);
0104: pane.add(tf2);
0105:
0106: showFrame(pane);
0107:
0108: ComponentReference cr1 = resolver.addComponent(tf1);
0109: ComponentReference cr2 = resolver.addComponent(tf2);
0110: assertTrue("Should get two unique references", cr1 != cr2);
0111:
0112: try {
0113: assertEquals("Incorrect sibling 1 lookup with " + cr1, tf1,
0114: cr1.getComponent());
0115: assertEquals("Incorrect sibling 2 lookup with " + cr2, tf2,
0116: cr2.getComponent());
0117: } catch (ComponentNotFoundException cnf) {
0118: fail(cnf.toString());
0119: } catch (MultipleComponentsFoundException mcf) {
0120: fail(mcf.toString());
0121: }
0122: }
0123:
0124: /**
0125: * Verify two identical sibling components can be distinguished.
0126: */
0127: public void testIdenticalSiblings() {
0128: JButton button1 = new JButton("Button");
0129: JButton button2 = new JButton("Button");
0130: JPanel pane = new JPanel();
0131: pane.add(button1);
0132: pane.add(button2);
0133:
0134: showFrame(pane);
0135:
0136: ComponentReference cr1 = resolver.addComponent(button1);
0137: ComponentReference cr2 = resolver.addComponent(button2);
0138: assertTrue("Should get two unique references", cr1 != cr2);
0139:
0140: try {
0141: assertEquals("Incorrect sibling button 1 lookup with "
0142: + cr1, button1, cr1.getComponent());
0143: assertEquals("Incorrect sibling button 2 lookup with "
0144: + cr2, button2, cr2.getComponent());
0145: } catch (ComponentNotFoundException cnf) {
0146: fail(cnf.toString());
0147: } catch (MultipleComponentsFoundException mcf) {
0148: fail(mcf.toString());
0149: }
0150: }
0151:
0152: /**
0153: * Verify two identical cousin (sibling parents) components can be
0154: * distinguished.
0155: */
0156: public void testIdenticalCousins() {
0157: JButton button1 = new JButton("Button");
0158: JButton button2 = new JButton("Button");
0159: JPanel panel1 = new JPanel();
0160: JPanel panel2 = new JPanel();
0161: panel1.add(button1);
0162: panel2.add(button2);
0163:
0164: JPanel pane = new JPanel();
0165: pane.add(panel1);
0166: pane.add(panel2);
0167:
0168: showFrame(pane);
0169:
0170: ComponentReference cr1 = resolver.addComponent(button1);
0171: ComponentReference cr2 = resolver.addComponent(button2);
0172: assertTrue("Should get two unique references", cr1 != cr2);
0173:
0174: try {
0175: assertEquals(
0176: "Incorrect cousin button 1 lookup with " + cr1,
0177: button1, cr1.getComponent());
0178: assertEquals(
0179: "Incorrect cousin button 2 lookup with " + cr2,
0180: button2, cr2.getComponent());
0181: } catch (ComponentNotFoundException cnf) {
0182: fail(cnf.toString());
0183: } catch (MultipleComponentsFoundException mcf) {
0184: fail(mcf.toString());
0185: }
0186: }
0187:
0188: /**
0189: * Test to see if two buttons which are identical except for their name
0190: * and index can be found
0191: */
0192: public void testTwoNamedButtons() {
0193: JButton button1 = new JButton("Button");
0194: JButton button2 = new JButton("Button");
0195: JPanel panel1 = new JPanel();
0196: JPanel panel2 = new JPanel();
0197:
0198: button1.setName("Button1");
0199: button2.setName("Button2");
0200:
0201: panel1.add(button1);
0202: panel2.add(button2);
0203: JPanel pane = new JPanel();
0204: pane.add(panel1);
0205: pane.add(panel2);
0206:
0207: showFrame(pane);
0208:
0209: ComponentReference cr1 = resolver.addComponent(button1);
0210: ComponentReference cr2 = resolver.addComponent(button2);
0211: assertTrue("Should get two unique references", cr1 != cr2);
0212:
0213: try {
0214: assertEquals("Button 1 not found", button1, cr1
0215: .getComponent());
0216: assertEquals("Button 2 not found", button2, cr2
0217: .getComponent());
0218: } catch (ComponentNotFoundException cnf) {
0219: fail(cnf.toString());
0220: } catch (MultipleComponentsFoundException mcf) {
0221: fail(mcf.toString());
0222: }
0223: }
0224:
0225: /**
0226: * Test to ensure that index can be used on otherwise indistingushable
0227: * components
0228: */
0229: public void testIdenticalLabelGroup() {
0230:
0231: final int NUM_LABELS = 10;
0232:
0233: ArrayList labels = new ArrayList();
0234: ArrayList refs = new ArrayList();
0235:
0236: JPanel pane = new JPanel();
0237: showFrame(pane);
0238: for (int i = 0; i < NUM_LABELS; ++i) {
0239: JLabel label = new JLabel("Empty");
0240: labels.add(label);
0241: pane.add(label);
0242: refs.add(resolver.addComponent(label));
0243: }
0244:
0245: for (int i = 0; i < NUM_LABELS - 1; ++i) {
0246: for (int next = i + 1; next < NUM_LABELS; next++) {
0247: Component c1 = (Component) labels.get(i);
0248: Component c2 = (Component) labels.get(next);
0249: ComponentReference cr1 = (ComponentReference) refs
0250: .get(i);
0251: ComponentReference cr2 = (ComponentReference) refs
0252: .get(next);
0253:
0254: try {
0255: assertEquals("label " + i + " not found", c1, cr1
0256: .getComponent());
0257: assertEquals("label " + next + " not found", c2,
0258: cr2.getComponent());
0259: } catch (ComponentNotFoundException cnf) {
0260: fail(cnf.toString());
0261: } catch (MultipleComponentsFoundException mcf) {
0262: fail(mcf.toString());
0263: }
0264: }
0265: }
0266: }
0267:
0268: /** Ensure that find window works with JOptionPane-generated
0269: * components. */
0270: public void testDuplicateJOptionPanes() throws Throwable {
0271: JOptionPane pane = new JOptionPane("A message",
0272: JOptionPane.INFORMATION_MESSAGE);
0273: JFrame frame = new JFrame(getName());
0274: Dialog dialog = pane.createDialog(frame, "Dialog");
0275: showWindow(dialog);
0276: dialog.setVisible(false);
0277: Timer timer = new Timer();
0278: while (dialog.isShowing()) {
0279: if (timer.elapsed() > 5000)
0280: throw new RuntimeException(
0281: "Timed out waiting for dialog to hide");
0282: getRobot().sleep();
0283: }
0284: JOptionPane pane2 = new JOptionPane("A message",
0285: JOptionPane.INFORMATION_MESSAGE);
0286: Dialog d2 = pane2.createDialog(frame, "Dialog 2");
0287: showWindow(d2);
0288: Component comp = getFinder().find(
0289: new WindowMatcher(d2.getTitle()));
0290: assertEquals("Wrong JOptionPane found", d2, comp);
0291: }
0292:
0293: private class ButtonMatcher implements Matcher {
0294: private String text = null;
0295:
0296: public ButtonMatcher() {
0297: this (null);
0298: }
0299:
0300: public ButtonMatcher(String text) {
0301: this .text = text;
0302: }
0303:
0304: public boolean matches(Component c) {
0305: return c instanceof JButton
0306: && (text == null || ((JButton) c).getText().equals(
0307: text));
0308: }
0309: }
0310:
0311: /** Component reference matching one dialog should match an identical
0312: * subsequent one using the same JOptionPane.
0313: */
0314: public void testSubsequentDialogContentsLookup() throws Throwable {
0315: ComponentReference ref = new ComponentReference(resolver,
0316: javax.swing.JButton.class, new String[][] { {
0317: XMLConstants.TAG_TEXT, "OK" } });
0318: Dialog d1 = null;
0319: Dialog d2 = null;
0320: JFrame frame = new JFrame(getName());
0321: JOptionPane pane = new JOptionPane("Dialog",
0322: JOptionPane.INFORMATION_MESSAGE);
0323: d1 = pane.createDialog(frame, "Dialog");
0324: showWindow(d1);
0325: JButton button = (JButton) getFinder().find(d1,
0326: new ButtonMatcher());
0327: assertNotNull("Button shouldn't be null", button);
0328: assertEquals("Wrong component found", button, ref
0329: .getComponent(getHierarchy()));
0330: d1.setVisible(false);
0331:
0332: d2 = pane.createDialog(frame, "Dialog");
0333: showWindow(d2);
0334: JButton button2 = (JButton) getFinder().find(d2,
0335: new ButtonMatcher());
0336: assertNotNull("Second button lookup shouldn't be null", button2);
0337: assertEquals("Same button should be used", button2, button);
0338: assertEquals("Wrong component found with " + ref, button2, ref
0339: .getComponent(getHierarchy()));
0340: }
0341:
0342: public void testJFileChooserReferences() throws Exception {
0343: final JFileChooser chooser = new JFileChooser();
0344: final Frame frame = showFrame(new JLabel(getName()));
0345: Dialog d1 = showModalDialog(new Runnable() {
0346: public void run() {
0347: chooser.showOpenDialog(frame);
0348: }
0349: });
0350: // Don't care if we get Open or Cancel
0351: JButton button = (JButton) getFinder().find(
0352: new ClassMatcher(JButton.class, true));
0353:
0354: ComponentReference ref = resolver.addComponent(d1);
0355: ComponentReference bref = resolver.addComponent(button);
0356:
0357: assertEquals("First file dialog not found", d1, ref
0358: .getComponent());
0359: assertEquals("Dialog button not found", button, bref
0360: .getComponent());
0361: // must dispose, not hide; otherwise it will still match
0362: disposeWindow(d1);
0363:
0364: Dialog d2 = showModalDialog(new Runnable() {
0365: public void run() {
0366: chooser.showOpenDialog(frame);
0367: }
0368: });
0369: assertTrue("JFileChooser presented same dialog", d1 != d2);
0370: assertEquals("Incorrect subsequent file dialog found with "
0371: + ref, d2, ref.getComponent());
0372: assertEquals("Same button should be used on both dialogs",
0373: button, bref.getComponent());
0374: }
0375:
0376: public void testFindMenuItem() throws Throwable {
0377: JMenuItem mi = new JMenuItem("item");
0378: JMenu menu = new JMenu("menu");
0379: JMenuBar mb = new JMenuBar();
0380: mb.add(menu);
0381: menu.add(mi);
0382: JFrame frame = new JFrame(getName());
0383: frame.setJMenuBar(mb);
0384: showWindow(frame);
0385: ComponentReference ref = resolver.addComponent(mi);
0386: assertEquals("Menu item not found: " + ref, mi, ref
0387: .getComponent());
0388: }
0389:
0390: public void testConsistentDefaultFrameReference() throws Throwable {
0391: // Default frame should always get the same reference
0392: JOptionPane pane = new JOptionPane("Dialog",
0393: JOptionPane.INFORMATION_MESSAGE);
0394: Dialog d1 = pane.createDialog(null, "Dialog");
0395: showWindow(d1);
0396: ComponentReference ref1 = resolver.addComponent(d1);
0397: d1 = pane.createDialog(null, "Dialog2");
0398: showWindow(d1);
0399: ComponentReference ref2 = resolver.addComponent(d1);
0400: assertEquals(
0401: "Option pane dialogs should share same default frame",
0402: ref1.getAttribute(TAG_PARENT), ref2
0403: .getAttribute(TAG_PARENT));
0404: assertEquals("Incorrect ID for shared frame instance",
0405: ComponentReference.SHARED_FRAME_ID, ref1
0406: .getAttribute(TAG_PARENT));
0407: }
0408:
0409: public void testRootReference() {
0410: JFrame frame = new JFrame(getName());
0411: showWindow(frame);
0412: Dialog d = new JDialog(frame, getName() + " Dialog");
0413: showWindow(d);
0414: ComponentReference ref = resolver.addComponent(frame);
0415: ComponentReference ref1 = resolver.addComponent(d);
0416: assertEquals("Component should be root", "true", ref
0417: .getAttribute(TAG_ROOT));
0418: assertNull("Component should not be root", ref1
0419: .getAttribute(TAG_ROOT));
0420: }
0421:
0422: public void testFindDialogWithHiddenFrame() throws Throwable {
0423: JFrame frame = new JFrame(getName());
0424: Dialog d1 = new JDialog(frame, getName() + " Dialog");
0425: showWindow(d1);
0426: ComponentReference ref = resolver.addComponent(d1);
0427: assertEquals("Dialog not found", d1, ref.getComponent());
0428: }
0429:
0430: public void testIndexlessHorizontalOrdering() throws Throwable {
0431: // Ensure that several components differing only by horizontal
0432: // location can be distinguished. Use Frames, so that the parent
0433: // index does not come into play.
0434: // Note that this ordering is only really meaningful to embedded
0435: // frames (and thus applets) which can not otherwise be moved or
0436: // resized independengly of one another.
0437: Component c1 = new InvisibleShowingFrame("Same");
0438: Component c2 = new InvisibleShowingFrame("Same");
0439: Component c3 = new InvisibleShowingFrame("Same");
0440: c1.setLocation(100, 100);
0441: c1.setSize(100, 100);
0442: c2.setLocation(200, 100);
0443: c2.setSize(100, 100);
0444: c3.setLocation(300, 100);
0445: c3.setSize(100, 100);
0446:
0447: ComponentReference cr1 = resolver.addComponent(c1);
0448: ComponentReference cr2 = resolver.addComponent(c2);
0449: ComponentReference cr3 = resolver.addComponent(c3);
0450:
0451: assertNotNull("Leftmost frame not found", cr1.getComponent());
0452: assertNotNull("Middle frame not found", cr2.getComponent());
0453: assertNotNull("Rightmost frame not found", cr3.getComponent());
0454:
0455: c1.setLocation(200, 100);
0456: c2.setLocation(300, 100);
0457: c3.setLocation(400, 100);
0458:
0459: assertNotNull("Leftmost frame not found", cr1.getComponent());
0460: assertNotNull("Middle frame not found", cr2.getComponent());
0461: assertNotNull("Rightmost frame not found", cr3.getComponent());
0462: }
0463:
0464: public void testDescendentIndexlessHorizontalOrdering()
0465: throws Throwable {
0466: // Similar to the IndexlessHorizontalOrdering, except that children
0467: // are checked, where the only difference is the window reference.
0468: Frame f1 = new InvisibleShowingFrame("Same");
0469: Frame f2 = new InvisibleShowingFrame("Same");
0470: Component c1 = new JLabel(getName());
0471: Component c2 = new JLabel(getName());
0472: f1.add(c1);
0473: f2.add(c2);
0474: f1.setLocation(100, 100);
0475: f1.setSize(100, 100);
0476: f2.setLocation(200, 100);
0477: f2.setSize(100, 100);
0478: ComponentReference cr1 = resolver.addComponent(c1);
0479: ComponentReference cr2 = resolver.addComponent(c2);
0480: assertNotNull("Leftmost component not found", cr1
0481: .getComponent());
0482: assertNotNull("Rightmost component not found", cr2
0483: .getComponent());
0484: }
0485:
0486: public void testIndexlessVerticalOrdering() throws Throwable {
0487: // Ensure that several components differing only by vertical
0488: // location can be distinguished. Use Frames, so that the parent
0489: // index does not come into play.
0490: // Note that this ordering is only really meaningful to embedded
0491: // frames (and thus applets) which can not otherwise be moved or
0492: // resized independengly of one another.
0493: Component c1 = new InvisibleShowingFrame("Same");
0494: Component c2 = new InvisibleShowingFrame("Same");
0495: Component c3 = new InvisibleShowingFrame("Same");
0496: c1.setLocation(100, 100);
0497: c1.setSize(100, 100);
0498: c2.setLocation(100, 200);
0499: c2.setSize(100, 100);
0500: c3.setLocation(100, 300);
0501: c3.setSize(100, 100);
0502:
0503: ComponentReference cr1 = resolver.addComponent(c1);
0504: ComponentReference cr2 = resolver.addComponent(c2);
0505: ComponentReference cr3 = resolver.addComponent(c3);
0506:
0507: assertNotNull("Top frame not found", cr1.getComponent());
0508: assertNotNull("Middle frame not found", cr2.getComponent());
0509: assertNotNull("Bottom frame not found", cr3.getComponent());
0510:
0511: c1.setLocation(100, 200);
0512: c2.setLocation(100, 300);
0513: c3.setLocation(100, 400);
0514:
0515: assertNotNull("Top frame not found", cr1.getComponent());
0516: assertNotNull("Middle frame not found", cr2.getComponent());
0517: assertNotNull("Bottom frame not found", cr3.getComponent());
0518: }
0519:
0520: private class InvisibleShowingFrame extends Frame {
0521: private Point location;
0522:
0523: public InvisibleShowingFrame(String title) {
0524: super (title);
0525: }
0526:
0527: public boolean isShowing() {
0528: return true;
0529: }
0530:
0531: // All other methods defer to this one
0532: public void setBounds(int x, int y, int width, int height) {
0533: super .setBounds(x, y, width, height);
0534: if (location == null)
0535: location = new Point(x, y);
0536: else
0537: location.setLocation(x, y);
0538: }
0539:
0540: public Point getLocationOnScreen() {
0541: return getLocation();
0542: }
0543:
0544: public Point getLocation() {
0545: if (location == null)
0546: location = new Point(0, 0);
0547: return location;
0548: }
0549: }
0550:
0551: public void testOrder() {
0552: Component c1 = new InvisibleShowingFrame("Same");
0553: Component c2 = new InvisibleShowingFrame("Same");
0554: Component c3 = new InvisibleShowingFrame("Same");
0555: c1.setLocation(100, 100);
0556: c1.setSize(100, 100);
0557: c2.setLocation(100, 200);
0558: c2.setSize(100, 100);
0559: c3.setLocation(200, 200);
0560: c3.setSize(100, 100);
0561: Component[] all = { c1, c2, c3 };
0562: assertEquals("Wrong leftmost order", "0", ComponentReference
0563: .getOrder(c1, all, true));
0564: assertEquals("Wrong middle order", "0", ComponentReference
0565: .getOrder(c2, all, true));
0566: assertEquals("Wrong rightmost order", "1", ComponentReference
0567: .getOrder(c3, all, true));
0568: assertEquals("Wrong top order", "0", ComponentReference
0569: .getOrder(c1, all, false));
0570: assertEquals("Wrong middle order", "1", ComponentReference
0571: .getOrder(c2, all, false));
0572: assertEquals("Wrong bottom order", "1", ComponentReference
0573: .getOrder(c3, all, false));
0574:
0575: }
0576:
0577: private static final int MAX_CREATION_TIME = 10000; //ms
0578:
0579: public void testBasicReferenceCreationPerformance()
0580: throws Throwable {
0581: // Make sure caching is on, since that's what's being measured
0582: ComponentReference.cacheOnCreation = true;
0583: // NOTE: need for this test was triggered by slowness in recording.
0584: // Scrollpanes (maybe w/all their buttons?) cause significant
0585: // slowdown.
0586: JPanel p1 = new JPanel();
0587: JButton b1 = new JButton("Label");
0588: p1.add(b1);
0589: p1.add(new JScrollPane(new JButton("Label")));
0590: p1.add(new JScrollPane(new JTextField("Label")));
0591: p1.add(new JScrollPane(new JComboBox()));
0592: p1.add(new JScrollPane(new JTree()));
0593: Frame f1 = showFrame(p1);
0594: getRobot().move(f1, 100, 100);
0595: getRobot().waitForIdle();
0596:
0597: Timer timer = new Timer();
0598: ComponentReference ref1 = resolver.addComponent(b1);
0599: long elapsed = timer.elapsed();
0600: assertTrue("Too long to create reference: " + elapsed + "ms",
0601: elapsed < MAX_CREATION_TIME);
0602: if (elapsed > MAX_CREATION_TIME / 5)
0603: Log.warn("Slow cref creation time: " + elapsed + "ms");
0604:
0605: JPanel p2 = new JPanel();
0606: JButton b2 = new JButton("Label");
0607: p2.add(b2);
0608: p2.add(new JScrollPane(new JButton("Label")));
0609: p2.add(new JScrollPane(new JTextField("Label")));
0610: p2.add(new JScrollPane(new JComboBox()));
0611: p2.add(new JScrollPane(new JTree()));
0612: Frame f2 = showFrame(p2);
0613: getRobot().move(f2, 101, 100);
0614: getRobot().waitForIdle();
0615:
0616: timer.reset();
0617: ComponentReference ref2 = resolver.addComponent(b2);
0618: elapsed = timer.elapsed();
0619: assertTrue("Too long to create reference (using ordering): "
0620: + elapsed, elapsed < MAX_CREATION_TIME);
0621: if (elapsed > MAX_CREATION_TIME / 5)
0622: Log.warn("Slow cref creation time: " + elapsed + "ms");
0623: }
0624:
0625: private static final int DEPTH = 10;
0626:
0627: private class NestedPanel extends JPanel {
0628: public NestedPanel(String name, int level) {
0629: setBorder(new EmptyBorder(0, 0, 0, 0));
0630: if (level > 0)
0631: add(new NestedPanel(name, --level));
0632: else {
0633: JButton b = new JButton(name);
0634: add(b);
0635: b.addActionListener(new ActionListener() {
0636: public void actionPerformed(ActionEvent e) {
0637: JOptionPane.showMessageDialog(null, "message",
0638: null, JOptionPane.PLAIN_MESSAGE);
0639: }
0640: });
0641: }
0642: }
0643: }
0644:
0645: private class MyFrame extends JFrame {
0646: public MyFrame(String name) {
0647: super (name);
0648: JPanel p = new JPanel();
0649: p.add(new NestedPanel("Submit " + name, DEPTH));
0650: p.add(new NestedPanel("Retrieve " + name, DEPTH));
0651: p.add(new NestedPanel("New " + name, DEPTH));
0652: p.add(new NestedPanel("Edit " + name, DEPTH));
0653: p.add(new NestedPanel("Search " + name, DEPTH));
0654: setContentPane(p);
0655: }
0656: }
0657:
0658: /** Create a number of references which have no current match, then
0659: test creation of a new reference based on an existing component.
0660: */
0661: public void testReferenceCreationPerformanceWithMatchFailures()
0662: throws Exception {
0663: // Make sure caching is on, since that's what's being measured
0664: ComponentReference.cacheOnCreation = true;
0665:
0666: // Numbers in parens are with cacheing of unresolved ref results
0667: // enabled; cacheing multiple match failures as well as not found
0668: // failures results in a reasonable creation time. (winxp, 1.2GHz)
0669: // 0=19s (4s), gets exponentially worse
0670: // 1=70s (15s)
0671: // 2=176s (38s)
0672: //
0673: // With full cacheing enabled:
0674: // N=time component count
0675: // ------------------------
0676: // 10=<1s 197
0677: // 20=1.2s 347
0678: // 40=3.6s 647
0679: // 80=15s 1247
0680: //
0681: SwingUtilities.invokeLater(new Runnable() {
0682: public void run() {
0683: JOptionPane.showMessageDialog(null, "cref", null,
0684: JOptionPane.PLAIN_MESSAGE);
0685: }
0686: });
0687: Timer timer = new Timer();
0688: while (true) {
0689: try {
0690: JButton button = (JButton) getFinder().find(
0691: new ClassMatcher(JButton.class));
0692: // Create a reference, then dispose of its match
0693: ComponentReference existing = getResolver()
0694: .addComponent(button);
0695: getHierarchy().dispose(
0696: SwingUtilities.getWindowAncestor(button));
0697: break;
0698: } catch (ComponentNotFoundException e) {
0699: getRobot().waitForIdle();
0700: }
0701: if (timer.elapsed() > 10000)
0702: fail("Timed out waiting for transient dialog to show");
0703: }
0704:
0705: Frame fa = new MyFrame("A");
0706: Frame fb = new MyFrame("B");
0707: Frame fc = new MyFrame("C");
0708: showWindow(fa);
0709: showWindow(fb);
0710: showWindow(fc);
0711:
0712: // find a button, any button will do
0713: JButton button2 = (JButton) getFinder().find(fa,
0714: new ClassMatcher(JButton.class));
0715:
0716: timer.reset();
0717: ComponentReference cref = resolver.addComponent(button2);
0718:
0719: assertTrue(
0720: "Maximum reference creation time exceeded, elapsed time="
0721: + timer.elapsed() + "ms",
0722: timer.elapsed() < MAX_CREATION_TIME);
0723: if (timer.elapsed() > MAX_CREATION_TIME / 5)
0724: Log.warn("Slow cref creation time: " + timer.elapsed()
0725: + "ms");
0726: }
0727:
0728: /** References which match a non-showing component still have to
0729: * re-match.
0730: */
0731: public void testReferenceCreationPerformanceWithNonShowingMatches()
0732: throws Exception {
0733: // Make sure caching is on, since that's what's being measured
0734: ComponentReference.cacheOnCreation = true;
0735:
0736: Frame fa = new MyFrame("A");
0737: Frame fb = new MyFrame("B");
0738: Frame fc = new MyFrame("C");
0739: showWindow(fa);
0740: showWindow(fb);
0741: showWindow(fc);
0742:
0743: // find a button, any button will do
0744: JButton button2 = (JButton) getFinder().find(fa,
0745: new ClassMatcher(JButton.class));
0746: JButton button3 = (JButton) getFinder().find(fb,
0747: new ClassMatcher(JButton.class));
0748:
0749: ComponentReference cref = resolver.addComponent(button2);
0750: fa.setVisible(false);
0751: Timer timer = new Timer();
0752: ComponentReference cref2 = resolver.addComponent(button3);
0753:
0754: assertTrue(
0755: "Maximum reference creation time exceeded, elapsed time="
0756: + timer.elapsed() + "ms",
0757: timer.elapsed() < MAX_CREATION_TIME);
0758: if (timer.elapsed() > MAX_CREATION_TIME / 5)
0759: Log.warn("Slow cref creation time: " + timer.elapsed()
0760: + "ms");
0761: }
0762:
0763: private static int appletCount = 0;
0764:
0765: private class InvisibleApplet extends Applet {
0766: public InvisibleApplet(final URL url, final String p1,
0767: final String p2) {
0768: setStub(new AppletStub() {
0769: public void appletResize(int w, int h) {
0770: }
0771:
0772: public AppletContext getAppletContext() {
0773: return null;
0774: }
0775:
0776: public URL getCodeBase() {
0777: return null;
0778: }
0779:
0780: public URL getDocumentBase() {
0781: return url;
0782: }
0783:
0784: public String getParameter(String name) {
0785: return "p1".equals(name) ? p1 : p2;
0786: }
0787:
0788: public boolean isActive() {
0789: return true;
0790: }
0791: });
0792: // Install into a frame so that it can be found
0793: // Note that all applet frames have a unique location
0794: Frame f = new InvisibleShowingFrame("Dummy Applet Frame");
0795: f.add(InvisibleApplet.this );
0796: f.setLocation(appletCount++, 0);
0797: }
0798:
0799: public String[][] getParameterInfo() {
0800: String[][] info = { { "p1", "" }, { "p2", "" }, };
0801: return info;
0802: }
0803:
0804: public boolean isShowing() {
0805: return true;
0806: }
0807: }
0808:
0809: public void testFindAppletsByParameter() throws Throwable {
0810: // Several identical applets with different parameters
0811: URL url = new URL("http://somewhere.com");
0812: Component c1 = new InvisibleApplet(url, "true", "true");
0813: Component c2 = new InvisibleApplet(url, "true", "false");
0814: ComponentReference cr1 = resolver.addComponent(c1);
0815: ComponentReference cr2 = resolver.addComponent(c2);
0816: assertNotNull("Could not resolve applet 1 by parameter value",
0817: cr1.getComponent());
0818: assertNotNull("Could not resolve applet 2 by parameter value",
0819: cr2.getComponent());
0820: }
0821:
0822: public void testFindAppletsByDocumentBase() throws Throwable {
0823: // Several identical applets with different document base
0824: URL url1 = new URL("http://somewhere.com");
0825: URL url2 = new URL("http://somewhereelse.com");
0826: Component c1 = new InvisibleApplet(url1, "true", "true");
0827: Component c2 = new InvisibleApplet(url2, "true", "true");
0828: ComponentReference cr1 = resolver.addComponent(c1);
0829: ComponentReference cr2 = resolver.addComponent(c2);
0830: assertNotNull("Could not resolve applet 1 by doc base", cr1
0831: .getComponent());
0832: assertNotNull("Could not resolve applet 2 by doc base", cr2
0833: .getComponent());
0834: }
0835:
0836: public void testDynamicButtonLabel() throws Throwable {
0837: JPanel pane = new JPanel();
0838: JPanel pane1 = new JPanel();
0839: JPanel root = new JPanel();
0840: final JButton button = new JButton("Open");
0841: pane.add(button);
0842: pane.add(new JButton("Wink"));
0843: pane.add(new JButton("Yank"));
0844: root.add(pane);
0845:
0846: pane1.add(new JButton("This"));
0847: pane1.add(new JButton("That"));
0848: root.add(pane1);
0849: showFrame(root);
0850: ComponentReference ref = resolver.addComponent(button);
0851: getRobot().click(button);
0852: getRobot().waitForIdle();
0853: button.setText("Close");
0854:
0855: ref.setAttribute(XMLConstants.TAG_TEXT, "/Open|Close/");
0856: assertNotNull("Could not find button after label change", ref
0857: .getComponent());
0858: }
0859:
0860: // These factory-created methods check for factory-created components
0861: // where a subsequent version is shown without necessarily disposing the
0862: // previous one
0863:
0864: public void testFactoryWithUnparentPrevious() throws Exception {
0865: JButton ok1 = new JButton("ok") {
0866: public String toString() {
0867: return "ok 1";
0868: }
0869: };
0870: ok1.setName("ok");
0871: JButton ok2 = new JButton("ok") {
0872: public String toString() {
0873: return "ok 2";
0874: }
0875: };
0876: ok2.setName("ok");
0877: Frame f1 = showFrame(ok1);
0878: ComponentReference ref = getResolver().addComponent(ok1);
0879: assertEquals("Initial lookup failed for " + ref, ok1, ref
0880: .getComponent());
0881: // disposal by removing references
0882: hideWindow(f1);
0883: f1.removeAll();
0884:
0885: Frame f2 = showFrame(ok2);
0886: assertEquals(
0887: "Cached value should not be used if it has no Window",
0888: ok2, ref.getComponent());
0889: }
0890:
0891: public void testFactoryPreferShowing() throws Exception {
0892: JButton ok1 = new JButton("ok") {
0893: public String toString() {
0894: return "ok 1";
0895: }
0896: };
0897: ok1.setName("ok");
0898: JButton ok2 = new JButton("ok") {
0899: public String toString() {
0900: return "ok 2";
0901: }
0902: };
0903: ok2.setName("ok");
0904: Frame f1 = showFrame(ok1);
0905: ComponentReference ref = getResolver().addComponent(ok1);
0906: assertEquals("Initial lookup failed for " + ref, ok1, ref
0907: .getComponent());
0908: // simulate "I forgot to dispose"
0909: hideWindow(f1);
0910:
0911: Frame f2 = showFrame(ok2);
0912: assertEquals(
0913: "Showing component should be preferred for " + ref,
0914: ok2, ref.getComponent());
0915: }
0916:
0917: public void testFactorySelectAmongHidden() throws Exception {
0918: JButton ok1 = new JButton("ok") {
0919: public String toString() {
0920: return "ok 1";
0921: }
0922: };
0923: ok1.setName("ok");
0924: JButton ok2 = new JButton("ok") {
0925: public String toString() {
0926: return "ok 2";
0927: }
0928: };
0929: ok2.setName("ok");
0930: Frame f1 = showFrame(ok1);
0931: ComponentReference ref = getResolver().addComponent(ok1);
0932: assertEquals("Initial lookup failed for " + ref, ok1, ref
0933: .getComponent());
0934: hideWindow(f1);
0935:
0936: Frame f2 = showFrame(ok2);
0937: hideWindow(f2);
0938:
0939: assertEquals(
0940: "Cached result should be used if all options are hidden",
0941: ok1, ref.getComponent());
0942: }
0943:
0944: /** Thanks to jimdoyle@users.sf.net for tracking this down. */
0945: public void testFindJTabbedPaneDescendant() {
0946: JTabbedPane tabs = new JTabbedPane();
0947: JButton button = null;
0948: int NEST = 10; // 2->750ms, 3->1.4s, 4->7s, 5->142s
0949: int TABS = 2;
0950: for (int t = 0; t < TABS; t++) {
0951: Container parent = tabs;
0952: JPanel panel;
0953: for (int i = 0; i < NEST; i++) {
0954: panel = new JPanel();
0955: parent.add(panel);
0956: parent = panel;
0957: }
0958: parent.add(button = new JButton("tab " + t));
0959: }
0960: showFrame(tabs);
0961: Timer timer = new Timer();
0962: ComponentReference ref = resolver.addComponent(button);
0963: if (timer.elapsed() > 500)
0964: fail("Creation of non-visible tabbed pane component took "
0965: + timer.elapsed() + "ms");
0966: }
0967:
0968: public void testFindJScrollBar() {
0969: JScrollPane pane = new JScrollPane(new JLabel(getName()));
0970: pane
0971: .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
0972: showFrame(pane);
0973: ComponentReference ref = resolver.addComponent(pane
0974: .getHorizontalScrollBar());
0975: assertTrue("Could not create ref", ref != null);
0976: }
0977:
0978: public void testBestExistingMatch() throws Exception {
0979: JPanel panel1 = new JPanel();
0980: JButton b1 = new JButton("b1");
0981: panel1.add(b1);
0982: JPanel panel2 = new JPanel();
0983: JButton b2 = new JButton("b2");
0984: panel2.add(b2);
0985: JPanel top = new JPanel();
0986: top.add(panel1);
0987: top.add(panel2);
0988: showFrame(top);
0989:
0990: ComponentReference ref1 = resolver.addComponent(b1);
0991: ComponentReference ref2 = resolver.addComponent(b2);
0992:
0993: Collection refs = resolver.getComponentReferences();
0994: assertEquals("Incorrect first match", ref1, ComponentReference
0995: .matchExisting(b1, refs));
0996: assertEquals("Incorrect second match", ref2, ComponentReference
0997: .matchExisting(b2, refs));
0998: }
0999:
1000: public void testMatchOrphanedComponent() throws Exception {
1001: final JPanel panel = new JPanel();
1002: final ArrayList list = new ArrayList();
1003: for (int i = 0; i < 2; i++) {
1004: list.add(new JButton("button " + i));
1005: }
1006: Component c = (Component) list.get(0);
1007: Component c2 = (Component) list.get(1);
1008: JButton button = new JButton("Change");
1009: button.addActionListener(new ActionListener() {
1010: private int index;
1011:
1012: public void actionPerformed(ActionEvent e) {
1013: panel.remove((Component) list.get(index));
1014: if (++index == list.size())
1015: index = 0;
1016: panel.add((Component) list.get(index));
1017: panel.revalidate();
1018: panel.repaint();
1019: }
1020: });
1021: panel.add(button);
1022: panel.add((Component) list.get(0));
1023: showFrame(panel);
1024:
1025: ComponentReference ref = resolver.addComponent(c);
1026: Collection refs = resolver.getComponentReferences();
1027: assertEquals("Component should match existing reference", ref,
1028: ComponentReference.matchExisting(c, refs));
1029:
1030: // makes second button display
1031: button.doClick();
1032: // components are not guaranteed to match if they are no longer in the
1033: // hierarchy.
1034: /*
1035: assertEquals("First component should still match when excised",
1036: ref, ComponentReference.matchExisting(c, refs));
1037: */
1038:
1039: // NOTE: force a reference creation; otherwise fuzzy matching will
1040: // cause the second component to match the first reference (as it
1041: // should).
1042: ComponentReference ref2 = new ComponentReference(resolver, c2,
1043: newRefs);
1044: Iterator iter = newRefs.keySet().iterator();
1045: while (iter.hasNext()) {
1046: ComponentReference tmp = (ComponentReference) newRefs
1047: .get(iter.next());
1048: resolver.addComponentReference(tmp);
1049: }
1050:
1051: // NOTE: this is a slight variation of "best existing match". Ensure
1052: // that we get the best match when more than one ref would pass a
1053: // fuzzy match.
1054: refs = resolver.getComponentReferences();
1055: assertEquals(
1056: "Second component should match proper existing ref",
1057: ref2, ComponentReference.matchExisting(c2, refs));
1058:
1059: // Make first button display
1060: button.doClick();
1061: assertEquals(
1062: "First component should match existing ref when restored",
1063: ref, ComponentReference.matchExisting(c, refs));
1064: // components are not guaranteed to match if they are no longer in the
1065: // hierarchy.
1066: /*
1067: assertEquals("Second component should still match when excised",
1068: ref2, ComponentReference.matchExisting(c2, refs));
1069: */
1070: }
1071:
1072: public ComponentReferenceTest(String name) {
1073: super (name);
1074: }
1075:
1076: public static void main(String[] args) {
1077: TestHelper.runTests(args, ComponentReferenceTest.class);
1078: }
1079: }
|