001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * Portions Copyrighted 2007 Sun Microsystems, Inc.
027: */
028:
029: package org.netbeans.modules.cnd.editor.cplusplus;
030:
031: import javax.swing.text.BadLocationException;
032: import org.netbeans.editor.Formatter;
033: import org.netbeans.editor.TokenID;
034: import org.netbeans.modules.cnd.editor.api.CodeStyle;
035: import org.netbeans.modules.cnd.editor.options.EditorOptions;
036:
037: /**
038: * Class was taken from java
039: * Links point to java IZ.
040: * C/C++ specific tests begin from testSystemInclude
041: * @author Alexander Simon
042: */
043: public class CCBracketCompletionUnitTestCase extends
044: CCFormatterBaseUnitTestCase {
045:
046: public CCBracketCompletionUnitTestCase(String testMethodName) {
047: super (testMethodName);
048: }
049:
050: // ------- Tests for completion of right parenthesis ')' -------------
051:
052: public void testRightParenSimpleMethodCall() {
053: setLoadDocumentText("m()|)");
054: assertTrue(isSkipRightParen());
055: }
056:
057: public void testRightParenSwingInvokeLaterRunnable() {
058: setLoadDocumentText("SwingUtilities.invokeLater(new Runnable()|))");
059: assertTrue(isSkipRightParen());
060: }
061:
062: public void testRightParenSwingInvokeLaterRunnableRun() {
063: setLoadDocumentText("SwingUtilities.invokeLater(new Runnable() {\n"
064: + " public void run()|)\n" + "})"
065:
066: );
067: assertTrue(isSkipRightParen());
068: }
069:
070: public void testRightParenIfMethodCall() {
071: setLoadDocumentText(" if (a()|) + 5 > 6) {\n" + " }");
072: assertTrue(isSkipRightParen());
073: }
074:
075: public void testRightParenNoSkipNonBracketChar() {
076: setLoadDocumentText("m()| ");
077: assertFalse(isSkipRightParen());
078: }
079:
080: public void testRightParenNoSkipDocEnd() {
081: setLoadDocumentText("m()|");
082: assertFalse(isSkipRightParen());
083: }
084:
085: // ------- Tests for completion of right brace '}' -------------
086:
087: public void testAddRightBraceIfLeftBrace() {
088: setLoadDocumentText("if (true) {|");
089: assertTrue(isAddRightBrace());
090: }
091:
092: public void testAddRightBraceIfLeftBraceWhiteSpace() {
093: setLoadDocumentText("if (true) { \t|\n");
094: assertTrue(isAddRightBrace());
095: }
096:
097: public void testAddRightBraceIfLeftBraceLineComment() {
098: setLoadDocumentText("if (true) { // line-comment|\n");
099: assertTrue(isAddRightBrace());
100: }
101:
102: public void testAddRightBraceIfLeftBraceBlockComment() {
103: setLoadDocumentText("if (true) { /* block-comment */|\n");
104: assertTrue(isAddRightBrace());
105: }
106:
107: public void testAddRightBraceIfLeftBraceAlreadyPresent() {
108: setLoadDocumentText("if (true) {|\n" + "}");
109: assertFalse(isAddRightBrace());
110: }
111:
112: public void testAddRightBraceCaretInComment() {
113: setLoadDocumentText("if (true) { /* in-block-comment |\n");
114: assertFalse(isAddRightBrace());
115: }
116:
117: public void testSimpleAdditionOfOpeningParenthesisAfterWhile()
118: throws Exception {
119: setLoadDocumentText("while |");
120: typeChar('(', false);
121: assertDocumentTextAndCaret(
122: "Even a closing ')' should be added", "while (|)");
123: }
124:
125: // ------- Tests for completion of quote (") -------------
126: public void testSimpleQuoteInEmptyDoc() throws Exception {
127: setLoadDocumentText("|");
128: typeQuoteChar('"');
129: assertDocumentTextAndCaret("Simple Quote In Empty Doc", "\"|\"");
130: }
131:
132: public void testSimpleQuoteAtBeginingOfDoc() throws Exception {
133: setLoadDocumentText("| ");
134: typeQuoteChar('"');
135: assertDocumentTextAndCaret("Simple Quote At Begining Of Doc",
136: "\"|\" ");
137: }
138:
139: public void testSimpleQuoteAtEndOfDoc() throws Exception {
140: setLoadDocumentText(" |");
141: typeQuoteChar('"');
142: assertDocumentTextAndCaret("Simple Quote At End Of Doc",
143: " \"|\"");
144: }
145:
146: public void testSimpleQuoteInWhiteSpaceArea() throws Exception {
147: setLoadDocumentText(" | ");
148: typeQuoteChar('"');
149: assertDocumentTextAndCaret("Simple Quote In White Space Area",
150: " \"|\" ");
151: }
152:
153: public void testQuoteAtEOL() throws Exception {
154: setLoadDocumentText(" |\n");
155: typeQuoteChar('"');
156: assertDocumentTextAndCaret("Quote At EOL", " \"|\"\n");
157: }
158:
159: public void testQuoteWithUnterminatedStringLiteral()
160: throws Exception {
161: setLoadDocumentText(" \"unterminated string| \n");
162: typeQuoteChar('"');
163: assertDocumentTextAndCaret(
164: "Quote With Unterminated String Literal",
165: " \"unterminated string\"| \n");
166: }
167:
168: public void testQuoteAtEOLWithUnterminatedStringLiteral()
169: throws Exception {
170: setLoadDocumentText(" \"unterminated string |\n");
171: typeQuoteChar('"');
172: assertDocumentTextAndCaret(
173: "Quote At EOL With Unterminated String Literal",
174: " \"unterminated string \"|\n");
175: }
176:
177: public void testQuoteInsideStringLiteral() throws Exception {
178: setLoadDocumentText(" \"stri|ng literal\" ");
179: typeQuoteChar('"');
180: assertDocumentTextAndCaret("Quote Inside String Literal",
181: " \"stri\"|ng literal\" ");
182: }
183:
184: public void testQuoteInsideEmptyParentheses() throws Exception {
185: setLoadDocumentText(" printf(|) ");
186: typeQuoteChar('"');
187: assertDocumentTextAndCaret("Quote Inside Empty Parentheses",
188: " printf(\"|\") ");
189: }
190:
191: public void testQuoteInsideNonEmptyParentheses() throws Exception {
192: setLoadDocumentText(" printf(|some text) ");
193: typeQuoteChar('"');
194: assertDocumentTextAndCaret(
195: "Quote Inside Non Empty Parentheses",
196: " printf(\"|some text) ");
197: }
198:
199: public void testQuoteInsideNonEmptyParenthesesBeforeClosingParentheses()
200: throws Exception {
201: setLoadDocumentText(" printf(i+|) ");
202: typeQuoteChar('"');
203: assertDocumentTextAndCaret(
204: "Quote Inside Non Empty Parentheses Before Closing Parentheses",
205: " printf(i+\"|\") ");
206: }
207:
208: public void testQuoteInsideNonEmptyParenthesesBeforeClosingParenthesesAndUnterminatedStringLiteral()
209: throws Exception {
210: setLoadDocumentText(" printf(\"unterminated string literal |); ");
211: typeQuoteChar('"');
212: assertDocumentTextAndCaret(
213: "Quote Inside Non Empty Parentheses Before Closing Parentheses And Unterminated String Literal",
214: " printf(\"unterminated string literal \"|); ");
215: }
216:
217: public void testQuoteBeforePlus() throws Exception {
218: setLoadDocumentText(" printf(|+\"string literal\"); ");
219: typeQuoteChar('"');
220: assertDocumentTextAndCaret("Quote Before Plus",
221: " printf(\"|\"+\"string literal\"); ");
222: }
223:
224: public void testQuoteBeforeComma() throws Exception {
225: setLoadDocumentText("String s[] = new String[]{|,\"two\"};");
226: typeQuoteChar('"');
227: assertDocumentTextAndCaret("Quote Before Comma",
228: "String s[] = new String[]{\"|\",\"two\"};");
229: }
230:
231: public void testQuoteBeforeBrace() throws Exception {
232: setLoadDocumentText("String s[] = new String[]{\"one\",|};");
233: typeQuoteChar('"');
234: assertDocumentTextAndCaret("Quote Before Brace",
235: "String s[] = new String[]{\"one\",\"|\"};");
236: }
237:
238: public void testQuoteBeforeSemicolon() throws Exception {
239: setLoadDocumentText("String s = \"\" + |;");
240: typeQuoteChar('"');
241: assertDocumentTextAndCaret("Quote Before Semicolon",
242: "String s = \"\" + \"|\";");
243: }
244:
245: public void testQuoteBeforeSemicolonWithWhitespace()
246: throws Exception {
247: setLoadDocumentText("String s = \"\" +| ;");
248: typeQuoteChar('"');
249: assertDocumentTextAndCaret(
250: "Quote Before Semicolon With Whitespace",
251: "String s = \"\" +\"|\" ;");
252: }
253:
254: public void testQuoteAfterEscapeSequence() throws Exception {
255: setLoadDocumentText("\\|");
256: typeQuoteChar('"');
257: assertDocumentTextAndCaret(
258: "Quote Before Semicolon With Whitespace", "\\\"|");
259: }
260:
261: /** issue #69524 */
262: public void testQuoteEaten() throws Exception {
263: setLoadDocumentText("|");
264: typeQuoteChar('"');
265: typeQuoteChar('"');
266: assertDocumentTextAndCaret("Quote Eaten", "\"\"|");
267: }
268:
269: /** issue #69935 */
270: public void testQuoteInsideComments() throws Exception {
271: setLoadDocumentText("/** |\n */");
272: typeQuoteChar('"');
273: assertDocumentTextAndCaret("Quote Inside Comments",
274: "/** \"|\n */");
275: }
276:
277: /** issue #71880 */
278: public void testQuoteAtTheEndOfLineCommentLine() throws Exception {
279: setLoadDocumentText("// test line comment |\n");
280: typeQuoteChar('"');
281: assertDocumentTextAndCaret(
282: "Quote At The End Of Line Comment Line",
283: "// test line comment \"|\n");
284: }
285:
286: // ------- Tests for completion of single quote (') -------------
287:
288: public void testSingleQuoteInEmptyDoc() throws Exception {
289: setLoadDocumentText("|");
290: typeQuoteChar('\'');
291: assertDocumentTextAndCaret("Single Quote In Empty Doc", "'|'");
292: }
293:
294: public void testSingleQuoteAtBeginingOfDoc() throws Exception {
295: setLoadDocumentText("| ");
296: typeQuoteChar('\'');
297: assertDocumentTextAndCaret("Single Quote At Begining Of Doc",
298: "'|' ");
299: }
300:
301: public void testSingleQuoteAtEndOfDoc() throws Exception {
302: setLoadDocumentText(" |");
303: typeQuoteChar('\'');
304: assertDocumentTextAndCaret("Single Quote At End Of Doc",
305: " '|'");
306: }
307:
308: public void testSingleQuoteInWhiteSpaceArea() throws Exception {
309: setLoadDocumentText(" | ");
310: typeQuoteChar('\'');
311: assertDocumentTextAndCaret("Single Quote In White Space Area",
312: " '|' ");
313: }
314:
315: public void testSingleQuoteAtEOL() throws Exception {
316: setLoadDocumentText(" |\n");
317: typeQuoteChar('\'');
318: assertDocumentTextAndCaret("Single Quote At EOL", " '|'\n");
319: }
320:
321: public void testSingleQuoteWithUnterminatedCharLiteral()
322: throws Exception {
323: setLoadDocumentText(" '| \n");
324: typeQuoteChar('\'');
325: assertDocumentTextAndCaret(
326: "Single Quote With Unterminated Char Literal",
327: " ''| \n");
328: }
329:
330: public void testSingleQuoteAtEOLWithUnterminatedCharLiteral()
331: throws Exception {
332: setLoadDocumentText(" ' |\n");
333: typeQuoteChar('\'');
334: assertDocumentTextAndCaret(
335: "Single Quote At EOL With Unterminated Char Literal",
336: " ' '|\n");
337: }
338:
339: public void testSingleQuoteInsideCharLiteral() throws Exception {
340: setLoadDocumentText(" '| ' ");
341: typeQuoteChar('\'');
342: assertDocumentTextAndCaret("Single Quote Inside Char Literal",
343: " ''| ' ");
344: }
345:
346: public void testSingleQuoteInsideEmptyParentheses()
347: throws Exception {
348: setLoadDocumentText(" printf(|) ");
349: typeQuoteChar('\'');
350: assertDocumentTextAndCaret(
351: "Single Quote Inside Empty Parentheses",
352: " printf('|') ");
353: }
354:
355: public void testSingleQuoteInsideNonEmptyParentheses()
356: throws Exception {
357: setLoadDocumentText(" printf(|some text) ");
358: typeQuoteChar('\'');
359: assertDocumentTextAndCaret(
360: "Single Quote Inside Non Empty Parentheses",
361: " printf('|some text) ");
362: }
363:
364: public void testSingleQuoteInsideNonEmptyParenthesesBeforeClosingParentheses()
365: throws Exception {
366: setLoadDocumentText(" printf(i+|) ");
367: typeQuoteChar('\'');
368: assertDocumentTextAndCaret(
369: "Single Quote Inside Non Empty Parentheses Before Closing Parentheses",
370: " printf(i+'|') ");
371: }
372:
373: public void testSingleQuoteInsideNonEmptyParenthesesBeforeClosingParenthesesAndUnterminatedCharLiteral()
374: throws Exception {
375: setLoadDocumentText(" printf(' |); ");
376: typeQuoteChar('\'');
377: assertDocumentTextAndCaret(
378: "Single Quote Inside Non Empty Parentheses Before Closing Parentheses And Unterminated Char Literal",
379: " printf(' '|); ");
380: }
381:
382: public void testSingleQuoteBeforePlus() throws Exception {
383: setLoadDocumentText(" printf(|+\"string literal\"); ");
384: typeQuoteChar('\'');
385: assertDocumentTextAndCaret("Single Quote Before Plus",
386: " printf('|'+\"string literal\"); ");
387: }
388:
389: public void testSingleQuoteBeforeComma() throws Exception {
390: setLoadDocumentText("String s[] = new String[]{|,\"two\"};");
391: typeQuoteChar('\'');
392: assertDocumentTextAndCaret("Single Quote Before Comma",
393: "String s[] = new String[]{'|',\"two\"};");
394: }
395:
396: public void testSingleQuoteBeforeBrace() throws Exception {
397: setLoadDocumentText("String s[] = new String[]{\"one\",|};");
398: typeQuoteChar('\'');
399: assertDocumentTextAndCaret("Single Quote Before Brace",
400: "String s[] = new String[]{\"one\",'|'};");
401: }
402:
403: public void testSingleQuoteBeforeSemicolon() throws Exception {
404: setLoadDocumentText("String s = \"\" + |;");
405: typeQuoteChar('\'');
406: assertDocumentTextAndCaret("Single Quote Before Semicolon",
407: "String s = \"\" + '|';");
408: }
409:
410: public void testsingleQuoteBeforeSemicolonWithWhitespace()
411: throws Exception {
412: setLoadDocumentText("String s = \"\" +| ;");
413: typeQuoteChar('\'');
414: assertDocumentTextAndCaret(
415: "Single Quote Before Semicolon With Whitespace",
416: "String s = \"\" +'|' ;");
417: }
418:
419: public void testSingleQuoteAfterEscapeSequence() throws Exception {
420: setLoadDocumentText("\\|");
421: typeQuoteChar('\'');
422: assertDocumentTextAndCaret(
423: "Single Quote Before Semicolon With Whitespace", "\\'|");
424: }
425:
426: /** issue #69524 */
427: public void testSingleQuoteEaten() throws Exception {
428: setLoadDocumentText("|");
429: typeQuoteChar('\'');
430: typeQuoteChar('\'');
431: assertDocumentTextAndCaret("Single Quote Eaten", "''|");
432: }
433:
434: /** issue #69935 */
435: public void testSingleQuoteInsideComments() throws Exception {
436: setLoadDocumentText("/* |\n */");
437: typeQuoteChar('\'');
438: assertDocumentTextAndCaret("Single Quote Inside Comments",
439: "/* \'|\n */");
440: }
441:
442: /** issue #71880 */
443: public void testSingleQuoteAtTheEndOfLineCommentLine()
444: throws Exception {
445: setLoadDocumentText("// test line comment |\n");
446: typeQuoteChar('\'');
447: assertDocumentTextAndCaret(
448: "Single Quote At The End Of Line Comment Line",
449: "// test line comment \'|\n");
450: }
451:
452: public void testSystemInclude() throws Exception {
453: setLoadDocumentText("#include |\n");
454: typeQuoteChar('<');
455: assertDocumentTextAndCaret("System Include", "#include <|>\n");
456: }
457:
458: public void testUserInclude() throws Exception {
459: setLoadDocumentText("#include |\n");
460: typeQuoteChar('"');
461: assertDocumentTextAndCaret("User Include", "#include \"|\"\n");
462: }
463:
464: public void testArray() throws Exception {
465: setLoadDocumentText("int a|\n");
466: typeQuoteChar('[');
467: assertDocumentTextAndCaret("Array", "int a[|]\n");
468: }
469:
470: public void testRightBracePreprocessor() {
471: setLoadDocumentText("void foo(){\n" + "#if A\n"
472: + " if (a){\n" + "#else\n" + " if (b){|\n"
473: + "#endif\n" + " }\n" + "}");
474: assertFalse(isAddRightBrace());
475: }
476:
477: public void testRightBracePreprocessor2() {
478: setLoadDocumentText("void foo(){\n" + "#if A\n"
479: + " if (a){|\n" + "#else\n" + " if (b){\n"
480: + "#endif\n" + " }\n" + "}");
481: assertFalse(isAddRightBrace());
482: }
483:
484: public void testRightBracePreprocessor3() {
485: setLoadDocumentText("void foo(){\n" + "#if A\n"
486: + " if (a){|\n" + "#else\n" + " if (b){\n"
487: + "#endif\n" + "// }\n" + "}");
488: assertTrue(isAddRightBrace());
489: }
490:
491: public void testRightBracePreprocessor4() {
492: setLoadDocumentText("void foo(){\n" + "#if A\n"
493: + " if (a){\n" + "#else\n" + " if (b){\n"
494: + "#endif\n" + " if (b){|\n" + " }\n" + "}");
495: assertTrue(isAddRightBrace());
496: }
497:
498: public void testRightBracePreprocessor5() {
499: setLoadDocumentText("void foo(){\n" + "#define PAREN {\n"
500: + " if (b){|\n" + " }\n" + "}");
501: assertFalse(isAddRightBrace());
502: }
503:
504: public void testIZ102091() throws Exception {
505: EditorOptions.getPreferences(
506: CodeStyle.getDefault(CodeStyle.Language.CPP)).put(
507: EditorOptions.newLineBeforeBrace,
508: CodeStyle.BracePlacement.NEW_LINE.name());
509: try {
510: setLoadDocumentText("if(i)\n" + " |");
511: typeChar('{', true);
512: assertDocumentTextAndCaret("IZ102091\n", "if(i)\n" + "{|");
513: } finally {
514: EditorOptions.getPreferences(
515: CodeStyle.getDefault(CodeStyle.Language.CPP)).put(
516: EditorOptions.newLineBeforeBrace,
517: CodeStyle.BracePlacement.SAME_LINE.name());
518: }
519: }
520:
521: // public void testColonAfterPublic() throws Exception {
522: // setLoadDocumentText (
523: // "class A{\n" +
524: // " public|\n" +
525: // "}\n"
526: // );
527: // typeChar(':');
528: // assertDocumentTextAndCaret ("Colon After Public",
529: // "class A{\n" +
530: // "public:|\n" +
531: // "}\n"
532: // );
533: // }
534:
535: // ------- Private methods -------------
536:
537: private void typeChar(char ch, boolean isIndent) throws Exception {
538: int pos = getCaretOffset();
539: getDocument().insertString(pos, String.valueOf(ch), null);
540: BracketCompletion.charInserted(getDocument(), pos, getCaret(),
541: ch);
542: if (isIndent) {
543: Formatter f = getDocument().getFormatter();
544: f.indentLock();
545: try {
546: getDocument().getFormatter().indentLine(getDocument(),
547: pos);
548: } finally {
549: f.indentUnlock();
550: }
551: }
552: }
553:
554: private void typeQuoteChar(char ch) throws Exception {
555: typeChar(ch, false);
556: }
557:
558: private boolean isSkipRightParen() {
559: return isSkipRightBracketOrParen(true);
560: }
561:
562: private boolean isSkipRightBracket() {
563: return isSkipRightBracketOrParen(false);
564: }
565:
566: private boolean isSkipRightBracketOrParen(boolean parenthesis) {
567: TokenID bracketTokenId = parenthesis ? CCTokenContext.RPAREN
568: : CCTokenContext.RBRACKET;
569:
570: try {
571: return BracketCompletion.isSkipClosingBracket(
572: getDocument(), getCaretOffset(), bracketTokenId);
573: } catch (BadLocationException e) {
574: e.printStackTrace(getLog());
575: fail();
576: return false; // should never be reached
577: }
578: }
579:
580: private boolean isAddRightBrace() {
581: try {
582: return BracketCompletion.isAddRightBrace(getDocument(),
583: getCaretOffset());
584: } catch (BadLocationException e) {
585: e.printStackTrace(getLog());
586: fail();
587: return false; // should never be reached
588: }
589: }
590: }
|