blob: e4b7b9503bfabdbe91748e4a4ab541d43438e656 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2015 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.text.tests;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelListener;
/**
* Tests the {@link org.eclipse.jface.text.source.IAnnotationModelExtension2}.
*
* @since 3.4
*/
public class AnnotationModelExtension2Test {
public static class OldAnnotationModel implements IAnnotationModel {
private final HashMap<Annotation, Position> fAnnotations= new HashMap<>();
@Override
public void addAnnotation(Annotation annotation, Position position) {
fAnnotations.put(annotation, position);
}
@Override
public void addAnnotationModelListener(IAnnotationModelListener listener) {
}
@Override
public void connect(IDocument document) {
}
@Override
public void disconnect(IDocument document) {
}
@Override
public Iterator<Annotation> getAnnotationIterator() {
return fAnnotations.keySet().iterator();
}
@Override
public Position getPosition(Annotation annotation) {
return fAnnotations.get(annotation);
}
@Override
public void removeAnnotation(Annotation annotation) {
fAnnotations.remove(annotation);
}
@Override
public void removeAnnotationModelListener(IAnnotationModelListener listener) {
}
public void removeAllAnnotations() {
fAnnotations.clear();
}
}
private static final int MODEL_COUNT= 3;
private Document fDocument;
private AnnotationModel fAnnotationModel;
private AnnotationModel fNewInnerModel;
private OldAnnotationModel fOldInnerModel;
private Annotation fInside;
private Annotation fBefore;
private Annotation fAfter;
private Annotation fInsideIn;
private Annotation fInsideOut;
private Annotation fBeforeIn;
private Annotation fBoforeOut;
private Annotation fAfterIn;
private Annotation fAfterOut;
@Before
public void setUp() {
fDocument= new Document("How much wood\nwould a woodchuck chuck\nif a woodchuck\ncould chuck wood?\n42");
fAnnotationModel= new AnnotationModel();
fNewInnerModel= new AnnotationModel();
fAnnotationModel.addAnnotationModel("model1", fNewInnerModel);
fOldInnerModel= new OldAnnotationModel();
fAnnotationModel.addAnnotationModel("model2", fOldInnerModel);
fInside= new Annotation(false);
fInsideIn= new Annotation(false);
fInsideOut= new Annotation(false);
fBefore= new Annotation(false);
fBeforeIn= new Annotation(false);
fBoforeOut= new Annotation(false);
fAfter= new Annotation(false);
fAfterIn= new Annotation(false);
fAfterOut= new Annotation(false);
fAnnotationModel.connect(fDocument);
}
@After
public void tearDown() {
fAnnotationModel.disconnect(fDocument);
}
private void assertEquals(Annotation[] expected, Annotation[] actual, IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
HashSet<Annotation> expectedSet= new HashSet<>(Arrays.asList(expected));
for (Annotation a : actual) {
if (!expectedSet.contains(a)) {
String message = "Unexpected annotation " + getName(a) + " in result with models [" + getAnnotationModelNames(insideModel, beforeModel, afterModel) + "]";
assertTrue(message, false);
}
expectedSet.remove(a);
}
if (!expectedSet.isEmpty()) {
String message= "Missing annotations in result with models [" + getAnnotationModelNames(insideModel, beforeModel, afterModel) + "]";
for (Annotation missing : expectedSet) {
message= message + "\n" + getName(missing);
}
assertTrue(message, false);
}
}
private String getAnnotationModelNames(IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
return "inside: " + getAnnotationModelName(insideModel) + " before: " + getAnnotationModelName(beforeModel) + " after: " + getAnnotationModelName(afterModel);
}
private String getAnnotationModelName(IAnnotationModel model) {
if (model == fAnnotationModel) {
return "'Top'";
} else if (model == fNewInnerModel) {
return "'New inner'";
} else if (model == fOldInnerModel) {
return "'Old inner'";
}
return "'Unknown'";
}
private String getName(Annotation annotation) {
Position position= fAnnotationModel.getPosition(annotation);
return "[" + position.getOffset() + ", " + position.getLength() + "]";
}
/*
* The annotations are added to the annotations models
* as following:
*
* 0-beforeout-9 21-afterout--30
* 0--beforein---11 19---afterin---30
* 0--before----10 20--after-----30
*
* 10--region----20
*
* 10--inside----20
* 11-insidein-19
* 9---insideout---21
*/
private void addAnnotations(IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
insideModel.addAnnotation(fInside, new Position(10, 11));
insideModel.addAnnotation(fInsideIn, new Position(11, 9));
insideModel.addAnnotation(fInsideOut, new Position(9, 13));
beforeModel.addAnnotation(fBefore, new Position(0, 11));
beforeModel.addAnnotation(fBeforeIn, new Position(0, 12));
beforeModel.addAnnotation(fBoforeOut, new Position(0, 10));
afterModel.addAnnotation(fAfter, new Position(20, 11));
afterModel.addAnnotation(fAfterIn, new Position(19, 12));
afterModel.addAnnotation(fAfterOut, new Position(21, 10));
}
private void removeAnnotations() {
fAnnotationModel.removeAllAnnotations();
fNewInnerModel.removeAllAnnotations();
fOldInnerModel.removeAllAnnotations();
}
private Annotation[] getAnnotations(boolean lookAhead, boolean lookBehind) {
Iterator<Annotation> iterator= fAnnotationModel.getAnnotationIterator(10, 11, lookAhead, lookBehind);
ArrayList<Annotation> result= new ArrayList<>();
while (iterator.hasNext()) {
result.add(iterator.next());
}
return result.toArray(new Annotation[result.size()]);
}
private void assertPermutations(boolean lookAhead, boolean lookBehind, Annotation[] expected) {
for (int i= 0; i < MODEL_COUNT; i++) {
for (int j= 0; j < MODEL_COUNT; j++) {
for (int k= 0; k < MODEL_COUNT; k++) {
IAnnotationModel insideModel= getModel(i);
IAnnotationModel beforeModel= getModel(j);
IAnnotationModel afterModel= getModel(k);
addAnnotations(insideModel, beforeModel, afterModel);
Annotation[] actual= getAnnotations(lookAhead, lookBehind);
assertEquals(expected, actual, insideModel, beforeModel, afterModel);
removeAnnotations();
}
}
}
}
private IAnnotationModel getModel(int number) {
switch (number) {
case 0:
return fAnnotationModel;
case 1:
return fNewInnerModel;
case 2:
return fOldInnerModel;
default:
break;
}
return null;
}
@Test
public void testInside() throws Exception {
Annotation[] expected= new Annotation[] { fInside, fInsideIn };
assertPermutations(false, false, expected);
}
@Test
public void testAhead() throws Exception {
Annotation[] expected= new Annotation[] { fInside, fInsideIn, fBefore, fBeforeIn };
assertPermutations(true, false, expected);
}
@Test
public void testBehind() throws Exception {
Annotation[] expected= new Annotation[] { fInside, fInsideIn, fAfter, fAfterIn };
assertPermutations(false, true, expected);
}
@Test
public void testAheadBehind() throws Exception {
Annotation[] expected= new Annotation[] { fInside, fInsideIn, fInsideOut, fAfter, fAfterIn, fBefore, fBeforeIn };
assertPermutations(true, true, expected);
}
}