blob: e6b4286e0ff1322ab8903b415c7c6dcc0e0fe928 [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 junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Event;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.text.tests.Accessor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.link.LinkedModeModel;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.ui.PartInitException;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.jdt.text.tests.performance.DisplayHelper;
import org.eclipse.jdt.text.tests.performance.EditorTestHelper;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor;
/**
* Tests the automatic bracket insertion feature of the CUEditor. Also tests
* linked mode along the way.
*
* @since 3.1
*/
public class BracketInserterTest extends TestCase {
private static final String PROJECT= "BracketInserterTest";
private static final String SRC= "src";
private static final String SEP= "/";
private static final String CU_NAME= "PR75423.java";
private static final String CU_CONTENTS= "package com.example.bugs;\n" +
"\n" +
"import java.lang.String;\n" +
"import java.lang.Integer;\n" +
"\n" +
"public class PR75423 {\n" +
" String string;\n" +
" Integer integer;\n" +
"\n" +
" public static void main(String[] args) {\n" +
" \n" +
" }\n" +
" void foo(String[] args) {\n" +
" \n" +
" }\n" +
" \n" +
" HashMap hm= new HashMap();\n" +
"}\n";
// document offsets
private static final int BODY_OFFSET= 196;
private static final int ARGS_OFFSET= 171;
private static final int BRACKETS_OFFSET= 178;
private static final int MAIN_VOID_OFFSET= 161;
private static final int FOO_VOID_OFFSET= 207;
private static final int FIELD_OFFSET= 264;
public static Test suite() {
return new TestSuite(BracketInserterTest.class);
}
private JavaEditor fEditor;
private StyledText fTextWidget;
private IDocument fDocument;
private Accessor fAccessor;
private IJavaProject fProject;
protected void setUp() throws Exception {
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, true);
}
private void setUpProject(String sourceLevel) throws CoreException, JavaModelException {
fProject= JavaProjectHelper.createJavaProject(PROJECT, "bin");
fProject.setOption(JavaCore.COMPILER_SOURCE, sourceLevel);
JavaProjectHelper.addSourceContainer(fProject, SRC);
IPackageFragment fragment= fProject.findPackageFragment(new Path(SEP + PROJECT + SEP + SRC));
fragment.createCompilationUnit(CU_NAME, CU_CONTENTS, true, new NullProgressMonitor());
}
private void setUpEditor() {
fEditor= openJavaEditor(new Path(SEP + PROJECT + SEP + SRC + SEP + CU_NAME));
assertNotNull(fEditor);
fTextWidget= fEditor.getViewer().getTextWidget();
assertNotNull(fTextWidget);
fAccessor= new Accessor(fTextWidget, StyledText.class);
fDocument= fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
assertNotNull(fDocument);
}
private JavaEditor openJavaEditor(IPath path) {
IFile file= ResourcesPlugin.getWorkspace().getRoot().getFile(path);
assertTrue(file != null && file.exists());
try {
return (JavaEditor)EditorTestHelper.openInEditor(file, true);
} catch (PartInitException e) {
fail();
return null;
}
}
protected void tearDown() throws Exception {
EditorTestHelper.closeEditor(fEditor);
JavaProjectHelper.delete(fProject);
// reset to defaults
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, true);
}
public void testInsertClosingParenthesis() throws BadLocationException, JavaModelException, CoreException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertSingleLinkedPosition(BODY_OFFSET + 1);
}
public void testDeletingParenthesis() throws JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type(SWT.BS);
assertEquals(CU_CONTENTS, fDocument.get());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testMultipleParenthesisInsertion() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 4, getCaret());
LinkedModeModel model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 4);
assertNotNull(model);
assertTrue(model.isNested());
}
public void testDeletingMultipleParenthesisInertion() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
// delete two levels
type(SWT.BS);
type(SWT.BS);
assertEquals("(())", fDocument.get(BODY_OFFSET, 4));
assertEquals(BODY_OFFSET + 2, getCaret());
LinkedModeModel model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 2);
assertNotNull(model);
assertTrue("models must be nested", model.isNested());
// delete the second-last level
type(SWT.BS);
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertEquals(BODY_OFFSET + 1, getCaret());
model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 1);
assertNotNull(model);
assertFalse("model must not be nested", model.isNested());
// delete last level
type(SWT.BS);
assertEquals(CU_CONTENTS, fDocument.get());
assertEquals(BODY_OFFSET, getCaret());
assertEquals(CU_CONTENTS, fDocument.get());
assertFalse("no linked model must exist", LinkedModeModel.hasInstalledModel(fDocument));
}
public void testNoInsertInsideText() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(ARGS_OFFSET);
type('(');
assertEquals("(St", fDocument.get(ARGS_OFFSET, 3));
assertEquals(ARGS_OFFSET + 1, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testInsertInsideBrackets() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BRACKETS_OFFSET);
type('(');
assertEquals("()", fDocument.get(BRACKETS_OFFSET, 2));
assertSingleLinkedPosition(BRACKETS_OFFSET + 1);
}
public void testPeerEntry() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type(')');
assertEquals("()", fDocument.get(BODY_OFFSET, 2));
assertEquals(BODY_OFFSET + 2, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testMultiplePeerEntry() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
type(')');
type(')');
type(')');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 7, getCaret());
LinkedModeModel model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 4);
assertNotNull(model);
assertFalse(model.isNested());
LinkedPosition position= model.findPosition(new LinkedPosition(fDocument, BODY_OFFSET + 1, 0));
assertNotNull(position);
assertEquals(BODY_OFFSET + 1, position.getOffset());
assertEquals(6, position.getLength());
type(')');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnTab() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
type('\t');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 5, getCaret());
LinkedModeModel model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 5);
assertNotNull(model);
assertTrue(model.isNested());
type('\t');
type('\t');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 7, getCaret());
model= LinkedModeModel.getModel(fDocument, BODY_OFFSET + 7);
assertNotNull(model);
assertFalse(model.isNested());
type('\t');
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnReturn() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
type(SWT.CR);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 8, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testExitOnEsc() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('(');
type('(');
type('(');
type('(');
type(SWT.ESC);
assertEquals("(((())))", fDocument.get(BODY_OFFSET, 8));
assertEquals(BODY_OFFSET + 4, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testInsertClosingQuote() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type('"');
assertEquals("\"\"", fDocument.get(BODY_OFFSET, 2));
assertSingleLinkedPosition(BODY_OFFSET + 1);
}
public void testPreferences() throws BadLocationException, JavaModelException, CoreException {
use14();
IPreferenceStore store= JavaPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_CLOSE_BRACKETS, false);
setCaret(BODY_OFFSET);
type('(');
assertEquals("(", fDocument.get(BODY_OFFSET, 1));
assertEquals(BODY_OFFSET + 1, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testAngleBracketsAsOperator() throws Exception {
use15();
setCaret(BODY_OFFSET);
type("test<");
assertEquals("test<", fDocument.get(BODY_OFFSET, 5));
assertFalse(">".equals(fDocument.get(BODY_OFFSET + 5, 1)));
assertEquals(BODY_OFFSET + 5, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testAngleBracketsIn14Project() throws BadLocationException, JavaModelException, CoreException {
use14();
setCaret(BODY_OFFSET);
type("Test<");
assertEquals("Test<", fDocument.get(BODY_OFFSET, 5));
assertFalse(">".equals(fDocument.get(BODY_OFFSET + 5, 1)));
assertEquals(BODY_OFFSET + 5, getCaret());
assertFalse(LinkedModeModel.hasInstalledModel(fDocument));
}
public void testAngleBracketsIn15Project() throws Exception {
use15();
setCaret(BODY_OFFSET);
type("Test<");
assertEquals("Test<>", fDocument.get(BODY_OFFSET, 6));
assertSingleLinkedPosition(BODY_OFFSET + 5);
}
public void testAngleBracketsInFieldDecl15() throws Exception {
use15();
setCaret(FIELD_OFFSET);
type('<');
assertEquals("HashMap<> hm", fDocument.get(FIELD_OFFSET - 7, 12));
assertSingleLinkedPosition(FIELD_OFFSET + 1);
}
public void testAngleBracketsInsideMethodDecl15() throws Exception {
use15();
setCaret(MAIN_VOID_OFFSET);
type('<');
assertEquals("public static <>void", fDocument.get(MAIN_VOID_OFFSET - 14, 20));
assertSingleLinkedPosition(MAIN_VOID_OFFSET + 1);
}
public void testAngleBracketsBeforeMethodDecl15() throws Exception {
use15();
setCaret(FOO_VOID_OFFSET);
type('<');
assertEquals("<>void foo", fDocument.get(FOO_VOID_OFFSET, 10));
assertSingleLinkedPosition(FOO_VOID_OFFSET + 1);
}
/* utilities */
private void assertSingleLinkedPosition(int offset) {
assertEquals(offset, getCaret());
LinkedModeModel model= LinkedModeModel.getModel(fDocument, offset);
assertNotNull(model);
assertFalse(model.isNested());
LinkedPosition position= model.findPosition(new LinkedPosition(fDocument, offset, 0));
assertNotNull(position);
assertEquals(offset, position.getOffset());
assertEquals(0, position.getLength());
}
private void use15() throws CoreException, JavaModelException {
setUpProject(JavaCore.VERSION_1_5);
setUpEditor();
}
private void use14() throws CoreException, JavaModelException {
setUpProject(JavaCore.VERSION_1_4);
setUpEditor();
}
/**
* Type characters into the styled text.
*
* @param characters the characters to type
*/
private void type(CharSequence characters) {
for (int i= 0; i < characters.length(); i++)
type(characters.charAt(i), 0, 0);
}
/**
* Type a character into the styled text.
*
* @param character the character to type
*/
private void type(char character) {
type(character, 0, 0);
}
/**
* Type a character into the styled text.
*
* @param character the character to type
* @param keyCode the key code
* @param stateMask the state mask
*/
private void type(char character, int keyCode, int stateMask) {
Event event= new Event();
event.character= character;
event.keyCode= keyCode;
event.stateMask= stateMask;
fAccessor.invoke("handleKeyDown", new Object[] {event});
new DisplayHelper() {
protected boolean condition() {
return false;
}
}.waitForCondition(EditorTestHelper.getActiveDisplay(), 200);
}
private int getCaret() {
return ((ITextSelection) fEditor.getSelectionProvider().getSelection()).getOffset();
}
private void setCaret(int offset) {
fEditor.getSelectionProvider().setSelection(new TextSelection(offset, 0));
int newOffset= ((ITextSelection)fEditor.getSelectionProvider().getSelection()).getOffset();
assertEquals(offset, newOffset);
}
}