blob: f5a61b378a250f121621db737ba4fd4a9a950b7f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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.jdt.text.tests;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.contentassist.ContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.tests.TestTextViewer;
import org.eclipse.jdt.internal.ui.text.java.JavaParameterListValidator;
public class JavaParameterListValidatorTest extends TestCase {
protected TestTextViewer fTextViewer;
protected IDocument fDocument;
protected JavaParameterListValidator fValidator;
public JavaParameterListValidatorTest(String name) {
super(name);
}
protected void setUp() {
fTextViewer= new TestTextViewer();
fDocument= new Document();
fValidator= new JavaParameterListValidator();
}
public static Test suite() {
return new TestSuite(JavaParameterListValidatorTest.class);
}
protected void tearDown () {
fTextViewer= null;
fDocument= null;
fValidator= null;
}
public void testParameterStyling() {
final String code= "a, b, c, d, e";
assertParameterInfoStyles(code, "int a, int b, int c, int d, int e", computeCommaPositions(code));
}
public void testParameterStylingWithString() {
final String code= "a, b, \"foo, bar, and such\", d, e";
assertParameterInfoStyles(code, "int a, int b, String c, int d, int e", computeCommaPositions(code));
}
public void testParameterStylingWithEscapedString() {
final String code= "a, b, \"foo, b\\\"ar, and such\\\\\", d, e";
assertParameterInfoStyles(code, "int a, int b, String c, int d, int e", computeCommaPositions(code));
}
public void testParameterStylingWithComment() {
final String code= "a, b, c /* the ( argument */, d, e";
assertParameterInfoStyles(code, "int a, int b, String c, int d, int e", computeCommaPositions(code));
}
public void testParameterStylingWithGenerics() {
final String code= "new HashMap <String, HashMap<String,Integer[]>>(), p1, p2";
assertParameterInfoStyles(code, "Map<String, Map> m, int p1, int p2", computeCommaPositions(code));
}
public void testParameterStylingWithGenericsAndComments() {
final String code= "new HashMap <String, /* comment > */HashMap<String,Integer[]>>(), p1, p2";
assertParameterInfoStyles(code, "Map<String, Map> m, int p1, int p2", new int[] {64, 68});
}
public void testParameterStylingWithConstants() {
final String code= "MAX < MIN, MAX > MIN";
assertParameterInfoStyles(code, "boolean b1, boolean b2", new int[] {9});
}
public void testParameterStylingWithGenericsThatLookLikeConstants() {
final String code= "new MAX < MIN, MAX >";
assertParameterInfoStyles(code, "MAX<?,?>", new int[0]);
}
private void assertParameterInfoStyles(String code, String infostring, int[] argumentCommas) {
fDocument.set(code);
fTextViewer.setDocument(fDocument);
int[] parameterCommas= computeCommaPositions(infostring);
IContextInformation info= new ContextInformation("context", infostring);
fValidator.install(info, fTextViewer, 0);
TextPresentation p= new TextPresentation();
for (int i= 0; i < fDocument.getLength(); i++) {
fValidator.updatePresentation(i, p);
assertEquals(createPresentation(i, parameterCommas, argumentCommas, infostring), p);
}
}
private int[] computeCommaPositions(String code) {
int pos= 0;
List positions= new ArrayList();
while (pos < code.length() && pos != -1) {
char ch= code.charAt(pos);
switch (ch) {
case ',':
positions.add(new Integer(pos));
break;
case '<':
pos= code.indexOf('>', pos);
break;
case '(':
pos= code.indexOf(')', pos);
break;
case '[':
pos= code.indexOf(']', pos);
break;
case '{':
pos= code.indexOf('}', pos);
break;
case '"':
pos= findLiteralEnd(code, pos + 1, '"');
break;
case '/':
if (pos < code.length() - 1 && code.charAt(pos + 1) == '*')
pos= findCommentEnd(code, pos + 2);
break;
case '\'':
pos= findLiteralEnd(code, pos + 1, '\'');
break;
default:
break;
}
if (pos != -1)
pos++;
}
int[] fields= new int[positions.size()];
for (int i= 0; i < fields.length; i++)
fields[i]= ((Integer) positions.get(i)).intValue();
return fields;
}
private int findCommentEnd(String code, int pos) {
while (pos < code.length()) {
pos= code.indexOf('*', pos);
if (pos == -1 || pos == code.length() - 1)
break;
if (code.charAt(pos + 1) == '/')
return pos;
pos++;
}
return -1;
}
private int findLiteralEnd(String code, int pos, char peer) {
while (pos < code.length()) {
char ch= code.charAt(pos);
if (ch == peer)
return pos;
if (ch == '\\')
pos += 2;
else
pos++;
}
return -1;
}
private TextPresentation createPresentation(int position, int[] parameterCommas, int[] argumentCommas, String contextInfo) {
int length= contextInfo.length();
TextPresentation p= new TextPresentation();
int boldStart= 0;
int boldEnd= length;
for (int i= 0; i < argumentCommas.length; i++) {
int argumentComma= argumentCommas[i];
int parameterComma= parameterCommas[i];
if (argumentComma < position)
boldStart= parameterComma + 1;
if (argumentComma >= position) {
boldEnd= parameterComma;
break;
}
}
if (boldStart > 0)
p.addStyleRange(new StyleRange(0, boldStart, null, null, SWT.NORMAL));
p.addStyleRange(new StyleRange(boldStart, boldEnd - boldStart, null, null, SWT.BOLD));
if (boldEnd < length)
p.addStyleRange(new StyleRange(boldEnd, length - boldEnd, null, null, SWT.NORMAL));
// TODO handle no range at all
return p;
}
private static void assertEquals(TextPresentation expected, TextPresentation actual) {
// check lengths
assertTrue(expected.getDenumerableRanges() == actual.getDenumerableRanges());
// check default range
assertEquals(expected.getDefaultStyleRange(), actual.getDefaultStyleRange());
// check rest
Iterator e1= expected.getAllStyleRangeIterator();
Iterator e2= actual.getAllStyleRangeIterator();
while (e1.hasNext())
assertEquals(e1.next(), e2.next());
}
protected String print(TextPresentation presentation) {
StringBuffer buf= new StringBuffer();
if (presentation != null) {
// default range
buf.append("Default style range: ");
StyleRange range= presentation.getDefaultStyleRange();
if (range != null)
buf.append(range.toString());
buf.append('\n');
// rest
Iterator e= presentation.getAllStyleRangeIterator();
while (e.hasNext()) {
buf.append(e.next().toString());
buf.append('\n');
}
}
return buf.toString();
}
public void testValidPositions() {
assertValidPositions("(a, b, c)");
}
public void testValidPositionsWithComment() {
assertValidPositions("(a, b /* the ( argument */, c)");
}
public void testValidPositionsWithString() {
assertValidPositions("(a, \"foo, bar, and such\", c)");
}
public void testValidGenericPositions() throws Exception {
assertValidPositions("(new A<T>(), new B<T>())");
}
public void testValidAllPositions() throws Exception {
assertValidPositions("(new HashMap<String, HashMap<String,Integer[]>>(), p1, p2)");
}
public void testValidArrayPositions() throws Exception {
assertValidPositions("(foo[], bar[13])");
}
/**
* Asserts that the context information is invalid both at both borders of the passed string,
* but valid at each position within the string.
*
* @param code the code to test, typically a parenthesized expression such as
* <code>(a, b, c)</code>
*/
private void assertValidPositions(final String code) {
fDocument.set(code + " ");
fTextViewer.setDocument(fDocument);
IContextInformation info= new ContextInformation("context", "info");
fValidator.install(info, fTextViewer, 1);
assertTrue(!fValidator.isContextInformationValid(0));
final int length= code.length();
final int firstInnerPosition= 1;
final int lastInnerPosition= length - 1;
// forward
for (int pos= firstInnerPosition; pos <= lastInnerPosition; pos++)
assertTrue(fValidator.isContextInformationValid(pos));
assertTrue(!fValidator.isContextInformationValid(length));
// backward
for (int pos= lastInnerPosition; pos >= firstInnerPosition; pos--)
assertTrue(fValidator.isContextInformationValid(pos));
assertTrue(!fValidator.isContextInformationValid(0));
}
}