Clover coverage report - clover
Coverage timestamp: Sat Oct 8 2005 22:54:17 EDT
file stats: LOC: 304   Methods: 31
NCLOC: 253   Classes: 10
 
 Source file Conditionals Statements Methods TOTAL
RobotAppletTest.java 59.1% 88.5% 90.3% 85.2%
coverage coverage
 1   
 package abbot.tester;
 2   
 
 3   
 import java.applet.Applet;
 4   
 import java.awt.*;
 5   
 import java.awt.event.*;
 6   
 import java.io.*;
 7   
 import java.lang.reflect.*;
 8   
 import java.util.*;
 9   
 import javax.swing.*;
 10   
 
 11   
 import abbot.*;
 12   
 import abbot.util.AWT;
 13   
 import abbot.script.*;
 14   
 import abbot.tester.Robot;
 15   
 import junit.extensions.abbot.*;
 16   
 import junit.extensions.abbot.Timer;
 17   
 
 18   
 /** Unit test to verify Robot operation on applets.<p> */
 19   
 
 20   
 public class RobotAppletTest extends ComponentTestFixture {
 21   
 
 22   
     // TODO: figure out a way to kill the event dispatch threads started by
 23   
     // each instantiation of AppletViewer; they should die on their own but
 24   
     // something seems to be resurrecting them (Robot.waitForIdle may be
 25   
     // partly responsible).
 26   
 
 27   
     private Robot robot;
 28   
 
 29  8
     protected void setUp() {
 30  8
         robot = getRobot();
 31  8
         appletStartCount = 0;
 32   
     }
 33   
 
 34  8
     protected void tearDown() {
 35   
         // must close, not dispose, to get rid of appletviewer
 36  8
         Iterator iter = getHierarchy().getRoots().iterator();
 37  8
         while (iter.hasNext()) {
 38  10
             Window w = (Window)iter.next();
 39  10
             closeAll(w);
 40   
         }
 41  8
         robot.waitForIdle();
 42  8
         System.setSecurityManager(oldsm);
 43   
     }
 44   
 
 45   
     static Object lock = new Object();
 46   
     private static final String TAG = " (applet test)";
 47   
     public static class TestApplet extends Applet {
 48   
         public static volatile Applet testInstance = null;
 49  10
         public void start() { ++appletStartCount; }
 50  10
         public void init() {
 51  10
             String name = Thread.currentThread().getName();
 52  10
             Thread.currentThread().setName(name + TAG);
 53  10
             testInstance = this;
 54  10
             SwingUtilities.invokeLater(new Runnable() {
 55  10
                 public void run() {
 56  10
                     Thread thread = Thread.currentThread();
 57  10
                     String name = thread.getName();
 58  10
                     if (name.indexOf(TAG) == -1) {
 59  8
                         thread.setName(name + TAG);
 60   
                     }
 61   
                 }
 62   
             });
 63   
         }
 64   
     }
 65   
 
 66   
     public static class ColoredApplet extends TestApplet {
 67   
         public TextField text;
 68  0
         public ColoredApplet() { setName(getClass().getName()); }
 69  4
         public ColoredApplet(Color c) {
 70  4
             setBackground(c);
 71   
         }
 72  4
         public void init() {
 73  4
             super.init();
 74  4
             text = new TextField(ColoredApplet.this.getName());
 75  4
             text.setBackground(getBackground());
 76  4
             add(text);
 77   
         }
 78   
     }
 79   
     public static class RedApplet extends ColoredApplet {
 80   
         public static volatile ColoredApplet instance = null;
 81   
         public static volatile boolean destroyed = false;
 82  2
         public RedApplet() { super(Color.red); }
 83  2
         public void start() { super.start(); instance = this; }
 84  2
         public void destroy() { super.destroy(); instance = null; }
 85   
     }
 86   
     public static class GreenApplet extends ColoredApplet {
 87   
         public static volatile ColoredApplet instance = null;
 88   
         public static volatile boolean destroyed = false;
 89  2
         public GreenApplet() { super(Color.green); }
 90  2
         public void start() { super.start(); instance = this; }
 91  2
         public void destroy() { super.destroy(); instance = null; }
 92   
     }
 93   
     private class FocusWatcher extends FocusAdapter {
 94   
         public volatile boolean gotFocus = false;
 95  4
         public void focusGained(FocusEvent f) {
 96  4
             gotFocus = true;
 97  4
             Log.log("AppContext=" + AWT.getAppContext(f.getComponent()).hashCode());
 98   
         }
 99   
     }
 100   
 
 101   
     private int exitCalled = 0;
 102   
     private volatile int appletCount = 0;
 103   
     private volatile static int appletStartCount = 0;
 104   
     private File htmlFile = null;
 105   
     private SecurityManager oldsm = null;
 106   
 
 107  8
     private void launch(String[] classNames) throws Exception {
 108  8
         appletCount = classNames.length;
 109  8
         StringBuffer html = new StringBuffer();
 110  8
         for (int i=0;i < classNames.length;i++) {
 111  10
             html.append("<html><applet codebase=\"build/classes\" code=\"");
 112  10
             html.append(classNames[i]);
 113  10
             html.append("\" width=\"100\" height=\"100\"></applet>");
 114   
         }
 115  8
         html.append("</html>");
 116   
         // HTML file must be a relative path
 117  8
         File dir = new File(System.getProperty("user.dir"));
 118  8
         htmlFile = File.createTempFile(getName(), ".html", dir);
 119  8
         htmlFile.deleteOnExit();
 120  8
         FileOutputStream os = new FileOutputStream(htmlFile);
 121  8
         os.write(html.toString().getBytes());
 122  8
         os.close();
 123   
         // The appletviewer and security manager must share a class loader
 124   
         // We use AppClassLoader b/c it knows how to reload AppletViewer
 125  8
         final AppClassLoader cl = new AppClassLoader(".");
 126  8
         oldsm = System.getSecurityManager();
 127   
         // Make sure we catch the appletviewer exit exception
 128  8
         String tgname = getName() + " Thread Group for catching exit";
 129  8
         final ThreadGroup group = new ThreadGroup(tgname) {
 130  9
             public void uncaughtException(Thread t, Throwable thrown) {
 131  9
                 if (!(thrown instanceof ExitException)
 132   
                     && !(thrown instanceof ThreadDeath))
 133  0
                     Log.warn(thrown);
 134   
             }
 135   
         };
 136  8
         Thread thread = new Thread(group, "AppletViewer Launcher") {
 137  8
             public void run() {
 138  8
                 try {
 139  8
                     Class cls =
 140   
                         Class.forName("abbot.script.AppletSecurityManager",
 141   
                                       true, cl);
 142  8
                     Constructor ctor = cls.getConstructor(new Class[] {
 143   
                         SecurityManager.class
 144   
                     });
 145  8
                     SecurityManager asm = (SecurityManager)
 146   
                         ctor.newInstance(new Object[] {
 147   
                             new NoExitSecurityManager() {
 148  0
                                 protected void exitCalled(int status) {
 149  0
                                     ++exitCalled;
 150   
                                 }
 151   
                             }
 152   
                         });
 153   
                     // Ensure AppletViewer is loaded by an instance of
 154   
                     // AppClassLoader, which can ensure the class gets 
 155   
                     // discarded after the test. 
 156  8
                     cls = Class.forName("sun.applet.Main", true, cl);
 157  8
                     System.setSecurityManager(asm);
 158  8
                     cls.getMethod("main", new Class[] { String[].class }).
 159   
                         invoke(null, new Object[] {
 160   
                             new String[] { htmlFile.getName() }
 161   
                         });
 162   
                 }
 163   
                 catch(Exception e) {
 164  0
                     Log.warn(e);
 165   
                 }
 166   
             }
 167   
         };
 168  8
         thread.setContextClassLoader(cl);
 169  8
         thread.start();
 170   
 
 171  8
         getWindowTracker();
 172  8
         Timer timer = new Timer();
 173  8
         while (appletStartCount < appletCount) {
 174  106
             if (timer.elapsed() > 60000) {
 175  0
                 fail("AppletViewer failed to launch");
 176   
             }
 177  106
             robot.sleep();
 178   
         }
 179   
     }
 180   
 
 181   
     // NOTE: maybe abstract this to an applet test fixture, which takes the
 182   
     // applet class (or a list of them) as an argument and makes appletviewer
 183   
     // display them
 184  2
     public void testFocusApplet() throws Exception {
 185  2
         launch(new String[] {
 186   
             RedApplet.class.getName(),
 187   
             GreenApplet.class.getName()
 188   
         });
 189  2
         ColoredApplet green = GreenApplet.instance;
 190  2
         ColoredApplet red = RedApplet.instance;
 191   
 
 192  2
         FocusWatcher fw = new FocusWatcher();
 193  2
         red.text.addFocusListener(fw);
 194  2
         robot.focus(red.text, true);
 195  2
         Timer timer = new Timer();
 196  2
         while (!fw.gotFocus) {
 197  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY) {
 198  0
                 Log.log("Failing applet focus");
 199  0
                 fail("Red applet text field never received focus");
 200   
             }
 201  0
             robot.sleep();
 202   
         }
 203  2
         fw = new FocusWatcher();
 204  2
         green.text.addFocusListener(fw);
 205  2
         robot.focus(green.text, true);
 206  2
         timer.reset();
 207  2
         while (!fw.gotFocus) {
 208  0
             if (timer.elapsed() > EVENT_GENERATION_DELAY) {
 209  0
                 Log.log("Failing text field focus");
 210  0
                 fail("Green applet text field never received focus");
 211   
             }
 212  0
             robot.sleep();
 213   
         }
 214   
     }
 215   
 
 216   
     private static abstract class AbstractComponentApplet extends TestApplet {
 217   
         public static Component component;
 218   
         protected abstract Component getComponent();
 219  6
         public void init() {
 220  6
             super.init();
 221  6
             add(component = getComponent());
 222   
         }
 223   
     }
 224   
     public static class TextFieldApplet extends AbstractComponentApplet {
 225  2
         protected Component getComponent() {
 226  2
             return new TextField("wider field");
 227   
         }
 228   
     }
 229   
     public static class JTextFieldApplet extends AbstractComponentApplet {
 230  2
         protected Component getComponent() {
 231  2
             return new JTextField("wider field");
 232   
         }
 233   
     }
 234   
 
 235   
     // FIXME fails on linux 1.4.2_04, AWT mode, pointer focus
 236   
     // Can't stuff a TextField with AWT events
 237  2
     public void testTextFieldEntry() throws Exception {
 238  2
         launch(new String[] { TextFieldApplet.class.getName() });
 239  2
         String TEXT = "a few more";
 240  2
         TextField tf = (TextField)TextFieldApplet.component;
 241  2
         tf.setText("");
 242  2
         robot.waitForIdle();
 243  2
         robot.focus(tf, true);
 244  2
         robot.keyString(TEXT);
 245  2
         robot.waitForIdle();
 246  2
         assertEquals("Text not entered", TEXT, tf.getText());
 247   
     }
 248   
 
 249   
     // This fails on linux/twm/pointer focus/1.4.1_02; the text
 250   
     // isn't directed to the proper window
 251  2
     public void testJTextFieldEntry() throws Exception {
 252  2
         launch(new String[] { JTextFieldApplet.class.getName() });
 253  2
         JTextField tf = (JTextField)JTextFieldApplet.component;
 254  2
         tf.setText("");
 255  2
         robot.waitForIdle();
 256  2
         robot.focus(tf, true);
 257  2
         String TEXT = "a few more";
 258  2
         robot.keyString(TEXT);
 259  2
         robot.waitForIdle();
 260  2
         assertEquals("Text not entered", TEXT, tf.getText());
 261   
     }
 262   
 
 263   
     public static class JButtonApplet extends AbstractComponentApplet {
 264  2
         protected Component getComponent() {
 265  2
             return new JButton("button");
 266   
         }
 267   
     }
 268   
 
 269  2
     public void testJButtonPress() throws Exception {
 270  2
         launch(new String[] { JButtonApplet.class.getName() });
 271  2
         final JButton b = (JButton)JButtonApplet.component;
 272  2
         final String expected = "Text changed";
 273  2
         b.addActionListener(new ActionListener() {
 274  2
             public void actionPerformed(ActionEvent e) {
 275  2
                 b.setText(expected);
 276   
             }
 277   
         });
 278  2
         robot.click(b);
 279  2
         robot.waitForIdle();
 280  2
         assertEquals("Button not hit", expected, b.getText());
 281   
     }
 282   
 
 283  10
     private void closeAll(Window w) {
 284  10
         Window[] owned = w.getOwnedWindows();
 285  10
         for (int i=0;i < owned.length;i++) {
 286  0
             closeAll(owned[i]);
 287   
         }
 288  10
         robot.close(w);
 289   
     }
 290   
     /*
 291   
     public void testZZZ() { 
 292   
         System.out.println("Get stack trace now");
 293   
         while(true);
 294   
     }
 295   
     */
 296   
     /** Create a new test case with the given name. */
 297  8
     public RobotAppletTest(String name) { super(name); }
 298   
 
 299   
     /** Provide for repetitive testing on individual tests. */
 300  0
     public static void main(String[] args) {
 301  0
         RepeatHelper.runTests(args, RobotAppletTest.class);
 302   
     }
 303   
 }
 304