SwingTest.java revision 11018:66682f651425
1/*
2 * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24import java.awt.Toolkit;
25import java.lang.reflect.InvocationTargetException;
26import java.lang.reflect.Method;
27import java.lang.reflect.Modifier;
28import java.util.Comparator;
29import java.util.Iterator;
30import java.util.Set;
31import java.util.TreeSet;
32import javax.swing.JFrame;
33import javax.swing.SwingUtilities;
34
35/**
36 * SwingTest is a utility class for writing regression tests
37 * that require interacting with the UI.
38 * It uses reflection to invoke all public methods without parameters.
39 * All static methods are starting on the current thread.
40 * Other methods including constructor are starting on the EDT.
41 * Between each method invocation all pending events are processed.
42 * The methods are sorted by name and invoked in that order.
43 * Failure of the test is signaled by any method throwing an exception.
44 * If no methods throw an exception the test is assumed to have passed.
45 *
46 * @author Sergey A. Malenkov
47 */
48final class SwingTest implements Runnable {
49
50    private static final int WIDTH = 640;
51    private static final int HEIGHT = 480;
52
53    public static void start(Class<?> type) throws Throwable {
54        new SwingTest(type).start();
55    }
56
57    private final Class<?> type;
58    private final Iterator<Method> methods;
59
60    private JFrame frame;
61    private Object object;
62    private Method method;
63    private Throwable error;
64
65    private SwingTest(Class<?> type) {
66        Set<Method> methods = new TreeSet<Method>(new Comparator<Method>() {
67            public int compare(Method first, Method second) {
68                return first.getName().compareTo(second.getName());
69            }
70        });
71        for (Method method : type.getMethods()) {
72            if (method.getDeclaringClass().equals(type)) {
73                if (method.getReturnType().equals(void.class)) {
74                    if (0 == method.getParameterTypes().length) {
75                        methods.add(method);
76                    }
77                }
78            }
79        }
80        this.type = type;
81        this.methods = methods.iterator();
82    }
83
84    public void run() {
85        try {
86            if (this.object == null) {
87                System.out.println(this.type);
88                this.frame = new JFrame(this.type.getSimpleName());
89                this.frame.setSize(WIDTH, HEIGHT);
90                this.frame.setLocationRelativeTo(null);
91                this.object = this.type.getConstructor(this.frame.getClass()).newInstance(this.frame);
92                this.frame.setVisible(true);
93            }
94            else if (this.method != null) {
95                System.out.println(this.method);
96                this.method.invoke(this.object);
97            }
98            else {
99                System.out.println((this.error == null) ? "PASSED" : "FAILED"); // NON-NLS: debug
100                this.frame.dispose();
101                this.frame = null;
102            }
103        }
104        catch (NoSuchMethodException exception) {
105            this.error = exception;
106        }
107        catch (SecurityException exception) {
108            this.error = exception;
109        }
110        catch (IllegalAccessException exception) {
111            this.error = exception;
112        }
113        catch (IllegalArgumentException exception) {
114            this.error = exception;
115        }
116        catch (InstantiationException exception) {
117            this.error = exception;
118        }
119        catch (InvocationTargetException exception) {
120            this.error = exception.getTargetException();
121        }
122        System.out.flush();
123        this.method = this.methods.hasNext() && (this.error == null)
124                ? this.methods.next()
125                : null;
126    }
127
128    private void start() throws Throwable {
129        do {
130            if ((this.method != null) && Modifier.isStatic(this.method.getModifiers())) {
131                run(); // invoke static method on the current thread
132            }
133            else {
134                SwingUtilities.invokeLater(this); // invoke on the event dispatch thread
135            }
136            java.awt.Robot robot = new java.awt.Robot();
137            robot.waitForIdle();
138        }
139        while (this.frame != null);
140        if (this.error != null) {
141            throw this.error;
142        }
143    }
144}
145