| /******************************************************************************* |
| * 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); |
| } |
| } |