0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.ruby;
0043:
0044: import java.util.List;
0045: import javax.swing.JTextArea;
0046: import javax.swing.text.BadLocationException;
0047: import javax.swing.text.Caret;
0048: import org.netbeans.modules.gsf.api.CompilationInfo;
0049: import org.netbeans.modules.gsf.api.OffsetRange;
0050: import org.netbeans.editor.BaseDocument;
0051: import org.netbeans.editor.Utilities;
0052: import org.netbeans.lib.editor.util.swing.DocumentUtilities;
0053: import org.netbeans.modules.ruby.lexer.LexUtilities;
0054: import org.openide.filesystems.FileObject;
0055:
0056: /**
0057: * @todo Test that if you insert x="" and then DELETE the ", it wipes out BOTH of them!
0058: * @todo Try typing in whole source files and other than tracking missing end and } closure
0059: * statements the buffer should be identical - both in terms of quotes to the rhs not having
0060: * accumulated as well as indentation being correct.
0061: * @todo
0062: * // TODO: Test
0063: * // - backspace deletion
0064: * // - entering incomplete output
0065: * // automatic reindentation of "end", "else" etc.
0066: *
0067: *
0068: *
0069: * @author Tor Norbye
0070: */
0071: public class BracketCompleterTest extends RubyTestBase {
0072:
0073: public BracketCompleterTest(String testName) {
0074: super (testName);
0075: }
0076:
0077: private void match(String original) throws BadLocationException {
0078: BracketCompleter bc = new BracketCompleter();
0079:
0080: int caretPos = original.indexOf('^');
0081:
0082: original = original.substring(0, caretPos)
0083: + original.substring(caretPos + 1);
0084: int matchingCaretPos = original.indexOf('^');
0085: assert caretPos < matchingCaretPos;
0086: original = original.substring(0, matchingCaretPos)
0087: + original.substring(matchingCaretPos + 1);
0088:
0089: BaseDocument doc = getDocument(original);
0090:
0091: OffsetRange range = bc.findMatching(doc, caretPos);
0092:
0093: assertNotSame("Didn't find matching token for "
0094: + LexUtilities.getToken(doc, caretPos).text()
0095: .toString(), OffsetRange.NONE, range);
0096: assertEquals("forward match not found; found '"
0097: + doc.getText(range.getStart(), range.getLength())
0098: + "' instead of "
0099: + LexUtilities.getToken(doc, matchingCaretPos).text()
0100: .toString(), matchingCaretPos, range.getStart());
0101:
0102: // Perform reverse match
0103: range = bc.findMatching(doc, matchingCaretPos);
0104:
0105: assertNotSame(OffsetRange.NONE, range);
0106: assertEquals("reverse match not found; found '"
0107: + doc.getText(range.getStart(), range.getLength())
0108: + "' instead of "
0109: + LexUtilities.getToken(doc, caretPos).text()
0110: .toString(), caretPos, range.getStart());
0111: }
0112:
0113: private void insertBreak(String original, String expected)
0114: throws BadLocationException {
0115: BracketCompleter bc = new BracketCompleter();
0116:
0117: int insertOffset = original.indexOf('^');
0118: int finalCaretPos = expected.indexOf('^');
0119: original = original.substring(0, insertOffset)
0120: + original.substring(insertOffset + 1);
0121: expected = expected.substring(0, finalCaretPos)
0122: + expected.substring(finalCaretPos + 1);
0123:
0124: BaseDocument doc = getDocument(original);
0125:
0126: JTextArea ta = new JTextArea(doc);
0127: Caret caret = ta.getCaret();
0128: caret.setDot(insertOffset);
0129: int newOffset = bc.beforeBreak(doc, insertOffset, ta);
0130: doc.atomicLock();
0131: DocumentUtilities.setTypingModification(doc, true);
0132:
0133: try {
0134: doc.insertString(caret.getDot(), "\n", null);
0135: // Indent the new line
0136: Formatter formatter = new Formatter();
0137: //ParserResult result = parse(fo);
0138:
0139: int startPos = caret.getDot() + 1;
0140: int endPos = startPos + 1;
0141:
0142: //ParserResult result = parse(fo);
0143: formatter.reindent(doc, startPos, endPos);
0144: int indent = LexUtilities.getLineIndent(doc,
0145: insertOffset + 1);
0146:
0147: //bc.afterBreak(doc, insertOffset, caret);
0148: String formatted = doc.getText(0, doc.getLength());
0149: assertEquals(expected, formatted);
0150: if (newOffset != -1) {
0151: caret.setDot(newOffset);
0152: } else {
0153: caret.setDot(insertOffset + 1 + indent);
0154: }
0155: if (finalCaretPos != -1) {
0156: assertEquals(finalCaretPos, caret.getDot());
0157: }
0158: } finally {
0159: DocumentUtilities.setTypingModification(doc, false);
0160: doc.atomicUnlock();
0161: }
0162: }
0163:
0164: private void insertChar(String original, char insertText,
0165: String expected) throws BadLocationException {
0166: insertChar(original, insertText, expected, null);
0167: }
0168:
0169: private void insertChar(String original, char insertText,
0170: String expected, String selection)
0171: throws BadLocationException {
0172: insertChar(original, insertText, expected, selection, false);
0173: }
0174:
0175: private void insertChar(String original, char insertText,
0176: String expected, String selection, boolean codeTemplateMode)
0177: throws BadLocationException {
0178: int insertOffset = original.indexOf('^');
0179: int finalCaretPos = expected.indexOf('^');
0180: original = original.substring(0, insertOffset)
0181: + original.substring(insertOffset + 1);
0182: expected = expected.substring(0, finalCaretPos)
0183: + expected.substring(finalCaretPos + 1);
0184:
0185: BracketCompleter bc = new BracketCompleter();
0186:
0187: BaseDocument doc = getDocument(original);
0188:
0189: if (codeTemplateMode) {
0190: // Copied from editor/codetemplates/src/org/netbeans/lib/editor/codetemplates/CodeTemplateInsertHandler.java
0191: String EDITING_TEMPLATE_DOC_PROPERTY = "processing-code-template"; // NOI18N
0192: doc
0193: .putProperty(EDITING_TEMPLATE_DOC_PROPERTY,
0194: Boolean.TRUE);
0195: }
0196:
0197: JTextArea ta = new JTextArea(doc);
0198: Caret caret = ta.getCaret();
0199: caret.setDot(insertOffset);
0200: if (selection != null) {
0201: int start = original.indexOf(selection);
0202: assertTrue(start != -1);
0203: assertTrue(
0204: "Ambiguous selection - multiple occurrences of selection string",
0205: original.indexOf(selection, start + 1) == -1);
0206: ta.setSelectionStart(start);
0207: ta.setSelectionEnd(start + selection.length());
0208: assertEquals(selection, ta.getSelectedText());
0209: }
0210:
0211: doc.atomicLock();
0212: DocumentUtilities.setTypingModification(doc, true);
0213:
0214: boolean handled = false;
0215: try {
0216: handled = bc.beforeCharInserted(doc, insertOffset, ta,
0217: insertText);
0218: } finally {
0219: DocumentUtilities.setTypingModification(doc, false);
0220: doc.atomicUnlock();
0221: }
0222: if (!handled) {
0223: if (ta.getSelectedText() != null
0224: && ta.getSelectedText().length() > 0) {
0225: insertOffset = ta.getSelectionStart();
0226: doc.remove(ta.getSelectionStart(), ta.getSelectionEnd()
0227: - ta.getSelectionStart());
0228: caret.setDot(insertOffset);
0229: }
0230: doc.insertString(caret.getDot(), "" + insertText, null);
0231: caret.setDot(insertOffset + 1);
0232: bc.afterCharInserted(doc, insertOffset, ta, insertText);
0233: }
0234: String formatted = doc.getText(0, doc.getLength());
0235: assertEquals(expected, formatted);
0236: if (finalCaretPos != -1) {
0237: assertEquals(finalCaretPos, caret.getDot());
0238: }
0239: }
0240:
0241: private void deleteChar(String original, String expected)
0242: throws BadLocationException {
0243: int afterRemoveOffset = original.indexOf('^');
0244: int finalCaretPos = expected.indexOf('^');
0245: original = original.substring(0, afterRemoveOffset)
0246: + original.substring(afterRemoveOffset + 1);
0247: expected = expected.substring(0, finalCaretPos)
0248: + expected.substring(finalCaretPos + 1);
0249:
0250: BracketCompleter bc = new BracketCompleter();
0251:
0252: BaseDocument doc = getDocument(original);
0253:
0254: JTextArea ta = new JTextArea(doc);
0255: Caret caret = ta.getCaret();
0256: caret.setDot(afterRemoveOffset);
0257: int dot = afterRemoveOffset;
0258: char ch = doc.getChars(dot - 1, 1)[0];
0259:
0260: doc.atomicLock();
0261: DocumentUtilities.setTypingModification(doc, true);
0262:
0263: try {
0264: doc.remove(dot - 1, 1);
0265: caret.setDot(dot - 1);
0266: boolean handled = bc.charBackspaced(doc, dot - 1, ta, ch);
0267: String formatted = doc.getText(0, doc.getLength());
0268: assertEquals(expected, formatted);
0269: if (finalCaretPos != -1) {
0270: assertEquals(finalCaretPos, caret.getDot());
0271: }
0272: } finally {
0273: DocumentUtilities.setTypingModification(doc, false);
0274: doc.atomicUnlock();
0275: }
0276: }
0277:
0278: private void deleteWord(String original, String expected)
0279: throws BadLocationException {
0280: // Try deleting the word not just using the testcase but also surrounded by strings
0281: // to make sure there's no problem with lexer token directions
0282: deleteWordImpl(original, expected);
0283: deleteWordImpl(original + "foo", expected + "foo");
0284: deleteWordImpl("foo" + original, "foo" + expected);
0285: deleteWordImpl(original + "::", expected + "::");
0286: deleteWordImpl(original + "::", expected + "::");
0287: }
0288:
0289: private void deleteWordImpl(String original, String expected)
0290: throws BadLocationException {
0291: int afterRemoveOffset = original.indexOf('^');
0292: int finalCaretPos = expected.indexOf('^');
0293: original = original.substring(0, afterRemoveOffset)
0294: + original.substring(afterRemoveOffset + 1);
0295: expected = expected.substring(0, finalCaretPos)
0296: + expected.substring(finalCaretPos + 1);
0297:
0298: BracketCompleter bc = new BracketCompleter();
0299:
0300: BaseDocument doc = getDocument(original);
0301:
0302: JTextArea ta = new JTextArea(doc);
0303: Caret caret = ta.getCaret();
0304: caret.setDot(afterRemoveOffset);
0305: int dot = afterRemoveOffset;
0306: //REMOVE char ch = doc.getChars(dot-1, 1)[0];
0307:
0308: int begin = bc.getNextWordOffset(doc, dot, true);
0309: if (begin == -1) {
0310: begin = Utilities.getPreviousWord(ta, dot);
0311: }
0312:
0313: doc.atomicLock();
0314: DocumentUtilities.setTypingModification(doc, true);
0315:
0316: try {
0317: doc.remove(begin, dot - begin);
0318: caret.setDot(begin);
0319: String formatted = doc.getText(0, doc.getLength());
0320: assertEquals(expected, formatted);
0321: if (finalCaretPos != -1) {
0322: assertEquals(finalCaretPos, caret.getDot());
0323: }
0324: } finally {
0325: DocumentUtilities.setTypingModification(doc, false);
0326: doc.atomicUnlock();
0327: }
0328: }
0329:
0330: private void assertLogicalRange(String source, boolean up,
0331: String expected) throws Exception {
0332: String BEGIN = "%<%"; // NOI18N
0333: String END = "%>%"; // NOI18N
0334: int sourceStartPos = source.indexOf(BEGIN);
0335: if (sourceStartPos != -1) {
0336: source = source.substring(0, sourceStartPos)
0337: + source.substring(sourceStartPos + BEGIN.length());
0338: }
0339:
0340: int caretPos = source.indexOf('^');
0341: source = source.substring(0, caretPos)
0342: + source.substring(caretPos + 1);
0343:
0344: int sourceEndPos = source.indexOf(END);
0345: if (sourceEndPos != -1) {
0346: source = source.substring(0, sourceEndPos)
0347: + source.substring(sourceEndPos + END.length());
0348: }
0349:
0350: int expectedStartPos = expected.indexOf(BEGIN);
0351: if (expectedStartPos != -1) {
0352: expected = expected.substring(0, expectedStartPos)
0353: + expected.substring(expectedStartPos
0354: + BEGIN.length());
0355: }
0356:
0357: int expectedCaretPos = expected.indexOf('^');
0358: expected = expected.substring(0, expectedCaretPos)
0359: + expected.substring(expectedCaretPos + 1);
0360:
0361: int expectedEndPos = expected.indexOf(END);
0362: if (expectedEndPos != -1) {
0363: expected = expected.substring(0, expectedEndPos)
0364: + expected.substring(expectedEndPos + END.length());
0365: }
0366:
0367: assertEquals("Only range markers should differ", source,
0368: expected);
0369:
0370: OffsetRange selected = null;
0371:
0372: BaseDocument doc = getDocument(source);
0373: FileObject fileObject = null;
0374: CompilationInfo info = new TestCompilationInfo(this ,
0375: fileObject, doc, source);
0376:
0377: BracketCompleter completer = new BracketCompleter();
0378: List<OffsetRange> ranges = completer.findLogicalRanges(info,
0379: caretPos);
0380: OffsetRange expectedRange;
0381: if (expectedStartPos != -1) {
0382: expectedRange = new OffsetRange(expectedStartPos,
0383: expectedEndPos);
0384: } else {
0385: expectedRange = new OffsetRange(expectedCaretPos,
0386: expectedCaretPos);
0387: }
0388:
0389: if (sourceStartPos != -1) {
0390: assert sourceEndPos != -1;
0391: selected = new OffsetRange(sourceStartPos, sourceEndPos);
0392:
0393: for (int i = 0; i < ranges.size(); i++) {
0394: if (ranges.get(i).equals(selected)) {
0395: if (up) {
0396: assertTrue(i < ranges.size() - 1);
0397: OffsetRange was = ranges.get(i + 1);
0398: assertEquals("Wrong selection: expected \""
0399: + expected.substring(expectedRange
0400: .getStart(), expectedRange
0401: .getEnd())
0402: + "\" and was \""
0403: + source.substring(was.getStart(), was
0404: .getEnd()) + "\"",
0405: expectedRange, was);
0406: return;
0407: } else {
0408: if (i == 0) {
0409: assertEquals(caretPos, expectedCaretPos);
0410: return;
0411: }
0412: OffsetRange was = ranges.get(i - 1);
0413: assertEquals("Wrong selection: expected \""
0414: + expected.substring(expectedRange
0415: .getStart(), expectedRange
0416: .getEnd())
0417: + "\" and was \""
0418: + source.substring(was.getStart(), was
0419: .getEnd()) + "\"",
0420: expectedRange, was);
0421: return;
0422: }
0423: }
0424: }
0425: fail("Selection range " + selected + " is not in the range");
0426: } else {
0427: assert ranges.size() > 0;
0428: OffsetRange was = ranges.get(0);
0429: assertEquals("Wrong selection: expected \""
0430: + expected.substring(expectedRange.getStart(),
0431: expectedRange.getEnd()) + "\" and was \""
0432: + source.substring(was.getStart(), was.getEnd())
0433: + "\"", expectedRange, was);
0434: return;
0435: }
0436: }
0437:
0438: public void testInsertX() throws Exception {
0439: insertChar("c^ass", 'l', "cl^ass");
0440: }
0441:
0442: public void testInsertX2() throws Exception {
0443: insertChar("clas^", 's', "class^");
0444: }
0445:
0446: public void testNoMatchInComments() throws Exception {
0447: insertChar("# Hello^", '\'', "# Hello'^");
0448: insertChar("# Hello^", '"', "# Hello\"^");
0449: insertChar("# Hello^", '[', "# Hello[^");
0450: insertChar("# Hello^", '(', "# Hello(^");
0451: }
0452:
0453: public void testNoMatchInStrings() throws Exception {
0454: insertChar("x = \"^\"", '\'', "x = \"'^\"");
0455: insertChar("x = \"^\"", '[', "x = \"[^\"");
0456: insertChar("x = \"^\"", '(', "x = \"(^\"");
0457: insertChar("x = \"^)\"", ')', "x = \")^)\"");
0458: insertChar("x = '^'", '"', "x = '\"^'");
0459: insertChar("x = \"\nf^\n\"", '\'', "x = \"\nf'^\n\"");
0460: insertChar("x = \"\nf^\n\"", '[', "x = \"\nf[^\n\"");
0461: insertChar("x = \"\nf^\n\"", '(', "x = \"\nf(^\n\"");
0462: insertChar("x = '\nf^\n'", '"', "x = '\nf\"^\n'");
0463: }
0464:
0465: public void testSingleQuotes1() throws Exception {
0466: insertChar("x = ^", '\'', "x = '^'");
0467: }
0468:
0469: public void testSingleQuotes2() throws Exception {
0470: insertChar("x = '^'", '\'', "x = ''^");
0471: }
0472:
0473: public void testSingleQuotes3() throws Exception {
0474: insertChar("x = '^'", 'a', "x = 'a^'");
0475: }
0476:
0477: public void testSingleQuotes4() throws Exception {
0478: insertChar("x = '\\^'", '\'', "x = '\\'^'");
0479: }
0480:
0481: public void testDoubleQuotes1() throws Exception {
0482: insertChar("x = ^", '"', "x = \"^\"");
0483: }
0484:
0485: public void testDoubleQuotes2() throws Exception {
0486: insertChar("x = \"^\"", '"', "x = \"\"^");
0487: }
0488:
0489: public void testDoubleQuotes3() throws Exception {
0490: insertChar("x = \"^\"", 'a', "x = \"a^\"");
0491: }
0492:
0493: public void testDobuleQuotes4() throws Exception {
0494: insertChar("x = \"\\^\"", '"', "x = \"\\\"^\"");
0495: }
0496:
0497: public void testDocs() throws Exception {
0498: insertBreak("=begin^\n", "=begin\n^\n=end\n");
0499: }
0500:
0501: public void testDocsEnd() throws Exception {
0502: insertBreak("=begin^", "=begin\n^\n=end");
0503: }
0504:
0505: public void testDocsEnd2() throws Exception {
0506: insertBreak("def foo\nend\n=begin^",
0507: "def foo\nend\n=begin\n^\n=end");
0508: }
0509:
0510: public void testInsertEnd1() throws Exception {
0511: insertBreak("x^", "x\n^");
0512: }
0513:
0514: public void testInsertEnd2() throws Exception {
0515: insertBreak("class Foo^", "class Foo\n ^\nend");
0516: }
0517:
0518: public void testInsertEnd3() throws Exception {
0519: insertBreak("class Foo^\nend", "class Foo\n ^\nend");
0520: }
0521:
0522: public void testInsertEnd4() throws Exception {
0523: insertBreak(
0524: "foo bar, {:x => :x,\n :y => :y, ^:z => :z} do\nend\n",
0525: "foo bar, {:x => :x,\n :y => :y, \n ^:z => :z} do\nend\n");
0526: }
0527:
0528: public void testInsertEnd5() throws Exception {
0529: insertBreak("if a_condition ^thing()",
0530: "if a_condition \n ^thing()\nend");
0531: }
0532:
0533: public void testInsertIf1() throws Exception {
0534: insertBreak(" if true^", " if true\n ^\n end");
0535: }
0536:
0537: // This doesn't work
0538: // public void testInsertIf2() throws Exception {
0539: // insertBreak(" if true\n else", 20, " if true\n else\n end", 27);
0540: // }
0541:
0542: public void testBrackets1() throws Exception {
0543: insertChar("x = ^", '[', "x = [^]");
0544: }
0545:
0546: public void testBrackets2() throws Exception {
0547: insertChar("x = [^]", ']', "x = []^");
0548: }
0549:
0550: public void testBracketsSpecialName() throws Exception {
0551: // "[]" and "[]=" are valid method names!
0552: insertChar("def ^", '[', "def [^]");
0553: }
0554:
0555: public void testBracketsSpecialName2() throws Exception {
0556: // "[]" and "[]=" are valid method names!
0557: insertChar("def [^]", ']', "def []^");
0558: }
0559:
0560: public void testBrackets3() throws Exception {
0561: insertChar("x = [^]", 'a', "x = [a^]");
0562: }
0563:
0564: public void testBrackets4() throws Exception {
0565: insertChar("x = [^]", '[', "x = [[^]]");
0566: }
0567:
0568: public void testBrackets5() throws Exception {
0569: insertChar("x = [[^]]", ']', "x = [[]^]");
0570: }
0571:
0572: public void testBrackets6() throws Exception {
0573: insertChar("x = [[]^]", ']', "x = [[]]^");
0574: }
0575:
0576: public void testParens1() throws Exception {
0577: insertChar("x = ^", '(', "x = (^)");
0578: }
0579:
0580: public void testParens2() throws Exception {
0581: insertChar("x = (^)", ')', "x = ()^");
0582: }
0583:
0584: public void testParens3() throws Exception {
0585: insertChar("x = (^)", 'a', "x = (a^)");
0586: }
0587:
0588: public void testParens4() throws Exception {
0589: insertChar("x = (^)", '(', "x = ((^))");
0590: }
0591:
0592: public void testParens5() throws Exception {
0593: insertChar("x = ((^))", ')', "x = (()^)");
0594: }
0595:
0596: public void testParens6() throws Exception {
0597: insertChar("x = (()^)", ')', "x = (())^");
0598: }
0599:
0600: public void testRegexp1() throws Exception {
0601: insertChar("x = ^", '/', "x = /^/");
0602: }
0603:
0604: public void testRegexp2() throws Exception {
0605: insertChar("x = /^/", '/', "x = //^");
0606: }
0607:
0608: public void testRegexp3() throws Exception {
0609: insertChar("x = /^/", 'a', "x = /a^/");
0610: }
0611:
0612: public void testRegexp4() throws Exception {
0613: insertChar("x = /\\^/", '/', "x = /\\/^/");
0614: }
0615:
0616: public void testRegexp5() throws Exception {
0617: insertChar(
0618: " regexp = /fofo^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in",
0619: '/',
0620: " regexp = /fofo/^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in");
0621: }
0622:
0623: public void testRegexp6() throws Exception {
0624: insertChar(" regexp = /fofo^\n", '/',
0625: " regexp = /fofo/^\n");
0626: }
0627:
0628: public void testRegexp7() throws Exception {
0629: insertChar("x = ^\n", '/', "x = /^/\n");
0630: }
0631:
0632: public void testRegexp8() throws Exception {
0633: insertChar("x = /^/\n", '/', "x = //^\n");
0634: }
0635:
0636: public void testRegexp9() throws Exception {
0637: insertChar("x = /^/\n", 'a', "x = /a^/\n");
0638: }
0639:
0640: public void testRegexp10() throws Exception {
0641: insertChar("x = /\\^/\n", '/', "x = /\\/^/\n");
0642: }
0643:
0644: public void testRegexp11() throws Exception {
0645: insertChar("/foo^", '/', "/foo/^");
0646: }
0647:
0648: public void testNotRegexp1() throws Exception {
0649: insertChar("x = 10 ^", '/', "x = 10 /^");
0650: }
0651:
0652: public void testNotRegexp2() throws Exception {
0653: insertChar("x = 3.14 ^", '/', "x = 3.14 /^");
0654: }
0655:
0656: // This test doesn't work; the lexer identifies x = y / as the
0657: // beginning of a regular expression. Without the space it DOES
0658: // work (see regexp4)
0659: //public void testNotRegexp3() throws Exception {
0660: // insertChar("x = y ^", '/', "x = y /^");
0661: //}
0662:
0663: public void testNotRegexp4() throws Exception {
0664: insertChar("x = y^", '/', "x = y/^");
0665: }
0666:
0667: public void testRegexpPercent1() throws Exception {
0668: insertChar("x = %r^", '(', "x = %r(^)");
0669: }
0670:
0671: public void testRegexpPercent2() throws Exception {
0672: insertChar("x = %r(^)", ')', "x = %r()^");
0673: }
0674:
0675: public void testSinglePercent1() throws Exception {
0676: insertChar("x = %q^", '(', "x = %q(^)");
0677: }
0678:
0679: public void testSinglePercent2() throws Exception {
0680: insertChar("x = %q(^)", ')', "x = %q()^");
0681: }
0682:
0683: // Broken!!
0684: // I've gotta handle proper parenthesis nesting here... e.g.
0685: // %q(())
0686: // public void testSinglePercent3() throws Exception {
0687: // insertChar("x = %q(^)", '(', "x = %q((^))");
0688: // }
0689:
0690: // Broken!!
0691: // public void testSinglePercent4() throws Exception {
0692: // insertChar("x = %q((^))", ')', "x = %q(()^)");
0693: // }
0694:
0695: public void testSinglePercent5() throws Exception {
0696: insertChar("x = %q((^))", 'a', "x = %q((a^))");
0697: }
0698:
0699: public void testSinglePercent6() throws Exception {
0700: insertChar("x = %q^", '-', "x = %q-^-");
0701: }
0702:
0703: public void testSinglePercent7() throws Exception {
0704: insertChar("x = %q-^-", '-', "x = %q--^");
0705: }
0706:
0707: public void testSinglePercent8() throws Exception {
0708: insertChar("x = %q^", ' ', "x = %q ^ ");
0709: }
0710:
0711: // Broken!
0712: // public void testSinglePercent9() throws Exception {
0713: // insertChar("x = %q ^ ", ' ', "x = %q ^");
0714: // }
0715:
0716: public void testSinglePercent10() throws Exception {
0717: insertChar("x = %q ^ ", 'x', "x = %q x^ ");
0718: }
0719:
0720: public void testSinglePercent11() throws Exception {
0721: insertChar("x = %q-\\^-", '-', "x = %q-\\-^-");
0722: }
0723:
0724: public void testHeredoc1() throws Exception {
0725: insertBreak("x=<<FOO^\n", "x=<<FOO\n^\nFOO\n");
0726: }
0727:
0728: public void testHeredoc2() throws Exception {
0729: insertBreak("x=f(<<FOO,^\n", "x=f(<<FOO,\n^\nFOO\n");
0730: }
0731:
0732: public void testFindMatching1() throws Exception {
0733: match("^if true\n^end");
0734: }
0735:
0736: public void testFindMatching2() throws Exception {
0737: match("x=^(true^)\ny=5");
0738: }
0739:
0740: public void testFindMatching3() throws Exception {
0741: match("x=^(true || (false)^)\ny=5");
0742: }
0743:
0744: public void testFindMatching4() throws Exception {
0745: match("^def foo\nif true\nend\n^end\nend");
0746: }
0747:
0748: public void testFindMatching5() throws Exception {
0749: // Test heredocs
0750: match("x=f(^<<ABC,\"hello\")\nfoo\nbar\n^ABC\n");
0751: }
0752:
0753: public void testBackspace1() throws Exception {
0754: deleteChar("x^", "^");
0755: }
0756:
0757: public void testBackspace2() throws Exception {
0758: deleteChar("x^y", "^y");
0759: }
0760:
0761: public void testBackspace3() throws Exception {
0762: deleteChar("xy^z", "x^z");
0763: }
0764:
0765: public void testBackspace4() throws Exception {
0766: deleteChar("xy^z", "x^z");
0767: }
0768:
0769: public void testBackspace5() throws Exception {
0770: deleteChar("x=\"^\"", "x=^");
0771: }
0772:
0773: public void testBackspace6() throws Exception {
0774: deleteChar("x='^'", "x=^");
0775: }
0776:
0777: public void testBackspace7() throws Exception {
0778: deleteChar("x=(^)", "x=^");
0779: }
0780:
0781: public void testBackspace7b() throws Exception {
0782: deleteChar("x=[^]", "x=^");
0783: }
0784:
0785: public void testBackspace8() throws Exception {
0786: // See bug 111534
0787: deleteChar("x={^}", "x=^");
0788: }
0789:
0790: public void testBackspace9() throws Exception {
0791: deleteChar("x=/^/", "x=^");
0792: }
0793:
0794: public void testPercentBackspace() throws Exception {
0795: deleteChar("x=\"#{^}\"", "x=\"#^\"");
0796: }
0797:
0798: public void testPercentBackspace2() throws Exception {
0799: deleteChar("x=\"#{a^}\"", "x=\"#{^}\"");
0800: }
0801:
0802: public void testPercentBackspace3() throws Exception {
0803: deleteChar("x=\"a#{^}b\"", "x=\"a#^b\"");
0804: }
0805:
0806: public void testPercentBackspace4() throws Exception {
0807: deleteChar("x=/#{^}/", "x=/#^/");
0808: }
0809:
0810: public void testPercentBackspace5() throws Exception {
0811: deleteChar("x=/#{a^}/", "x=/#{^}/");
0812: }
0813:
0814: public void testPercentBackspace6() throws Exception {
0815: deleteChar("x=/a#{^}b/", "x=/a#^b/");
0816: }
0817:
0818: public void testContComment() throws Exception {
0819: if (BracketCompleter.CONTINUE_COMMENTS) {
0820: insertBreak("# ^", "# \n# ^");
0821: } else {
0822: insertBreak("# ^", "# \n^");
0823: }
0824: }
0825:
0826: public void testContComment2() throws Exception {
0827: // No auto-# on new lines
0828: if (BracketCompleter.CONTINUE_COMMENTS) {
0829: insertBreak(" # ^", " # \n # ^");
0830: } else {
0831: insertBreak(" # ^", " # \n ^");
0832: }
0833: }
0834:
0835: public void testContComment3() throws Exception {
0836: // No auto-# on new lines
0837: if (BracketCompleter.CONTINUE_COMMENTS) {
0838: insertBreak(" #\t^", " #\t\n #\t^");
0839: } else {
0840: insertBreak(" #\t^", " #\t\n ^");
0841: }
0842: }
0843:
0844: public void testContComment4() throws Exception {
0845: insertBreak("# foo\n^", "# foo\n\n^");
0846: }
0847:
0848: public void testContComment5() throws Exception {
0849: // No auto-# on new lines
0850: if (BracketCompleter.CONTINUE_COMMENTS) {
0851: insertBreak(" # ^", " # \n # ^");
0852: } else {
0853: insertBreak(" # ^", " # \n ^");
0854: }
0855: }
0856:
0857: public void testContComment6() throws Exception {
0858: insertBreak(" # foo^bar", " # foo\n # ^bar");
0859: }
0860:
0861: public void testContComment7() throws Exception {
0862: insertBreak(" # foo^\n # bar", " # foo\n # ^\n # bar");
0863: }
0864:
0865: public void testContComment8() throws Exception {
0866: insertBreak(" # foo^bar", " # foo\n # ^bar");
0867: }
0868:
0869: public void testContComment9() throws Exception {
0870: insertBreak("^# foobar", "\n^# foobar");
0871: }
0872:
0873: public void testContComment10() throws Exception {
0874: insertBreak("#foo\n^# foobar", "#foo\n# ^\n# foobar");
0875: }
0876:
0877: public void testContComment11() throws Exception {
0878: insertBreak("code #foo\n^# foobar", "code #foo\n\n^# foobar");
0879: }
0880:
0881: public void testContComment12() throws Exception {
0882: insertBreak(" code\n^# foobar", " code\n\n ^# foobar");
0883: }
0884:
0885: public void testContComment14() throws Exception {
0886: insertBreak("def foo\n code\n^# foobar\nend\n",
0887: "def foo\n code\n\n ^# foobar\nend\n");
0888: }
0889:
0890: public void testContComment15() throws Exception {
0891: insertBreak("\n\n^# foobar", "\n\n\n^# foobar");
0892: }
0893:
0894: public void testContComment16() throws Exception {
0895: insertBreak("\n \n^# foobar", "\n \n\n^# foobar");
0896: }
0897:
0898: public void testContComment17() throws Exception {
0899: insertBreak("def foo\n # cmnt1\n^ # cmnt2\nend\n",
0900: "def foo\n # cmnt1\n # ^\n # cmnt2\nend\n");
0901: }
0902:
0903: public void testNoContComment() throws Exception {
0904: // No auto-# on new lines
0905: insertBreak("foo # ^", "foo # \n^");
0906: }
0907:
0908: public void testDeleteContComment() throws Exception {
0909: deleteChar("# ^", "^");
0910: deleteChar("\n# ^", "\n^");
0911: }
0912:
0913: public void testDeleteContComment2() throws Exception {
0914: deleteChar("# ^ ", "^ ");
0915: deleteChar("\n# ^ ", "\n^ ");
0916: }
0917:
0918: public void testNoDeleteContComment() throws Exception {
0919: deleteChar("# ^", "# ^");
0920: deleteChar("#^", "^");
0921: deleteChar("puts '# ^'", "puts '#^'");
0922: }
0923:
0924: public void testFindMatching6() throws Exception {
0925: // Test heredocs
0926: match("x=f(^<<ABC,'hello',<<-DEF,'bye')\nfoo\nbar\n^ABC\nbaz\n DEF\nwhatever");
0927: }
0928:
0929: public void testFindMatching7() throws Exception {
0930: // Test heredocs
0931: match("x=f(<<ABC,'hello',^<<-DEF,'bye')\nfoo\nbar\nABC\nbaz\n ^DEF\nwhatever");
0932: }
0933:
0934: // public void testFreakOutEditor1() throws Exception {
0935: // String before = "x = method_call(50, <<TOKEN1, \"arg3\", <<TOKEN2, /startofregexp/^\nThis is part of the string\nTOKEN1\nrestofregexp/)";
0936: // String after = "x = method_call(50, <<TOKEN1, \"arg3\", <<TOKEN2, /startofregexp^\nThis is part of the string\nTOKEN1\nrestofregexp/)";
0937: // deleteChar(before, after);
0938: // }
0939: //
0940:
0941: public void testInsertPercentInString() throws Exception {
0942: insertChar("x = \"foo ^\"", '#', "x = \"foo #{^}\"");
0943: }
0944:
0945: public void testInsertPercentInString2() throws Exception {
0946: // Make sure type-through works
0947: insertChar("x = \"foo #{^}\"", '}', "x = \"foo #{}^\"");
0948: }
0949:
0950: public void testInsertPercentInString3() throws Exception {
0951: insertChar("x = \"foo #{^}\"", '{', "x = \"foo #{^}\"");
0952: }
0953:
0954: public void testInsertPercentInString4() throws Exception {
0955: insertChar("x = \"foo #{^a}\"", '}', "x = \"foo #{}^a}\"");
0956: }
0957:
0958: public void testInsertPercentInString5() throws Exception {
0959: insertChar("x = \"foo {^}\"", '}', "x = \"foo {}^}\"");
0960: }
0961:
0962: public void testInsertPercentInString6() throws Exception {
0963: insertChar("x = \"foo {^}\"", '{', "x = \"foo {{^}\"");
0964: }
0965:
0966: public void testNoInsertPercentInString() throws Exception {
0967: insertChar("x = 'foo ^'", '#', "x = 'foo #^'");
0968: }
0969:
0970: public void testNoInsertPercentElsewhere() throws Exception {
0971: insertChar("x = ^", '#', "x = #^");
0972: }
0973:
0974: public void testInsertPercentInRegexp() throws Exception {
0975: insertChar("x = /foo ^/", '#', "x = /foo #{^}/");
0976: }
0977:
0978: public void testInsertPercentInRegexp2() throws Exception {
0979: // Make sure type-through works
0980: insertChar("x = /foo #{^}/", '}', "x = /foo #{}^/");
0981: }
0982:
0983: public void testInsertPercentInRegexp3() throws Exception {
0984: insertChar("x = /foo #{^}/", '{', "x = /foo #{^}/");
0985: }
0986:
0987: public void testInsertPercentInRegexp4() throws Exception {
0988: insertChar("x = /foo #{^a}/", '}', "x = /foo #{}^a}/");
0989: }
0990:
0991: public void testInsertPercentInRegexp5() throws Exception {
0992: insertChar("x = /foo {^}/", '}', "x = /foo {}^}/");
0993: }
0994:
0995: public void testInsertPercentInRegexp6() throws Exception {
0996: insertChar("x = /foo {^}/", '{', "x = /foo {{^}/");
0997: }
0998:
0999: public void testReplaceSelection1() throws Exception {
1000: insertChar("x = foo^", 'y', "x = y^", "foo");
1001: }
1002:
1003: public void testReplaceSelection2() throws Exception {
1004: insertChar("x = foo^", '"', "x = \"foo\"^", "foo");
1005: }
1006:
1007: public void testReplaceSelection3() throws Exception {
1008: insertChar("x = \"foo^bar\"", '#', "x = \"#{foo}^bar\"", "foo");
1009: }
1010:
1011: public void testReplaceSelection4() throws Exception {
1012: insertChar("x = 'foo^bar'", '#', "x = '#^bar'", "foo");
1013: }
1014:
1015: public void testReplaceSelection5() throws Exception {
1016: insertChar("'(^position:absolute;'", '{',
1017: "'{^position:absolute;'", "(");
1018: }
1019:
1020: public void testReplaceSelection6() throws Exception {
1021: insertChar("'position^:absolute;'", '{', "'pos{^:absolute;'",
1022: "ition");
1023: }
1024:
1025: public void testReplaceSelectionChangeType1() throws Exception {
1026: insertChar("x = \"foo\"^", '\'', "x = 'foo'^", "\"foo\"");
1027: }
1028:
1029: public void testReplaceSelectionChangeType2() throws Exception {
1030: insertChar("x = \"foo\"^", '{', "x = {foo}^", "\"foo\"");
1031: }
1032:
1033: public void testReplaceSelectionNotInTemplateMode1()
1034: throws Exception {
1035: insertChar("x = foo^", '"', "x = \"^\"", "foo", true);
1036: }
1037:
1038: // Functionality works but test is broken
1039: //public void testReplaceSelectionNotInTemplateMode2() throws Exception {
1040: // insertChar("x = \"foo^bar\"", '#', "x = \"#{^}bar\"", "foo", true);
1041: //}
1042:
1043: public void testReplaceCommentSelectionBold() throws Exception {
1044: insertChar("# foo^", '*', "# *foo*^", "foo");
1045: }
1046:
1047: public void testReplaceCommentSelectionTerminal() throws Exception {
1048: insertChar("# foo^", '+', "# +foo+^", "foo");
1049: }
1050:
1051: public void testReplaceCommentSelectionItalic() throws Exception {
1052: insertChar("# foo^", '_', "# _foo_^", "foo");
1053: }
1054:
1055: public void testReplaceCommentSelectionWords() throws Exception {
1056: // No replacement if it contains multiple lines
1057: insertChar("# foo bar^", '*', "# *^", "foo bar");
1058: }
1059:
1060: public void testReplaceCommentOther() throws Exception {
1061: // No replacement if it's not one of the three chars
1062: insertChar("# foo^", 'x', "# x^", "foo");
1063: }
1064:
1065: public void testdeleteWord() throws Exception {
1066: deleteWord("foo_bar_baz^", "foo_bar_^");
1067: }
1068:
1069: public void testdeleteWord111303() throws Exception {
1070: deleteWord("foo::bar^", "foo::^");
1071: deleteWord("Foo::Bar^", "Foo::^");
1072: deleteWord("Foo::Bar_Baz^", "Foo::Bar_^");
1073: }
1074:
1075: public void testdeleteWordx111305() throws Exception {
1076: deleteWord("foo_bar^", "foo_^");
1077: deleteWord("x.foo_bar^.y", "x.foo_^.y");
1078: }
1079:
1080: public void testdeleteWord2() throws Exception {
1081: deleteWord("foo_bar_baz ^", "foo_bar_baz^");
1082: deleteWord("foo_bar_^", "foo_^");
1083: }
1084:
1085: public void testdeleteWord3() throws Exception {
1086: deleteWord("FooBarBaz^", "FooBar^");
1087: }
1088:
1089: public void testDeleteWord4_110998() throws Exception {
1090: deleteWord("Blah::Set^Foo", "Blah::^Foo");
1091: }
1092:
1093: public void testdeleteWord5() throws Exception {
1094: deleteWord("foo_bar_^", "foo_^");
1095: }
1096:
1097: public void testdeleteWords() throws Exception {
1098: deleteWord("foo bar^", "foo ^");
1099: }
1100:
1101: public void testDeleteWord4_110998c() throws Exception {
1102: String before = " snark^\n";
1103: String after = " ^\n";
1104: deleteWord(before, after);
1105: }
1106:
1107: public void testDeleteWord4_110998b() throws Exception {
1108: String before = "" + " snark(%w(a b c))\n"
1109: + " snark(%W(a b c))\n" + " snark^\n"
1110: + " snark(%Q(a b c))\n" + " snark(%w(a b c))\n";
1111: String after = "" + " snark(%w(a b c))\n"
1112: + " snark(%W(a b c))\n" + " ^\n"
1113: + " snark(%Q(a b c))\n" + " snark(%w(a b c))\n";
1114: deleteWord(before, after);
1115: }
1116:
1117: public void testBackwardsDeletion() throws Exception {
1118: String s = "Foo::Bar = whatever('hello') \n nextline";
1119: BracketCompleter bc = new BracketCompleter();
1120: for (int i = s.length(); i >= 1; i--) {
1121: String shortened = s.substring(0, i);
1122: BaseDocument doc = getDocument(shortened);
1123:
1124: JTextArea ta = new JTextArea(doc);
1125: Caret caret = ta.getCaret();
1126: int dot = i;
1127: caret.setDot(dot);
1128: int begin = bc.getNextWordOffset(doc, dot, true);
1129: if (begin == -1) {
1130: begin = Utilities.getPreviousWord(ta, dot);
1131: }
1132:
1133: assert begin != -1 && begin < i;
1134: }
1135: }
1136:
1137: public void test108889() throws Exception {
1138: // Reproduce 108889: AIOOBE and AE during editing
1139: // NOTE: While the test currently throws an exception, when the
1140: // exception is fixed the test won't actually pass; that's an expected
1141: // fail I will deal with later
1142: insertChar("x = %q((^))", 'a', "x = %q((a^))");
1143: }
1144:
1145: public void test110332() throws Exception {
1146: String before = "args = {\n"
1147: + " :name => args[:name],\n"
1148: + " :status => :missing,\n"
1149: + " :s2_test_comments => comments, \n"
1150: + " :metric => '', \n"
1151: + " :duration => '', \n"
1152: + " :setback? => true,\n"
1153: + " :progress? => false, :compare_metric => 0, ^:compare_duration => 0}\n"
1154: + " OpenStruct.new\n" + "";
1155: String after = "args = {\n"
1156: + " :name => args[:name],\n"
1157: + " :status => :missing,\n"
1158: + " :s2_test_comments => comments, \n"
1159: + " :metric => '', \n"
1160: + " :duration => '', \n"
1161: + " :setback? => true,\n"
1162: + " :progress? => false, :compare_metric => 0, \n ^:compare_duration => 0}\n"
1163: + " OpenStruct.new\n" + "";
1164: insertBreak(before, after);
1165: }
1166:
1167: public void test110332b() throws Exception {
1168: String before = "args = {\n"
1169: + " :name => args[:name],\n"
1170: + " :status => :missing,\n"
1171: + " :s2_test_comments => comments, \n"
1172: + " :metric => '', \n"
1173: + " :duration => '', \n"
1174: + " :setback? => true,\n"
1175: + " :progress? => false, :compare_metric => 0,^ :compare_duration => 0}\n"
1176: + " OpenStruct.new\n" + "";
1177: String after = "args = {\n"
1178: + " :name => args[:name],\n"
1179: + " :status => :missing,\n"
1180: + " :s2_test_comments => comments, \n"
1181: + " :metric => '', \n"
1182: + " :duration => '', \n"
1183: + " :setback? => true,\n"
1184: + " :progress? => false, :compare_metric => 0,\n ^:compare_duration => 0}\n"
1185: + " OpenStruct.new\n" + "";
1186: insertBreak(before, after);
1187: }
1188:
1189: public void testLogicalRange1() throws Exception {
1190: String code = "if (true)\n fo^o\nend";
1191: String next = "if (true)\n %<%fo^o%>%\nend";
1192: assertLogicalRange(code, true, next);
1193: assertLogicalRange(next, false, code);
1194: }
1195:
1196: public void testLogicalRange2() throws Exception {
1197: String code = "if (true)\n %<%fo^o%>%\nend";
1198: String next = "%<%if (true)\n fo^o\nend%>%";
1199: assertLogicalRange(code, true, next);
1200: assertLogicalRange(next, false, code);
1201: }
1202:
1203: public void testLogicalRange3() throws Exception {
1204: String code = "def foo\nif (true)\n %<%fo^o%>%\nend\nend";
1205: String next = "def foo\n%<%if (true)\n fo^o\nend%>%\nend";
1206: assertLogicalRange(code, true, next);
1207: assertLogicalRange(next, false, code);
1208: }
1209:
1210: public void testLogicalRange4() throws Exception {
1211: String code = "class Foo\ndef foo\nif (true)\n %<%fo^o%>%\nend\nend\nend";
1212: String next = "class Foo\ndef foo\n%<%if (true)\n fo^o\nend%>%\nend\nend";
1213: assertLogicalRange(code, true, next);
1214: assertLogicalRange(next, false, code);
1215: }
1216:
1217: public void testLogicalRange5() throws Exception {
1218: String code = "class Foo\ndef foo\n%<%if (true)\n fo^o\nend%>%\nend\nend";
1219: String next = "class Foo\n%<%def foo\nif (true)\n fo^o\nend\nend%>%\nend";
1220: assertLogicalRange(code, true, next);
1221: assertLogicalRange(next, false, code);
1222: }
1223:
1224: public void testLogicalRange6() throws Exception {
1225: String code = "class Foo\n%<%def fo^o\nif (true)\n foo\nend\nend%>%\nend";
1226: String next = "%<%class Foo\ndef fo^o\nif (true)\n foo\nend\nend\nend%>%";
1227: assertLogicalRange(code, true, next);
1228: assertLogicalRange(next, false, code);
1229: }
1230:
1231: public void testLogicalRangeComment1() throws Exception {
1232: String code = "foo\n # Foo Bar\n # Foo^y Baary\n # Bye\ndef foo\nend\n";
1233: String next = "foo\n # Foo Bar\n %<%# Foo^y Baary%>%\n # Bye\ndef foo\nend\n";
1234: assertLogicalRange(code, true, next);
1235: assertLogicalRange(next, false, code);
1236: }
1237:
1238: public void testLogicalRangeComment2() throws Exception {
1239: String code = "foo\n # Foo Bar\n %<%# Foo^y Baary%>%\n # Bye\ndef foo\nend\n";
1240: String next = "foo\n %<%# Foo Bar\n # Foo^y Baary\n # Bye%>%\ndef foo\nend\n";
1241: assertLogicalRange(code, true, next);
1242: assertLogicalRange(next, false, code);
1243: }
1244:
1245: public void testLogicalRangeComment3() throws Exception {
1246: String code = "foo\n # Foo Bar\n\n %<%# Foo^y Baary%>%\n # Bye\ndef foo\nend\n";
1247: String next = "foo\n # Foo Bar\n\n %<%# Foo^y Baary\n # Bye%>%\ndef foo\nend\n";
1248: assertLogicalRange(code, true, next);
1249: assertLogicalRange(next, false, code);
1250: }
1251:
1252: public void testLogicalRangeComment5() throws Exception {
1253: String code = "foo\n foo # Foo Bar\n %<%# Foo^y Baary%>%\n # Bye\ndef foo\nend\n";
1254: String next = "foo\n foo # Foo Bar\n %<%# Foo^y Baary\n # Bye%>%\ndef foo\nend\n";
1255: assertLogicalRange(code, true, next);
1256: assertLogicalRange(next, false, code);
1257: }
1258:
1259: public void testLogicalRangeStrings1() throws Exception {
1260: String code = "x = 'foo b^ar baz', y = \"whatever\"";
1261: String next = "x = %<%'foo b^ar baz'%>%, y = \"whatever\"";
1262: assertLogicalRange(code, true, next);
1263: assertLogicalRange(next, false, code);
1264: }
1265:
1266: public void testLogicalRangeStrings2() throws Exception {
1267: String code = "x = %q-foo b^ar baz-, y = \"whatever\"";
1268: String next = "x = %<%%q-foo b^ar baz-%>%, y = \"whatever\"";
1269: assertLogicalRange(code, true, next);
1270: assertLogicalRange(next, false, code);
1271: }
1272:
1273: public void testLogicalRangeStrings3() throws Exception {
1274: String code = "def foo\nif (true)\nx = %<%'foo b^ar baz'%>%\nend\nend";
1275: String next = "def foo\nif (true)\n%<%x = 'foo b^ar baz'%>%\nend\nend";
1276: assertLogicalRange(code, true, next);
1277: assertLogicalRange(next, false, code);
1278: }
1279:
1280: public void testLogicalRangeStrings4() throws Exception {
1281: String code = "def foo\nif (true)\n%<%x = 'foo b^ar baz'%>%\nend\nend";
1282: String next = "def foo\n%<%if (true)\nx = 'foo b^ar baz'\nend%>%\nend";
1283: assertLogicalRange(code, true, next);
1284: assertLogicalRange(next, false, code);
1285: }
1286:
1287: public void testLogicalRangeStrings5() throws Exception {
1288: String code = "def test\n 'return^ me'\nend";
1289: String next = "def test\n %<%'return^ me'%>%\nend";
1290: assertLogicalRange(code, true, next);
1291: assertLogicalRange(next, false, code);
1292: }
1293:
1294: public void testLogicalRangeStrings6() throws Exception {
1295: String code = "def test\n %<%'return^ me'%>%\nend";
1296: String next = "%<%def test\n 'return^ me'\nend%>%";
1297: assertLogicalRange(code, true, next);
1298: assertLogicalRange(next, false, code);
1299: }
1300:
1301: public void testLogicalRangeRegexps1() throws Exception {
1302: String code = "x = /foo b^ar baz/, y = \"whatever\"";
1303: // Uhm - is it good that we're selecting the -inside- of the regexp?
1304: String next = "x = /%<%foo b^ar baz%>%/, y = \"whatever\"";
1305: assertLogicalRange(code, true, next);
1306: assertLogicalRange(next, false, code);
1307: }
1308:
1309: public void testPipes1() throws Exception {
1310: insertChar("5.each { ^", '|', "5.each { |^|");
1311: }
1312:
1313: public void testPipes2() throws Exception {
1314: insertChar("5.each { ^}", '|', "5.each { |^|}");
1315: }
1316:
1317: public void testPipes3() throws Exception {
1318: insertChar("5.each { |^|}", '|', "5.each { ||^}");
1319: }
1320:
1321: public void testPipes4() throws Exception {
1322: insertChar("5.each { |foo^|}", '|', "5.each { |foo|^}");
1323: }
1324:
1325: public void testNegativePipes1() throws Exception {
1326: insertChar("'^'", '|', "'|^'");
1327: }
1328:
1329: public void testNegativePipes2() throws Exception {
1330: insertChar("/^/", '|', "/|^/");
1331: }
1332:
1333: public void testNegativePipes3() throws Exception {
1334: insertChar("#^", '|', "#|^");
1335: }
1336:
1337: public void testNegativePipes4() throws Exception {
1338: insertChar("\"^\"", '|', "\"|^\"");
1339: }
1340:
1341: public void testNegativePipes5() throws Exception {
1342: insertChar("5.each { |f^oo|}", '|', "5.each { |f|^oo|}");
1343: }
1344:
1345: public void testNegativePipes6() throws Exception {
1346: insertChar("5.each { |^|foo|}", '|', "5.each { ||^foo|}");
1347: }
1348:
1349: public void testNegativePipes7() throws Exception {
1350: insertChar("x = true ^", '|', "x = true |^");
1351: }
1352:
1353: public void testNegativePipes8() throws Exception {
1354: insertChar("x = true |^", '|', "x = true ||^");
1355: }
1356:
1357: public void testBackspacePipes() throws Exception {
1358: deleteChar("x=|^|", "x=^");
1359: }
1360:
1361: public void testBackspacePipes2() throws Exception {
1362: deleteChar("x=|^x", "x=^x");
1363: }
1364:
1365: public void testBackspacePipes3() throws Exception {
1366: deleteChar("x=|^", "x=^");
1367: }
1368: }
|