blob: fb8824b24dd5402d6c925c8fe37207eaa79e3969 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2017 Wind River Systems, 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
* Jonah Graham (Kichwa Coders) - extract most of FoldingTest into FoldingTestBase
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager;
import org.eclipse.cdt.internal.ui.text.doctools.NullDocCommentOwner;
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.ui.text.doctools.IDocCommentOwner;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Path;
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.source.Annotation;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.projection.IProjectionPosition;
import org.eclipse.jface.text.source.projection.ProjectionAnnotation;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.ui.PartInitException;
abstract public class FoldingTestBase extends BaseUITestCase {
protected static class ProjectionPosition extends Position implements IProjectionPosition, IRegion {
private int fCaptionOffset;
ProjectionPosition(int offset, int length, int captionOffset) {
super(offset, length);
fCaptionOffset = captionOffset;
}
@Override
public int computeCaptionOffset(IDocument document) throws BadLocationException {
return fCaptionOffset;
}
@Override
public IRegion[] computeProjectionRegions(IDocument document) throws BadLocationException {
return new IRegion[] { this };
}
}
protected static class PositionAndCollapsed {
public Position position;
public boolean isCollapsed;
public PositionAndCollapsed(Position position, boolean isCollapsed) {
this.position = position;
this.isCollapsed = isCollapsed;
}
}
private static final String LINKED_FOLDER = "resources/folding";
private static final String PROJECT = "FoldingTest";
private ICProject fCProject;
private final String fTestFilename = "/FoldingTest/src/FoldingTest.cpp";
protected CEditor fEditor;
private SourceViewer fSourceViewer;
private IFile fFileUnderTest;
public FoldingTestBase() {
super();
}
public FoldingTestBase(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
fCProject = EditorTestHelper.createCProject(PROJECT, LINKED_FOLDER);
StringBuilder[] contents = getContentsForTest(1);
assertEquals("test requires exactly one test block", 1, contents.length);
String code = contents[0].toString();
String filename;
if (code.trim().isEmpty()) {
filename = fTestFilename;
} else {
TestSourceReader.createFile(fCProject.getProject(), new Path("FoldingTest.cpp"), code);
filename = "/FoldingTest/FoldingTest.cpp";
}
fFileUnderTest = ResourceTestHelper.findFile(filename);
openEditor();
}
private void openEditor() throws PartInitException {
fEditor = (CEditor) EditorTestHelper.openInEditor(fFileUnderTest, true);
fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 300));
}
private void closeEditor() {
EditorTestHelper.closeEditor(fEditor);
}
@Override
protected void tearDown() throws Exception {
closeEditor();
if (fCProject != null)
CProjectHelper.delete(fCProject);
super.tearDown();
}
protected void runWithEditorClosed(Runnable runnable) throws PartInitException {
// When the workspace comment owner changes, all open editors are
// re-opened asynchronously, within the test that async is a problem
// because we lose the handle and have no real condition to wait on.
// Instead close and reopen editor within this method.
closeEditor();
runnable.run();
openEditor();
}
/**
* Set the doctool to None. This method should be run with the editor
* closed, see {@link #runWithEditorClosed(Runnable)}
*/
protected void setDoctoolToNone() {
DocCommentOwnerManager.getInstance().setWorkspaceCommentOwner(NullDocCommentOwner.INSTANCE);
}
/**
* Set the doctool to Doxygen. This method should be run with the editor
* closed, see {@link #runWithEditorClosed(Runnable)}
*/
protected void setDoctoolToDoxygen() {
IDocCommentOwner[] registeredOwners = DocCommentOwnerManager.getInstance().getRegisteredOwners();
IDocCommentOwner doxygenOwner = null;
for (IDocCommentOwner owner : registeredOwners) {
if (owner.getID().contains("doxygen")) {
assertNull("More than one owner looks like doxygen", doxygenOwner);
doxygenOwner = owner;
}
}
DocCommentOwnerManager.getInstance().setWorkspaceCommentOwner(doxygenOwner);
}
protected void assertEqualPositions(PositionAndCollapsed[] expected, PositionAndCollapsed[] actual)
throws BadLocationException {
assertEquals(expected.length, actual.length);
IDocument document = fSourceViewer.getDocument();
for (int i = 0, n = expected.length; i < n; i++) {
final Position exp = expected[i].position;
int expectedStartLine = document.getLineOfOffset(exp.getOffset());
int expectedEndLine = document.getLineOfOffset(exp.getOffset() + exp.getLength());
final Position act = actual[i].position;
int actualStartLine = document.getLineOfOffset(act.getOffset());
int actualEndLine = document.getLineOfOffset(act.getOffset() + exp.getLength());
assertEquals(exp.isDeleted(), act.isDeleted());
assertEquals(expectedStartLine, actualStartLine);
assertEquals(expectedEndLine, actualEndLine);
if (exp instanceof IProjectionPosition) {
int expectedCaptionOffset = ((IProjectionPosition) exp).computeCaptionOffset(document);
int expectedCaptionLine = document.getLineOfOffset(exp.getOffset() + expectedCaptionOffset);
int actualCaptionLine = actualStartLine;
if (act instanceof IProjectionPosition) {
int actualCaptionOffset = ((IProjectionPosition) act).computeCaptionOffset(document);
actualCaptionLine = document.getLineOfOffset(exp.getOffset() + actualCaptionOffset);
}
assertEquals(expectedCaptionLine, actualCaptionLine);
}
assertEquals(expected[i].isCollapsed, actual[i].isCollapsed);
}
}
protected PositionAndCollapsed createPosition(int startLine, int endLine) throws BadLocationException {
return createPosition(startLine, endLine, false);
}
protected PositionAndCollapsed createPosition(int startLine, int endLine, boolean collapsed)
throws BadLocationException {
IDocument document = fSourceViewer.getDocument();
int startOffset = document.getLineOffset(startLine);
int endOffset = document.getLineOffset(endLine) + document.getLineLength(endLine);
Position position = new Position(startOffset, endOffset - startOffset);
return new PositionAndCollapsed(position, collapsed);
}
protected PositionAndCollapsed createPosition(int startLine, int endLine, int captionLine)
throws BadLocationException {
return createPosition(startLine, endLine, captionLine, false);
}
protected PositionAndCollapsed createPosition(int startLine, int endLine, int captionLine, boolean collapsed)
throws BadLocationException {
IDocument document = fSourceViewer.getDocument();
int startOffset = document.getLineOffset(startLine);
int endOffset = document.getLineOffset(endLine) + document.getLineLength(endLine);
int captionOffset = document.getLineOffset(captionLine);
Position position = new ProjectionPosition(startOffset, endOffset - startOffset, captionOffset - startOffset);
return new PositionAndCollapsed(position, collapsed);
}
protected String toString(PositionAndCollapsed[] positionAndCollapseds) throws BadLocationException {
StringBuilder buf = new StringBuilder();
IDocument document = fSourceViewer.getDocument();
buf.append("PositionAndCollapsed[] expected= new PositionAndCollapsed[] {\n");
for (int i = 0, n = positionAndCollapseds.length; i < n; i++) {
Position position = positionAndCollapseds[i].position;
int startLine = document.getLineOfOffset(position.getOffset());
int endLine = document.getLineOfOffset(position.getOffset() + position.getLength() - 1);
int captionLine = startLine;
if (position instanceof IProjectionPosition) {
final int captionOffset = ((IProjectionPosition) position).computeCaptionOffset(document);
captionLine = document.getLineOfOffset(position.getOffset() + captionOffset);
}
buf.append("\tcreatePosition(");
buf.append(startLine);
buf.append(", ");
buf.append(endLine);
if (captionLine != startLine) {
buf.append(", ");
buf.append(captionLine);
}
if (positionAndCollapseds[i].isCollapsed) {
buf.append(", true");
}
buf.append("),\n");
}
buf.append("};\n");
return buf.toString();
}
protected PositionAndCollapsed[] getFoldingPositions() {
List<PositionAndCollapsed> positionAndCollapseds = new ArrayList<>();
ProjectionAnnotationModel model = fEditor.getAdapter(ProjectionAnnotationModel.class);
assertNotNull(model);
for (Iterator<Annotation> iter = model.getAnnotationIterator(); iter.hasNext();) {
Annotation ann = iter.next();
ProjectionAnnotation proAnn = (ProjectionAnnotation) ann;
Position pos = model.getPosition(ann);
positionAndCollapseds.add(new PositionAndCollapsed(pos, proAnn.isCollapsed()));
}
Collections.sort(positionAndCollapseds, new Comparator<PositionAndCollapsed>() {
@Override
public int compare(PositionAndCollapsed p0, PositionAndCollapsed p1) {
return p0.position.offset - p1.position.offset;
}
});
return positionAndCollapseds.toArray(new PositionAndCollapsed[positionAndCollapseds.size()]);
}
}