Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorangelozerr2018-08-01 15:35:42 +0000
committerMickael Istria2018-08-03 07:15:45 +0000
commitfe1f173989deb9f16974d0c78d55f68c04a07462 (patch)
treed75e3894334ac161536142c44bf560273a6d37e5 /org.eclipse.ui.genericeditor.tests/src
parent839c84221733f9fc9c6adc7a0a23d4132d79b92a (diff)
downloadeclipse.platform.text-fe1f173989deb9f16974d0c78d55f68c04a07462.tar.gz
eclipse.platform.text-fe1f173989deb9f16974d0c78d55f68c04a07462.tar.xz
eclipse.platform.text-fe1f173989deb9f16974d0c78d55f68c04a07462.zip
Bug 520659 - [generic editor] Default Code folding for generic editorI20180803-2000
should use IndentFoldingStrategy Change-Id: If023933536584f07960fcb6b99c6dedcf6f6be1c Signed-off-by: angelozerr <angelo.zerr@gmail.com>
Diffstat (limited to 'org.eclipse.ui.genericeditor.tests/src')
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/FoldingTest.java118
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/GenericEditorTestSuite.java1
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingReconciler.java33
-rw-r--r--org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingStrategy.java157
4 files changed, 309 insertions, 0 deletions
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/FoldingTest.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/FoldingTest.java
new file mode 100644
index 00000000000..d8d66bf8eb2
--- /dev/null
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/FoldingTest.java
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2018 Angelo ZERR.
+ * 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:
+ * Angelo Zerr <angelo.zerr@gmail.com> - [generic editor] Default Code folding for generic editor should use IndentFoldingStrategy - Bug 520659
+ */
+package org.eclipse.ui.genericeditor.tests;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.jface.text.tests.util.DisplayHelper;
+
+import org.eclipse.ui.genericeditor.tests.contributions.EnabledPropertyTester;
+
+public class FoldingTest extends AbstratGenericEditorTest {
+
+ @Override
+ protected void createAndOpenFile() throws Exception {
+ //leave editor creation to individual tests
+ }
+
+ @Test
+ public void testDefaultIndentFoldingOneFold() throws Exception {
+ createAndOpenFile("bar.xml", "<a>\n b</a>");
+ checkFolding(pos(0, 10));
+ }
+
+ @Test
+ public void testDefaultIndentFoldingTwoFold() throws Exception {
+ createAndOpenFile("bar.xml", "<a>\n <b>\n c\n </b>\n</a>");
+ checkFolding(pos(0, 19), pos(4, 9));
+ }
+
+ @Test
+ public void testCustomFoldingReconciler() throws Exception {
+ createAndOpenFile("bar.txt", "<a>\n <b>\n c\n </b>\n</a>\n");
+ checkFolding(pos(0, 24), pos(5, 14));
+ }
+
+ @Test
+ public void testEnabledWhenCustomFoldingReconciler() throws Exception {
+ EnabledPropertyTester.setEnabled(true);
+ createAndOpenFile("enabledWhen.txt", "<a>\n <b>\n c\n </b>\n</a>\n");
+ checkFolding(pos(0, 24), pos(5, 14));
+ cleanFileAndEditor();
+
+ EnabledPropertyTester.setEnabled(false);
+ createAndOpenFile("enabledWhen.txt", "<a>\n <b>\n c\n </b>\n</a>\n");
+ checkFolding();
+ }
+
+ private static Position pos(int offset, int length) {
+ return new Position(offset, length);
+ }
+
+ private void checkFolding(Position... expectedPositions) {
+ if (expectedPositions == null) {
+ expectedPositions= new Position[0];
+ }
+ waitForAnnotations(expectedPositions.length);
+ List<Annotation> folderAnnotations= getAnnotationsFromAnnotationModel();
+ Assert.assertEquals(expectedPositions.length, folderAnnotations.size());
+ List<Position> actualPositions= new ArrayList<>(expectedPositions.length);
+ for (int i= 0; i < expectedPositions.length; i++) {
+ Annotation folderAnnotation= folderAnnotations.get(i);
+ Position actualPosition= getProjectionAnnotationModel().getPosition(folderAnnotation);
+ actualPositions.add(actualPosition);
+ }
+ // Sort actual positions by offset
+ Collections.sort(actualPositions, (p1, p2) -> p1.offset - p2.offset);
+ Assert.assertArrayEquals(expectedPositions, actualPositions.toArray());
+ }
+
+ private IAnnotationModel getProjectionAnnotationModel() {
+ ProjectionViewer dp= (ProjectionViewer) editor.getAdapter(ITextViewer.class);
+ IAnnotationModel am= dp.getProjectionAnnotationModel();
+ return am;
+ }
+
+ private void waitForAnnotations(int count) {
+ new DisplayHelper() {
+ @Override
+ protected boolean condition() {
+ return getAnnotationsFromAnnotationModel().size() == count;
+ }
+ }.waitForCondition(Display.getDefault(), 2000);
+ }
+
+ private List<Annotation> getAnnotationsFromAnnotationModel() {
+ List<Annotation> annotationList= new ArrayList<>();
+ Iterator<Annotation> annotationIterator= getProjectionAnnotationModel().getAnnotationIterator();
+ while (annotationIterator.hasNext()) {
+ Annotation ann= annotationIterator.next();
+ if (ann.getType().equals(ProjectionAnnotation.TYPE)) {
+ annotationList.add(ann);
+ }
+ }
+ return annotationList;
+ }
+}
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/GenericEditorTestSuite.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/GenericEditorTestSuite.java
index ee4c1940719..6ab16ce9db0 100644
--- a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/GenericEditorTestSuite.java
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/GenericEditorTestSuite.java
@@ -22,6 +22,7 @@ import org.junit.runners.Suite.SuiteClasses;
StylingTest.class,
HoverTest.class,
EditorTest.class,
+ FoldingTest.class,
AutoEditTest.class,
ReconcilerTest.class,
HighlightTest.class
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingReconciler.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingReconciler.java
new file mode 100644
index 00000000000..7a13de4b76e
--- /dev/null
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingReconciler.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Red Hat Inc. 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:
+ * Lucas Bullen (Red Hat Inc.) - initial implementation
+ *******************************************************************************/
+package org.eclipse.ui.genericeditor.tests.contributions;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.reconciler.Reconciler;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+public class FoldingReconciler extends Reconciler {
+
+ private FoldingStrategy fStrategy;
+
+ public FoldingReconciler() {
+ fStrategy = new FoldingStrategy();
+ this.setReconcilingStrategy(fStrategy, IDocument.DEFAULT_CONTENT_TYPE);
+ }
+
+ @Override
+ public void install(ITextViewer textViewer) {
+ super.install(textViewer);
+ ProjectionViewer pViewer =(ProjectionViewer)textViewer;
+ fStrategy.setProjectionViewer(pViewer);
+ }
+} \ No newline at end of file
diff --git a/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingStrategy.java b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingStrategy.java
new file mode 100644
index 00000000000..aeae3176324
--- /dev/null
+++ b/org.eclipse.ui.genericeditor.tests/src/org/eclipse/ui/genericeditor/tests/contributions/FoldingStrategy.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Red Hat Inc. 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:
+ * Lucas Bullen (Red Hat Inc.) - initial implementation
+ *******************************************************************************/
+package org.eclipse.ui.genericeditor.tests.contributions;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.reconciler.DirtyRegion;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
+import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+
+public class FoldingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension {
+
+ private IDocument document;
+ private String oldDocument;
+ private ProjectionViewer projectionViewer;
+ private List<Annotation> oldAnnotations = new ArrayList<>();
+ private List<Position> oldPositions = new ArrayList<>();
+
+ @Override
+ public void setDocument(IDocument document) {
+ this.document = document;
+ }
+
+ public void setProjectionViewer(ProjectionViewer projectionViewer) {
+ this.projectionViewer = projectionViewer;
+ }
+
+ @Override
+ public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+ initialReconcile();
+ }
+
+ @Override
+ public void reconcile(IRegion partition) {
+ initialReconcile();
+ }
+
+ @Override
+ public void initialReconcile() {
+ if(document.get().equals(oldDocument)) return;
+ oldDocument = document.get();
+
+ List<Position> positions = getNewPositionsOfAnnotations();
+
+ List<Position> positionsToRemove = new ArrayList<>();
+ List<Annotation> annotationToRemove = new ArrayList<>();
+
+ for (Position position : oldPositions) {
+ if(!positions.contains(position)) {
+ projectionViewer.getProjectionAnnotationModel().removeAnnotation(oldAnnotations.get(oldPositions.indexOf(position)));
+ positionsToRemove.add(position);
+ annotationToRemove.add(oldAnnotations.get(oldPositions.indexOf(position)));
+ }else {
+ positions.remove(position);
+ }
+ }
+ oldPositions.removeAll(positionsToRemove);
+ oldAnnotations.removeAll(annotationToRemove);
+
+ for (Position position : positions) {
+ Annotation annotation = new ProjectionAnnotation();
+ projectionViewer.getProjectionAnnotationModel().addAnnotation(annotation, position);
+ oldPositions.add(position);
+ oldAnnotations.add(annotation);
+ }
+ }
+
+ private static enum SearchingFor {
+ START_OF_TAG, START_OF_WORD, END_OF_WORD, END_OF_LINE
+ }
+
+ private List<Position> getNewPositionsOfAnnotations(){
+ List<Position> positions = new ArrayList<>();
+ Map<String, Integer> startOfAnnotation = new HashMap<>();
+ SearchingFor searchingFor = SearchingFor.START_OF_TAG;
+
+ int characters = document.getLength();
+ int currentCharIndex = 0;
+
+ int wordStartIndex = 0;
+ int sectionStartIndex = 0;
+ String word = "";
+
+ try {
+ while (currentCharIndex < characters) {
+ char currentChar = document.getChar(currentCharIndex);
+ switch (searchingFor) {
+ case START_OF_TAG:
+ if(currentChar == '<') {
+ char nextChar = document.getChar(currentCharIndex+1);
+ if(nextChar != '?') {
+ sectionStartIndex = currentCharIndex;
+ searchingFor = SearchingFor.START_OF_WORD;
+ }
+ }
+ break;
+ case START_OF_WORD:
+ if(Character.isLetter(currentChar)) {
+ wordStartIndex = currentCharIndex;
+ searchingFor = SearchingFor.END_OF_WORD;
+ }
+ break;
+ case END_OF_WORD:
+ if(!Character.isLetter(currentChar)) {
+ word = document.get(wordStartIndex, currentCharIndex - wordStartIndex);
+ if(startOfAnnotation.containsKey(word)) {
+ searchingFor = SearchingFor.END_OF_LINE;
+ }else {
+ startOfAnnotation.put(word, sectionStartIndex);
+ searchingFor = SearchingFor.START_OF_TAG;
+ }
+ }
+ break;
+ case END_OF_LINE:
+ if(currentChar == '\n') {
+ int start = startOfAnnotation.get(word);
+ if(document.getLineOfOffset(start) != document.getLineOfOffset(currentCharIndex)) {
+ positions.add(new Position(start,currentCharIndex + 1 - start));
+ }
+ startOfAnnotation.remove(word);
+ searchingFor = SearchingFor.START_OF_TAG;
+ }
+ break;
+ }
+ currentCharIndex++;
+ }
+ } catch (BadLocationException e) {
+ // skip the remainder of file due to error
+ }
+ return positions;
+ }
+
+ @Override
+ public void setProgressMonitor(IProgressMonitor monitor) {
+ // no progress monitor used
+ }
+
+} \ No newline at end of file

Back to the top