diff options
author | Markus Keller | 2012-08-29 16:13:16 +0000 |
---|---|---|
committer | Markus Keller | 2012-08-29 16:13:16 +0000 |
commit | 54d70bc9abb288b278ce134bfe8f6dae764f4a4e (patch) | |
tree | 7910996b42197d8dd9428b5f1cc5a398838cf268 | |
parent | 938570cb1fc944907b2e4f52232497b0f02b2717 (diff) | |
download | eclipse.platform.text-54d70bc9abb288b278ce134bfe8f6dae764f4a4e.tar.gz eclipse.platform.text-54d70bc9abb288b278ce134bfe8f6dae764f4a4e.tar.xz eclipse.platform.text-54d70bc9abb288b278ce134bfe8f6dae764f4a4e.zip |
- added BytecodeOrderedTestSuite
- removed all hacks in FindReplaceDialogTest
- added separate ScreenshotTest to experiment with screenshots
4 files changed, 394 insertions, 135 deletions
diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/BytecodeOrderedTestSuite.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/BytecodeOrderedTestSuite.java new file mode 100644 index 00000000000..b08cfb84f64 --- /dev/null +++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/BytecodeOrderedTestSuite.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.workbench.texteditor.tests; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Test suite that contains the same tests as a regular {@link TestSuite}, + * but the order of tests is the bytecode order from the classfile. + * + * <p> + * <b>Background:</b> {@link java.lang.Class#getDeclaredMethods()} does not + * specify the order of the methods. Up to JavaSE 6, the methods were usually + * sorted in declaration order, but in JavaSE 7, the order is random. This class + * guarantees reliable test execution order. + * </p> + * + * @since 3.9 + */ +public class BytecodeOrderedTestSuite extends TestSuite { + + /** + * Creates a new test suite that runs tests in bytecode order. + * + * @param testClass the JUnit-3-style test class + */ + public BytecodeOrderedTestSuite(Class testClass) { + this(testClass, testClass.getName()); + } + + /** + * Creates a new test suite that runs tests in bytecode order. + * + * @param testClass the JUnit-3-style test class + * @param name the name of the suite + */ + public BytecodeOrderedTestSuite(Class testClass, String name) { + super(name); + + TestSuite randomOrderSuite= new TestSuite(testClass); + ArrayList tests= Collections.list(randomOrderSuite.tests()); + + class SortingException extends RuntimeException { + private static final long serialVersionUID= 1L; + public SortingException(String message) { + super(message); + } + } + final ArrayList orderedMethodNames= new ArrayList(); + Class c= testClass; + try { + while (Test.class.isAssignableFrom(c)) { + addDeclaredTestMethodNames(c, orderedMethodNames); + c= c.getSuperclass(); + } + Collections.sort(tests, new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof TestCase && o2 instanceof TestCase) { + TestCase t1= (TestCase) o1; + TestCase t2= (TestCase) o2; + int i1= orderedMethodNames.indexOf(t1.getName()); + int i2= orderedMethodNames.indexOf(t2.getName()); + if (i1 != -1 && i2 != -1) + return i1 - i2; + } + throw new SortingException("suite failed to detect test order: " + o1 + ", " + o2); + } + }); + } catch (SortingException e) { + addTest(error(testClass, "suite failed to detect test order", e)); //$NON-NLS-1$ + } catch (IOException e) { + addTest(error(testClass, "suite failed to detect test order", e)); //$NON-NLS-1$ + } + + for (Iterator iter= tests.iterator(); iter.hasNext(); ) { + Test test= (Test) iter.next(); + addTest(test); + } + } + + private static Test error(Class testClass, String testMethod, Exception exception) { + final Throwable e2= exception.fillInStackTrace(); + return new TestCase(testMethod + "(" + testClass.getName() + ")") { //$NON-NLS-1$ //$NON-NLS-2$ + protected void runTest() throws Throwable { + throw e2; + } + }; + } + + private ArrayList addDeclaredTestMethodNames(Class c, ArrayList methodNames) throws IOException { + String className= c.getName(); + int lastDot= className.lastIndexOf("."); + if (lastDot != -1) + className= className.substring(lastDot + 1); + DataInputStream is= new DataInputStream(new BufferedInputStream(c.getResourceAsStream(className + ".class"))); + int magic= is.readInt(); + if (magic != 0xcafebabe) + throw new IOException("bad magic bytes: 0x" + Integer.toHexString(magic)); + skip(is, 2); // minor_version + int major= is.readUnsignedShort(); + if (major > 51) { // > Java 7 + addTest(error(c, "suite can't handle class file version", new RuntimeException(c.getName() + " (major = " + major + ")"))); + } + int cpCount= is.readUnsignedShort(); + String[] constantPoolStrings= new String[cpCount]; + for (int i= 1; i < cpCount; i++) { + + byte tag= is.readByte(); + switch (tag) { + case 7: // CONSTANT_Class + skip(is, 2); + break; + case 9: // CONSTANT_Fieldref + case 10: // CONSTANT_Methodref + case 11: // CONSTANT_InterfaceMethodref + skip(is, 4); + break; + case 8: // CONSTANT_String + skip(is, 2); + break; + case 3: // CONSTANT_Integer + case 4: // CONSTANT_Float + skip(is, 4); + break; + case 5: // CONSTANT_Long + case 6: // CONSTANT_Double + skip(is, 8); + i++; // weird spec + break; + case 12: // CONSTANT_NameAndType + skip(is, 4); + break; + case 1: // CONSTANT_Utf8 + constantPoolStrings[i]= is.readUTF(); + break; + case 15: // CONSTANT_MethodHandle + skip(is, 3); + break; + case 16: // CONSTANT_MethodType + skip(is, 2); + break; + case 18: // CONSTANT_InvokeDynamic + skip(is, 4); + break; + default: + throw new IOException("unknown constant pool tag (" + i + "): " + tag); + } + } + skip(is, 2 * 3); // access_flags, this_class, super_class + int interfacesCount= is.readUnsignedShort(); + skip(is, 2 * interfacesCount); + int fieldsCount= is.readUnsignedShort(); + for (int i= 0; i < fieldsCount; i++) { + skip(is, 2 * 3); // access_flags, name_index, descriptor_index + int attributesCount= is.readUnsignedShort(); + for (int j= 0; j < attributesCount; j++) { + skip(is, 2); // attribute_name_index + long attInfoCount= readUnsignedInt(is); + skip(is, attInfoCount); + } + } + + int methodsCount= is.readUnsignedShort(); + for (int i= 0; i < methodsCount; i++) { + skip(is, 2); // access_flags + int nameIndex= is.readUnsignedShort(); + int descIndex= is.readUnsignedShort(); + if ("()V".equals(constantPoolStrings[descIndex])) { + String name= constantPoolStrings[nameIndex]; + if (name.startsWith("test")) + methodNames.add(name); + } + int attributesCount= is.readUnsignedShort(); + for (int j= 0; j < attributesCount; j++) { + skip(is, 2); // attribute_name_index + long attInfoCount= readUnsignedInt(is); + skip(is, attInfoCount); + } + } + return methodNames; + } + + private static void skip(DataInputStream is, long bytes) throws IOException { + while (bytes > 0) + bytes -= is.skip(bytes); + if (bytes != 0) + throw new IOException("error in skipping bytes: " + bytes); + } + + private static long readUnsignedInt(DataInputStream is) throws IOException { + return is.readInt() & 0xFFFFffffL; + } + +} diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/FindReplaceDialogTest.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/FindReplaceDialogTest.java index 35cb1ad02a6..8897834f608 100644 --- a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/FindReplaceDialogTest.java +++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/FindReplaceDialogTest.java @@ -10,28 +10,18 @@ *******************************************************************************/ package org.eclipse.ui.workbench.texteditor.tests; -import java.io.File; -import java.io.PrintStream; import java.util.ResourceBundle; import junit.framework.Test; import junit.framework.TestCase; -import junit.framework.TestSuite; import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.ImageLoader; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; -import org.eclipse.core.runtime.Platform; - import org.eclipse.text.tests.Accessor; import org.eclipse.jface.util.Util; @@ -57,16 +47,7 @@ public class FindReplaceDialogTest extends TestCase { } public static Test suite() { - TestSuite suite= new TestSuite(FindReplaceDialogTest.class.getName()); - suite.addTest(new FindReplaceDialogTest("testInitialButtonState")); - suite.addTest(new FindReplaceDialogTest("testDisableWholeWordIfRegEx")); - suite.addTest(new FindReplaceDialogTest("testDisableWholeWordIfNotWord")); - suite.addTest(new FindReplaceDialogTest("testFocusNotChangedWhenEnterPressed")); - if (org.eclipse.jface.util.Util.isWindows() || org.eclipse.jface.util.Util.isLinux()) - suite.addTest(new FindReplaceDialogTest("testFocusNotChangedWhenButtonMnemonicPressed")); - suite.addTest(new FindReplaceDialogTest("testShiftEnterReversesSearchDirection")); - - return suite; + return new BytecodeOrderedTestSuite(FindReplaceDialogTest.class); } private void runEventQueue() { @@ -218,124 +199,14 @@ public class FindReplaceDialogTest extends TestCase { assertTrue(allScopeBox.isFocusControl()); } - public void testWindowsTaskManagerScreenshots() throws Exception { - takeScreenshot(FindReplaceDialogTest.class, getName() + 1); - - if (! Util.isWindows()) - return; - - Display display= Display.getDefault(); - - Event event= new Event(); - event.type= SWT.KeyDown; - event.keyCode= SWT.CTRL; - System.out.println("* CTRL " + display.post(event)); - event.keyCode= SWT.SHIFT; - System.out.println("* SHIFT " + display.post(event)); - event.character= SWT.ESC; - event.keyCode= SWT.ESC; - System.out.println("* ESC " + display.post(event)); - - event.type= SWT.KeyUp; - System.out.println("* ESC up " + display.post(event)); - event.character= 0; - event.keyCode= SWT.SHIFT; - System.out.println("* SHIFT up " + display.post(event)); - event.keyCode= SWT.CTRL; - System.out.println("* CTRL up " + display.post(event)); - - runEventQueue(); - display.beep(); - takeScreenshot(FindReplaceDialogTest.class, getName() + 2); - - event.type= SWT.KeyDown; - event.character= SWT.ESC; - event.keyCode= SWT.ESC; - System.out.println("* ESC " + display.post(event)); - event.type= SWT.KeyUp; - System.out.println("* ESC up " + display.post(event)); - - runEventQueue(); - display.beep(); - takeScreenshot(FindReplaceDialogTest.class, getName() + 3); - } - private String takeScreenshot() { - return takeScreenshot(FindReplaceDialogTest.class, getName()); - } - - private String takeScreenshot(Class testClass, String testName) { - File resultsHtmlDir= getJunitReportOutput(); // ends up in testresults/linux.gtk.x86_6.0/<class>.<test>.png - - if (resultsHtmlDir == null) { // fallback, NOT platform-dependent: - File eclipseDir= new File("").getAbsoluteFile(); // eclipse-testing/test-eclipse/eclipse - resultsHtmlDir= new File(eclipseDir, "../../results/html/").getAbsoluteFile(); // ends up in testresults/html/<class>.<test>.png - } - - PrintStream out= System.out; - - Display display= Display.getDefault(); - - // Wiggle the mouse: - Event mouseMove= new Event(); - mouseMove.x= 10; - mouseMove.y= 10; - display.post(mouseMove); - runEventQueue(); - mouseMove.x= 20; - mouseMove.y= 20; - display.post(mouseMove); - runEventQueue(); - - // Dump focus control, parents, and shells: - Control focusControl = display.getFocusControl(); - if (focusControl != null) { - out.println("FocusControl: "); - StringBuffer indent = new StringBuffer(" "); - do { - out.println(indent.toString() + focusControl); - focusControl = focusControl.getParent(); - indent.append(" "); - } while (focusControl != null); - } - Shell[] shells = display.getShells(); - if (shells.length > 0) { - out.println("Shells: "); - for (int i = 0; i < shells.length; i++) { - Shell shell = shells[i]; - out.println((shell.isVisible() ? " visible: " : " invisible: ") + shell); - } - } - - // Take a screenshot: - GC gc = new GC(display); - final Image image = new Image(display, display.getBounds()); - gc.copyArea(image, 0, 0); - gc.dispose(); - - resultsHtmlDir.mkdirs(); - String filename = new File( - resultsHtmlDir.getAbsolutePath(), - testClass.getName() + "." + testName + ".png").getAbsolutePath(); - ImageLoader loader = new ImageLoader(); - loader.data = new ImageData[] { image.getImageData() }; - loader.save(filename, SWT.IMAGE_PNG); - out.println("Screenshot saved to: " + filename); - image.dispose(); - return filename; - } - - private static File getJunitReportOutput() { - String[] args= Platform.getCommandLineArgs(); - for (int i= 0; i < args.length - 1; i++) { - if ("-junitReportOutput".equals(args[i])) { // see library.xml and org.eclipse.test.EclipseTestRunner - return new File(args[i + 1]).getAbsoluteFile(); - } - } - return null; + return ScreenshotTest.takeScreenshot(FindReplaceDialogTest.class, getName(), System.out); } public void testFocusNotChangedWhenButtonMnemonicPressed() { + if (Util.isMac()) + return; + openTextViewerAndFindReplaceDialog(); Combo findField= (Combo)fFindReplaceDialog.get("fFindField"); diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/ScreenshotTest.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/ScreenshotTest.java new file mode 100644 index 00000000000..7d5542e54f4 --- /dev/null +++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/ScreenshotTest.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2012 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.ui.workbench.texteditor.tests; + +import java.io.File; +import java.io.PrintStream; + +import junit.framework.Test; +import junit.framework.TestCase; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.graphics.ImageLoader; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.core.runtime.Platform; + +import org.eclipse.jface.util.Util; + +import org.eclipse.ui.PlatformUI; + +public class ScreenshotTest extends TestCase { + + public ScreenshotTest(String name) { + super(name); + } + + public static Test suite() { + return new BytecodeOrderedTestSuite(ScreenshotTest.class); + } + + + public void testWindowsTaskManagerScreenshots() throws Exception { + takeScreenshot(ScreenshotTest.class, getName() + 1, System.out); + + if (! Util.isWindows()) + return; + + Display display= Display.getDefault(); + + Event event= new Event(); + event.type= SWT.KeyDown; + event.keyCode= SWT.CTRL; + System.out.println("* CTRL " + display.post(event)); + event.keyCode= SWT.SHIFT; + System.out.println("* SHIFT " + display.post(event)); + event.character= SWT.ESC; + event.keyCode= SWT.ESC; + System.out.println("* ESC " + display.post(event)); + + event.type= SWT.KeyUp; + System.out.println("* ESC up " + display.post(event)); + event.character= 0; + event.keyCode= SWT.SHIFT; + System.out.println("* SHIFT up " + display.post(event)); + event.keyCode= SWT.CTRL; + System.out.println("* CTRL up " + display.post(event)); + + runEventQueue(); + takeScreenshot(ScreenshotTest.class, getName() + 2, System.out); + + event.type= SWT.KeyDown; + event.character= SWT.ESC; + event.keyCode= SWT.ESC; + System.out.println("* ESC " + display.post(event)); + event.type= SWT.KeyUp; + System.out.println("* ESC up " + display.post(event)); + + runEventQueue(); + takeScreenshot(ScreenshotTest.class, getName() + 3, System.out); + } + + /** + * Takes a screenshot and dumps other debugging information to the given stream. + * + * @param testClass test class that takes the screenshot + * @param name screenshot identifier (e.g. test name) + * @param out print stream to use for diagnostics. + * @return file system path to the screenshot file + */ + public static String takeScreenshot(Class testClass, String name, PrintStream out) { + File resultsHtmlDir= getJunitReportOutput(); // ends up in testresults/linux.gtk.x86_6.0/<class>.<test>.png + + if (resultsHtmlDir == null) { // Fallback. Warning: uses same file location on all test platforms: + File eclipseDir= new File("").getAbsoluteFile(); // eclipse-testing/test-eclipse/eclipse + resultsHtmlDir= new File(eclipseDir, "../../results/html/").getAbsoluteFile(); // ends up in testresults/html/<class>.<test>.png + } + + Display display= PlatformUI.getWorkbench().getDisplay(); + + // Wiggle the mouse: + Event mouseMove= new Event(); + mouseMove.x= 10; + mouseMove.y= 10; + display.post(mouseMove); + runEventQueue(); + mouseMove.x= 20; + mouseMove.y= 20; + display.post(mouseMove); + runEventQueue(); + + // Dump focus control, parents, and shells: + Control focusControl = display.getFocusControl(); + if (focusControl != null) { + out.println("FocusControl: "); + StringBuffer indent = new StringBuffer(" "); + do { + out.println(indent.toString() + focusControl); + focusControl = focusControl.getParent(); + indent.append(" "); + } while (focusControl != null); + } + Shell[] shells = display.getShells(); + if (shells.length > 0) { + out.println("Shells: "); + for (int i = 0; i < shells.length; i++) { + Shell shell = shells[i]; + out.println((shell.isVisible() ? " visible: " : " invisible: ") + shell); + } + } + + // Take a screenshot: + GC gc = new GC(display); + final Image image = new Image(display, display.getBounds()); + gc.copyArea(image, 0, 0); + gc.dispose(); + + resultsHtmlDir.mkdirs(); + String filename = new File( + resultsHtmlDir.getAbsolutePath(), + testClass.getName() + "." + name + ".png").getAbsolutePath(); + ImageLoader loader = new ImageLoader(); + loader.data = new ImageData[] { image.getImageData() }; + loader.save(filename, SWT.IMAGE_PNG); + out.println("Screenshot saved to: " + filename); + image.dispose(); + return filename; + } + + private static File getJunitReportOutput() { + String[] args= Platform.getCommandLineArgs(); + for (int i= 0; i < args.length - 1; i++) { + if ("-junitReportOutput".equals(args[i])) { // see library.xml and org.eclipse.test.EclipseTestRunner + return new File(args[i + 1]).getAbsoluteFile(); + } + } + return null; + } + + private static void runEventQueue() { + Display display= PlatformUI.getWorkbench().getDisplay(); + for (int i= 0; i < 10; i++) { // workaround for https://bugs.eclipse.org/323272 + while (display.readAndDispatch()) { + // do nothing + } + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + } +} diff --git a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java index 0f778ac5157..2059a40b4ac 100644 --- a/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java +++ b/org.eclipse.ui.workbench.texteditor.tests/src/org/eclipse/ui/workbench/texteditor/tests/WorkbenchTextEditorTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -35,6 +35,7 @@ public class WorkbenchTextEditorTestSuite extends TestSuite { suite.addTest(ChangeRegionTest.suite()); suite.addTest(RulerTestSuite.suite()); suite.addTest(HunkComputerTest.suite()); + suite.addTest(ScreenshotTest.suite()); //$JUnit-END$ return suite; |