diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategyTest.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategyTest.java | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategyTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategyTest.java new file mode 100644 index 000000000..27661b3f2 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/AndroidXmlAutoEditStrategyTest.java @@ -0,0 +1,473 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.eclipse.org/org/documents/epl-v10.php + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.ide.eclipse.adt.internal.editors; + +import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.AdtProjectTest; + +import org.eclipse.core.resources.IFile; +import org.eclipse.jface.text.DocumentCommand; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; + +@SuppressWarnings("javadoc") +public class AndroidXmlAutoEditStrategyTest extends AdtProjectTest { + + public void checkInsertNewline(String before, String after) throws Exception { + AndroidXmlAutoEditStrategy s = new AndroidXmlAutoEditStrategy(); + + // All tests just operate on the "edithandling" document; the contents are + // ignored and replaced with the before-document passed in + IFile file = getLayoutFile(getProject(), "edithandling.xml"); + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + assertNotNull(page); + IEditorPart editor = IDE.openEditor(page, file); + assertTrue(editor instanceof AndroidXmlEditor); + AndroidXmlEditor layoutEditor = (AndroidXmlEditor) editor; + ISourceViewer viewer = layoutEditor.getStructuredSourceViewer(); + + String newDocumentContent = stripCaret(before); + IDocument document = viewer.getDocument(); + document.replace(0, document.getLength(), newDocumentContent); + + // Determine the offset, and possibly make text range selections as well + int offset = updateCaret(viewer, before); + + DocumentCommand c = new TestDocumentCommand(); + c.doit = true; + c.offset = offset; + c.caretOffset = -1; + c.length = 0; + c.text = "\n"; + + s.customizeDocumentCommand(document, c); + + if (c.doit) { + if (c.length == 0 && c.text == null) { + return; + } + + document.replace(c.offset, c.length, c.text); + + int caretOffset = c.offset + c.text.length(); + + // The shiftsCaret flag doesn't behave the way it's documented to + //if (c.shiftsCaret && c.caretOffset != -1) { + if (c.caretOffset != -1) { + caretOffset = c.caretOffset; + } + viewer.setSelectedRange(caretOffset, 0); + } + + String text = document.get(); + Point selectedRange = viewer.getSelectedRange(); + assert selectedRange.y == 0; + String textWithCaret = text; + if (selectedRange.x >= 0) { + textWithCaret = text.substring(0, selectedRange.x) + "^" + + text.substring(selectedRange.x); + } + + assertEquals(after, textWithCaret); + } + + private static String stripCaret(String s) { + int index = s.indexOf('^'); + assertTrue(index != -1); + return s.substring(0, index) + s.substring(index + 1); + } + + public void testCornerCase1() throws Exception { + checkInsertNewline("^", "\n^"); + } + + public void testCornerCase2() throws Exception { + checkInsertNewline( + "\n^", + + "\n\n^"); + } + + public void testCornerCase3() throws Exception { + checkInsertNewline( + " ^", + + " \n" + + " ^"); + } + + public void testSimpleIndentation1() throws Exception { + checkInsertNewline( + " ^ ", + + " \n" + + " ^ "); + } + + public void testSimpleIndentation2() throws Exception { + checkInsertNewline( + "\n" + + " foo^\n", + + "\n" + + " foo\n" + + " ^\n"); + } + + public void testSimpleIndentation3() throws Exception { + checkInsertNewline( + "\n" + + " <newtag>^\n", + + "\n" + + " <newtag>\n" + + " ^\n"); + } + + public void testSimpleIndentation4() throws Exception { + checkInsertNewline( + "\n" + + " <newtag/>^\n", + + "\n" + + " <newtag/>\n" + + " ^\n"); + } + + public void testSimpleIndentation5() throws Exception { + checkInsertNewline( + "\n" + + " <newtag^\n", + "\n" + + " <newtag\n" + + " ^\n"); + } + + public void testSplitAttribute() throws Exception { + checkInsertNewline( + "\n" + + " <newtag ^attribute='value'/>\n", + + "\n" + + " <newtag \n" + + " ^attribute='value'/>\n"); + } + + public void testIndentationInComments1() throws Exception { + // Make sure that inside a comment we ignore tags etc + checkInsertNewline( + "<!--\n foo^\n--->\n", + + "<!--\n foo\n ^\n--->\n"); + } + + public void testIndentationInComments2() throws Exception { + // Make sure that inside a comment we ignore tags etc + checkInsertNewline( + "\n" + + "<!--\n" + + "<foo><^\n" + + "-->\n", + + "\n" + + "<!--\n" + + "<foo><\n" + + "^\n" + + "-->\n"); + } + + public void testSurroundCaret() throws Exception { + checkInsertNewline( + "\n" + + " <item>^</item>\n", + + "\n" + + " <item>\n" + + " ^\n" + + " </item>\n"); + } + + public void testSurroundCaret2() throws Exception { + // This test combines both surround with and continuing earlier lines (where + // it searches for a matching tag) + checkInsertNewline( + "\n" + + " <foo\n" + + " name='value'>^</foo>\n", + + "\n" + + " <foo\n" + + " name='value'>\n" + + " ^\n" + + " </foo>\n"); + } + + public void testContinueEarlierLine1() throws Exception { + // Here we need to indent to the exact location of an earlier line + checkInsertNewline( + "\n" + + " <foo\n" + + " name='value'/>^\n", + + "\n" + + " <foo\n" + + " name='value'/>\n" + + " ^\n"); + } + + public void testContinueEarlierLine2() throws Exception { + checkInsertNewline( + "\n" + + " <foo\n" + + " name='value'></foo>^\n", + + "\n" + + " <foo\n" + + " name='value'></foo>\n" + + " ^\n"); + // Note that + // <foo + // > + // </foo> + // does not require special handling, this only happens with the closing tag is sharing + // a line. + } + + public void testContinueEarlierLine3() throws Exception { + // Make sure the code to look up the corresponding opening tag works properly + checkInsertNewline( + "\n" + + " <foo\n" + + " name='value'><bar></bar><baz/></foo>^\n", + + "\n" + + " <foo\n" + + " name='value'><bar></bar><baz/></foo>\n" + + " ^\n"); + } + + public void testContinueEarlierLine4() throws Exception { + checkInsertNewline( + " <Button\n" + + " android:id=\"@+id/button1\"\n" + + " android:layout_width=\"wrap_content\"\n" + + " android:layout_height=\"wrap_content\"\n" + + " android:text=\"Button\" >^\n" + + " </Button>\n", + + " <Button\n" + + " android:id=\"@+id/button1\"\n" + + " android:layout_width=\"wrap_content\"\n" + + " android:layout_height=\"wrap_content\"\n" + + " android:text=\"Button\" >\n" + + " ^\n" + + " </Button>\n"); + } + + public void testIndent() throws Exception { + checkInsertNewline( + " <Button\n" + + " attr=\"value\"></Button>^\n", + + " <Button\n" + + " attr=\"value\"></Button>\n" + + " ^\n" + + ""); + } + + public void testLineBeginning1() throws Exception { + // Test that if you insert on a blank line, we just add a newline and indent + checkInsertNewline( + "<foo>\n" + + "^\n" + + "</foo>", + + "<foo>\n" + + "\n" + + " ^\n" + + "</foo>"); + } + + public void testLineBeginning2() throws Exception { + // Test that if you insert with the caret on the beginning of a line that has + // content, we insert an indent correctly + checkInsertNewline( + "<foo>\n" + + "^ <bar/>\n" + + "</foo>", + + "<foo>\n" + + "\n" + + " ^<bar/>\n" + + "</foo>"); + } + + public void testLineBeginning3() throws Exception { + checkInsertNewline( + "<foo>\n" + + " <bar>\n" + + "^\n" + + " <baz/>\n" + + " </bar>\n" + + "</foo>", + + "<foo>\n" + + " <bar>\n" + + "\n" + + " ^\n" + + " <baz/>\n" + + " </bar>\n" + + "</foo>"); + + } + + public void testLineBeginning4() throws Exception { + // Test that if you insert with the caret on the beginning of a line that has + // content, we insert an indent correctly + checkInsertNewline( + "<foo>\n" + + " <bar>\n" + + "\n" + + "^ <baz/>\n" + + " </bar>\n" + + "</foo>", + + "<foo>\n" + + " <bar>\n" + + "\n" + + "\n" + + " ^<baz/>\n" + + " </bar>\n" + + "</foo>"); + } + + public void testLineBeginning5() throws Exception { + // Test that if you insert with the caret on the beginning of a line that has + // content, we insert an indent correctly + checkInsertNewline( + "<foo>\n" + + " <bar>\n" + + "\n" + + " ^ <baz/>\n" + + " </bar>\n" + + "</foo>", + + "<foo>\n" + + " <bar>\n" + + "\n" + + " \n" + + " ^<baz/>\n" + + " </bar>\n" + + "</foo>"); + } + + public void testLineBeginning6() throws Exception { + + checkInsertNewline( + " <foo>\n" + + " <bar>\n" + + " \n" + + " \n" + + "^ </bar>\n" + + " </foo>\n", + + " <foo>\n" + + " <bar>\n" + + " \n" + + " \n" + + "\n" + + " ^</bar>\n" + + " </foo>\n"); + } + + public void testBlankContinuation() throws Exception { + + checkInsertNewline( + " <foo>\n" + + " <bar>\n" + + " ^\n" + + " </bar>\n" + + " </foo>\n" + + "", + + " <foo>\n" + + " <bar>\n" + + " \n" + + " ^\n" + + " </bar>\n" + + " </foo>\n" + + ""); + } + + public void testIssue22332a() throws Exception { + checkInsertNewline( + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<resources>\n" + + "\n" + + " <string name=\"hello\">Hello World, MainActivity!</string>^\n" + + "\n" + + "</resources>", + + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<resources>\n" + + "\n" + + " <string name=\"hello\">Hello World, MainActivity!</string>\n" + + " ^\n" + + "\n" + + "</resources>"); + } + + public void testIssue22332b() throws Exception { + checkInsertNewline( + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<resources>\n" + + "\n" + + " <string name=\"hello\">Hello World, MainActivity!</string>\n" + + " ^\n" + + "\n" + + "</resources>", + + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + + "<resources>\n" + + "\n" + + " <string name=\"hello\">Hello World, MainActivity!</string>\n" + + " \n" + + " ^\n" + + "\n" + + "</resources>"); + } + + /** + * To test + * When you press / after < I should reindent the current line. For example, + * if you have + * <foo> + * <bar> + * </ the moment you've typed this we should dedent it back out + * When you press newline we need to reindent + */ + + /** Subclassed for test usage since constructor is protected */ + private class TestDocumentCommand extends DocumentCommand { + public TestDocumentCommand() { + } + } +} |