diff options
author | Mickael Istria | 2019-02-21 14:08:45 +0000 |
---|---|---|
committer | Mickael Istria | 2019-02-27 14:14:15 +0000 |
commit | dc3fc7c378f03dcd8404fd598641aa43a8ab086a (patch) | |
tree | 01085f5090e5cefe724128326fb546961277af92 | |
parent | 1fb70c44cdadcbdff87a191e446fc4a071a31cd7 (diff) | |
download | eclipse.platform.text-dc3fc7c378f03dcd8404fd598641aa43a8ab086a.tar.gz eclipse.platform.text-dc3fc7c378f03dcd8404fd598641aa43a8ab086a.tar.xz eclipse.platform.text-dc3fc7c378f03dcd8404fd598641aa43a8ab086a.zip |
Bug 541415 - [Test] Add test for code mining Ctrl+Home/EndY20190227-2200I20190228-0300I20190227-1800
Change-Id: Id50805fd1e5b6f91de27d573a2b6c1850902931f
Signed-off-by: Mickael Istria <mistria@redhat.com>
7 files changed, 388 insertions, 6 deletions
diff --git a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF index c3f62e24502..b6794013ede 100644 --- a/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.jface.text.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.jface.text.tests -Bundle-Version: 3.11.400.qualifier +Bundle-Version: 3.11.500.qualifier Bundle-Vendor: %Plugin.providerName Bundle-Localization: plugin Export-Package: @@ -17,7 +17,8 @@ Require-Bundle: org.eclipse.jface;bundle-version="[3.5.0,4.0.0)", org.junit;bundle-version="4.12.0", org.eclipse.text.tests;bundle-version="[3.5.0,4.0.0)", - org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)" + org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)", + org.eclipse.ui.workbench.texteditor Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Eclipse-BundleShape: dir Automatic-Module-Name: org.eclipse.jface.text.tests diff --git a/org.eclipse.jface.text.tests/pom.xml b/org.eclipse.jface.text.tests/pom.xml index bfa7090f065..51f25538a20 100644 --- a/org.eclipse.jface.text.tests/pom.xml +++ b/org.eclipse.jface.text.tests/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.jface</groupId> <artifactId>org.eclipse.jface.text.tests</artifactId> - <version>3.11.400-SNAPSHOT</version> + <version>3.11.500-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <properties> <testSuite>${project.artifactId}</testSuite> diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/CodeMiningTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/CodeMiningTest.java new file mode 100644 index 00000000000..f1ebf98b295 --- /dev/null +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/CodeMiningTest.java @@ -0,0 +1,176 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Mickael Istria (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.jface.text.tests; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.codemining.ICodeMiningProvider; +import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.reconciler.MonoReconciler; +import org.eclipse.jface.text.source.AnnotationModel; +import org.eclipse.jface.text.source.AnnotationPainter; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.tests.util.DisplayHelper; + +public class CodeMiningTest { + + private SourceViewer fViewer; + private Shell fShell; + + @Rule public ScreenshotOnFailureRule rule = new ScreenshotOnFailureRule(); + + @Before + public void setUp() { + fShell= new Shell(Display.getDefault()); + fShell.setSize(500, 200); + fShell.setLayout(new FillLayout()); + fViewer= new SourceViewer(fShell, null, SWT.NONE); + final StyledText textWidget= fViewer.getTextWidget(); + MonoReconciler reconciler = new MonoReconciler(new IReconcilingStrategy() { + @Override + public void setDocument(IDocument document) { + fViewer.updateCodeMinings(); + } + + @Override + public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) { + // nothing to do + } + + @Override + public void reconcile(IRegion partition) { + fViewer.updateCodeMinings(); + } + }, false); + reconciler.install(fViewer); + fViewer.setDocument(new Document(), new AnnotationModel()); + fViewer.setCodeMiningProviders(new ICodeMiningProvider[] { new DelayedEchoCodeMiningProvider() }); + AnnotationPainter annotationPainter = new AnnotationPainter(fViewer, null); + fViewer.setCodeMiningAnnotationPainter(annotationPainter); + fViewer.addPainter(annotationPainter); + // this currently needs to be repeated + fViewer.setCodeMiningProviders(new ICodeMiningProvider[] { new DelayedEchoCodeMiningProvider() }); + final Display display = textWidget.getDisplay(); + fShell.open(); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().isVisible(); + } + }.waitForCondition(display, 3000)); + DisplayHelper.sleep(textWidget.getDisplay(), 1000); + } + + @After + public void tearDown() { + fShell.dispose(); + fViewer = null; + } + + @Test + public void testCodeMiningFirstLine() { + fViewer.getDocument().set("echo"); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().getLineVerticalIndent(0) > 0; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + } + + @Test + public void testCodeMiningCtrlHome() throws BadLocationException { + DelayedEchoCodeMiningProvider.DELAY = 500; + fViewer.getDocument().set(TextViewerTest.generate5000Lines()); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().getText().length() > 5000; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + TextViewerTest.ctrlEnd(fViewer); + final int lastLine = fViewer.getDocument().getNumberOfLines() - 1; + final int lastLineOffset = fViewer.getDocument().getLineOffset(lastLine); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return lastLineOffset >= fViewer.getVisibleRegion().getOffset() && lastLineOffset <= fViewer.getVisibleRegion().getOffset() + fViewer.getVisibleRegion().getLength(); + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + DisplayHelper.sleep(fViewer.getControl().getDisplay(), 500); + AtomicInteger events = new AtomicInteger(); + fViewer.addViewportListener(offset -> + events.incrementAndGet()); + TextViewerTest.ctrlHome(fViewer); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return events.get() > 0; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + Assert.assertEquals(0, fViewer.getVisibleRegion().getOffset()); + // wait for codemining to style line + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().getLineVerticalIndent(0) > 0; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 300000)); + } + + @Test + public void testCodeMiningCtrlEnd() throws BadLocationException { + fViewer.getDocument().set(TextViewerTest.generate5000Lines()); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().getText().length() > 5000 && fViewer.getTextWidget().getLineVerticalIndent(0) > 0; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + DisplayHelper.sleep(fViewer.getTextWidget().getDisplay(), 500); + TextViewerTest.ctrlEnd(fViewer); + final int lastLine = fViewer.getDocument().getNumberOfLines() - 1; + final int lastLineOffset = fViewer.getDocument().getLineOffset(lastLine); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return lastLineOffset >= fViewer.getVisibleRegion().getOffset() && lastLineOffset <= fViewer.getVisibleRegion().getOffset() + fViewer.getVisibleRegion().getLength(); + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + Assert.assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return fViewer.getTextWidget().getLineVerticalIndent(lastLine) > 0; + } + }.waitForCondition(fViewer.getControl().getDisplay(), 3000)); + } + +} diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DelayedEchoCodeMiningProvider.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DelayedEchoCodeMiningProvider.java new file mode 100644 index 00000000000..8dd93c96f48 --- /dev/null +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/DelayedEchoCodeMiningProvider.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Mickael Istria (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.jface.text.tests; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.jface.text.BadLocationException; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.codemining.AbstractCodeMiningProvider; +import org.eclipse.jface.text.codemining.ICodeMining; +import org.eclipse.jface.text.codemining.ICodeMiningProvider; +import org.eclipse.jface.text.codemining.LineHeaderCodeMining; + +public class DelayedEchoCodeMiningProvider extends AbstractCodeMiningProvider implements ICodeMiningProvider { + + public static int DELAY = 0; + + @Override + public CompletableFuture<List<? extends ICodeMining>> provideCodeMinings(ITextViewer viewer, IProgressMonitor monitor) { + return CompletableFuture.supplyAsync(() -> { + try { + Thread.sleep(DELAY); + } catch (InterruptedException e1) { + e1.printStackTrace(); + return null; + } + IDocument document = viewer.getDocument(); + List<ICodeMining> res = new ArrayList<>(); + for (int lineNumber = 0; lineNumber < document.getNumberOfLines(); lineNumber++) { + try { + String lineContent = document.get(document.getLineOffset(lineNumber), document.getLineLength(lineNumber)); + if (!lineContent.trim().isEmpty()) { + LineHeaderCodeMining mining = new LineHeaderCodeMining(lineNumber, document, DelayedEchoCodeMiningProvider.this) { + // Nothing in particular + }; + mining.setLabel(lineContent); + res.add(mining); + } + } catch (BadLocationException e) { + e.printStackTrace(); + } + + } + return res; + }); + } + +} diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java index d1b8f5c1cb4..a62c552abac 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/JFaceTextTestSuite.java @@ -53,6 +53,7 @@ import org.eclipse.jface.text.tests.templates.persistence.TemplatePersistenceDat WordRuleTest.class, TemplatePersistenceDataTest.class, + CodeMiningTest.class }) public class JFaceTextTestSuite { // see @SuiteClasses diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ScreenshotOnFailureRule.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ScreenshotOnFailureRule.java new file mode 100644 index 00000000000..69a10a6d857 --- /dev/null +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/ScreenshotOnFailureRule.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat Inc. and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * - Mickael Istria (Red Hat Inc.) - initial implementation + *******************************************************************************/ +package org.eclipse.jface.text.tests; + +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.image.BufferedImage; +import java.io.File; + +import javax.imageio.ImageIO; + +import org.junit.rules.TestWatcher; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +final class ScreenshotOnFailureRule extends TestWatcher { + @Override + protected void failed(Throwable e, org.junit.runner.Description description) { + Robot robot; + try { + robot= new Robot(); + String format = "jpg"; + String fileName = Platform.getLogFileLocation().removeLastSegments(2).toString() + '/' + description.getClassName() + '.' + description.getMethodName() + ".failure." + format; + Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); + BufferedImage screenFullImage = robot.createScreenCapture(screenRect); + ImageIO.write(screenFullImage, format, new File(fileName)); + super.failed(e, description); + } catch (Exception ex) { + Platform.getLog(Platform.getBundle("org.eclipse.jface.text.tests")).log(new Status(IStatus.ERROR, "org.eclipse.jface.text.tests", ex.getMessage(), ex)); + } + } +}
\ No newline at end of file diff --git a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java index 2daa475762f..ba71f379947 100644 --- a/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java +++ b/org.eclipse.jface.text.tests/src/org/eclipse/jface/text/tests/TextViewerTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014 Google, Inc and others. + * Copyright (c) 2014-2019 Google, Inc and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -9,26 +9,38 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Sergey Prigogin (Google) - initial API and implementation + * - Sergey Prigogin (Google) - initial API and implementation + * - Mickael Istria (Red Hat Inc.) - [Bug 544708] Ctrl+Home *******************************************************************************/ package org.eclipse.jface.text.tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.Rule; import org.junit.Test; import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.ITextViewer; import org.eclipse.jface.text.TextViewer; +import org.eclipse.jface.text.source.SourceViewer; +import org.eclipse.jface.text.tests.util.DisplayHelper; /** * Basic tests for TextViewer. */ public class TextViewerTest { - + + @Rule public ScreenshotOnFailureRule screenshotRule = new ScreenshotOnFailureRule(); + @Test public void testSetRedraw_Bug441827() throws Exception { Shell shell= new Shell(); @@ -52,4 +64,86 @@ public class TextViewerTest { shell.dispose(); } } + + @Test + public void testCtrlHomeViewportListener() { + Shell shell= new Shell(); + try { + shell.setLayout(new FillLayout()); + shell.setSize(500, 200); + SourceViewer textViewer= new SourceViewer(shell, null, SWT.NONE); + textViewer.setDocument(new Document(generate5000Lines())); + shell.open(); + textViewer.revealRange(4000, 1); + AtomicBoolean notifyHomeReached = new AtomicBoolean(); + ctrlEnd(textViewer); + DisplayHelper.sleep(textViewer.getTextWidget().getDisplay(), 1000); + textViewer.addViewportListener(offset -> notifyHomeReached.set(offset == 0)); + ctrlHome(textViewer); + assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return notifyHomeReached.get(); + } + }.waitForCondition(textViewer.getTextWidget().getDisplay(), 3000)); + } finally { + shell.dispose(); + } + } + + @Test + public void testCtrlEndViewportListener() { + Shell shell= new Shell(); + try { + shell.setLayout(new FillLayout()); + shell.setSize(500, 200); + SourceViewer textViewer= new SourceViewer(shell, null, SWT.NONE); + Document document= new Document(generate5000Lines()); + textViewer.setDocument(document); + shell.open(); + AtomicBoolean notifyEndReached = new AtomicBoolean(); + textViewer.addViewportListener(offset -> + notifyEndReached.set(offset > 4000)); + ctrlEnd(textViewer); + assertTrue(new DisplayHelper() { + @Override + protected boolean condition() { + return notifyEndReached.get(); + } + }.waitForCondition(textViewer.getControl().getDisplay(), 3000)); + } finally { + shell.dispose(); + } + } + + public static void ctrlEnd(ITextViewer viewer) { + Event ctrlEndEvent = new Event(); + ctrlEndEvent.widget = viewer.getTextWidget(); + ctrlEndEvent.keyCode = SWT.END; + ctrlEndEvent.stateMask = SWT.CONTROL; + ctrlEndEvent.type = SWT.KeyDown; + ctrlEndEvent.doit = true; + viewer.getTextWidget().getDisplay().post(ctrlEndEvent); + } + + public static void ctrlHome(ITextViewer viewer) { + Event ctrlHomeEvent = new Event(); + ctrlHomeEvent.widget = viewer.getTextWidget(); + ctrlHomeEvent.keyCode = SWT.HOME; + ctrlHomeEvent.stateMask = SWT.CONTROL; + ctrlHomeEvent.type = SWT.KeyDown; + ctrlHomeEvent.doit = true; + viewer.getTextWidget().getDisplay().post(ctrlHomeEvent); + } + + + public static String generate5000Lines() { + StringBuilder b = new StringBuilder("start"); + for (int i = 0; i < 5000; i++) { + b.append('\n'); + } + b.append("end"); + return b.toString(); + } + } |