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.ruby.rhtml.editor;
030:
031: import javax.swing.JEditorPane;
032: import javax.swing.text.BadLocationException;
033: import javax.swing.text.Caret;
034: import javax.swing.text.DefaultEditorKit;
035: import org.netbeans.editor.BaseDocument;
036: import org.netbeans.modules.ruby.rhtml.RhtmlTestBase;
037:
038: /**
039: *
040: * @author Tor Norbye
041: */
042: public class RhtmlKitTest extends RhtmlTestBase {
043:
044: public RhtmlKitTest(String testName) {
045: super (testName);
046: }
047:
048: public void toggleComment(String text, String expected)
049: throws Exception {
050: JEditorPane pane = getPane(text);
051:
052: runKitAction(pane, "toggle-comment", "");
053:
054: String toggled = pane.getText();
055: assertEquals(expected, toggled);
056: }
057:
058: @Override
059: protected boolean runInEQ() {
060: // Must run in AWT thread (BaseKit.install() checks for that)
061: return true;
062: }
063:
064: private void insertChar(String original, char insertText,
065: String expected) throws BadLocationException, Exception {
066: insertChar(original, insertText, expected, null);
067: }
068:
069: private void insertChar(String original, char insertText,
070: String expected, String selection)
071: throws BadLocationException, Exception {
072: JEditorPane pane = getPane(original);
073: int insertOffset = original.indexOf('^');
074: int finalCaretPos = expected.indexOf('^');
075: original = original.substring(0, insertOffset)
076: + original.substring(insertOffset + 1);
077: expected = expected.substring(0, finalCaretPos)
078: + expected.substring(finalCaretPos + 1);
079:
080: Caret caret = pane.getCaret();
081: caret.setDot(insertOffset);
082: BaseDocument doc = (BaseDocument) pane.getDocument();
083: if (selection != null) {
084: int start = original.indexOf(selection);
085: assertTrue(start != -1);
086: assertTrue(
087: "Ambiguous selection - multiple occurrences of selection string",
088: original.indexOf(selection, start + 1) == -1);
089: pane.setSelectionStart(start);
090: pane.setSelectionEnd(start + selection.length());
091: assertEquals(selection, pane.getSelectedText());
092: }
093: runKitAction(pane, DefaultEditorKit.defaultKeyTypedAction, ""
094: + insertText);
095:
096: String formatted = doc.getText(0, doc.getLength());
097: assertEquals(expected, formatted);
098: if (finalCaretPos != -1) {
099: assertEquals(finalCaretPos, caret.getDot());
100: }
101: }
102:
103: private void deleteChar(String original, String expected)
104: throws BadLocationException, Exception {
105: JEditorPane pane = getPane(original);
106: int afterRemoveOffset = original.indexOf('^');
107: int finalCaretPos = expected.indexOf('^');
108: original = original.substring(0, afterRemoveOffset)
109: + original.substring(afterRemoveOffset + 1);
110: expected = expected.substring(0, finalCaretPos)
111: + expected.substring(finalCaretPos + 1);
112:
113: Caret caret = pane.getCaret();
114: caret.setDot(afterRemoveOffset);
115: BaseDocument doc = (BaseDocument) pane.getDocument();
116: char ch = doc.getChars(afterRemoveOffset - 1, 1)[0];
117:
118: runKitAction(pane, DefaultEditorKit.deletePrevCharAction, ""
119: + ch);
120:
121: String formatted = doc.getText(0, doc.getLength());
122: assertEquals(expected, formatted);
123: if (finalCaretPos != -1) {
124: assertEquals(finalCaretPos, caret.getDot());
125: }
126: }
127:
128: public void testInsertTag() throws Exception {
129: insertChar("<^", '%', "<%^%>");
130: }
131:
132: public void testInsertTag2a() throws Exception {
133: insertChar("<^\n", '%', "<%^%>\n");
134: }
135:
136: public void testInsertTag2b() throws Exception {
137: insertChar("<%^", '%', "<%%^");
138: }
139:
140: public void testInsertTag2c() throws Exception {
141: insertChar("<^f\n", '%', "<%^f\n");
142: }
143:
144: public void testInsertTag3() throws Exception {
145: insertChar("<%%^", '>', "<%%>^");
146: }
147:
148: public void testInsertTag4() throws Exception {
149: insertChar("<%^ ", '%', "<%%^ ");
150: }
151:
152: // Fails - problem with Ruby completion itself
153: //public void testInsertTag5() throws Exception {
154: // insertChar("<%%^ ", '>', "<%%>^ ");
155: //}
156:
157: public void testInsertTag5b() throws Exception {
158: insertChar("<%#%^ ", '>', "<%#%>^ ");
159: }
160:
161: public void testInsertTag6() throws Exception {
162: insertChar("<%^% ", '%', "<%%^% ");
163: }
164:
165: public void testInsertTag8() throws Exception {
166: insertChar("<%^%>", '%', "<%%^>");
167: }
168:
169: public void testInsertTag9() throws Exception {
170: insertChar("<%%^>", '>', "<%%>^");
171: }
172:
173: public void testInsertTag10() throws Exception {
174: insertChar("<%%^> ", '>', "<%%>^ ");
175: }
176:
177: public void testInsertTag11() throws Exception {
178: insertChar("<%foo^%>", '%', "<%foo%^>");
179: }
180:
181: public void testInsertTag12() throws Exception {
182: insertChar("<%foo%^>", '>', "<%foo%>^");
183: }
184:
185: public void testInsertTag13() throws Exception {
186: insertChar("<%foo%^> ", '>', "<%foo%>^ ");
187: }
188:
189: public void testDeleteTag() throws Exception {
190: deleteChar("<%^%>", "<^");
191: }
192:
193: public void testDeleteTag2() throws Exception {
194: deleteChar("<%^%> ", "<^ ");
195: }
196:
197: public void testDeleteTag3() throws Exception {
198: deleteChar("<%^%><div>", "<^<div>");
199: }
200:
201: public void testInsertX() throws Exception {
202: insertChar("c^ass", 'l', "cl^ass");
203: }
204:
205: public void testDeleteX() throws Exception {
206: deleteChar("cl^ass", "c^ass");
207: }
208:
209: public void testInsertX2() throws Exception {
210: insertChar("clas^", 's', "class^");
211: }
212:
213: public void testInsertX3() throws Exception {
214: insertChar("<% ^ %>", '"', "<% \"^\" %>");
215: }
216:
217: public void testInsertX4() throws Exception {
218: insertChar(" ^ ", '"', " \"^ ");
219: }
220:
221: public void testDeleteX3() throws Exception {
222: deleteChar("<% \"^\" %>", "<% ^ %>");
223: }
224:
225: public void testNoMatchInComments() throws Exception {
226: insertChar("<% # Hello^ %>", '\'', "<% # Hello'^ %>");
227: insertChar("<% # Hello^ %>", '"', "<% # Hello\"^ %>");
228: insertChar("<% # Hello^ %>", '[', "<% # Hello[^ %>");
229: insertChar("<% # Hello^ %>", '(', "<% # Hello(^ %>");
230: }
231:
232: public void testSingleQuotes1() throws Exception {
233: insertChar("<% x = ^ %>", '\'', "<% x = '^' %>");
234: }
235:
236: public void testSingleQuotes2() throws Exception {
237: insertChar("<% x = '^' %>", '\'', "<% x = ''^ %>");
238: }
239:
240: public void testSingleQuotes3() throws Exception {
241: insertChar("<% x = '^' %>", 'a', "<% x = 'a^' %>");
242: }
243:
244: public void testSingleQuotes4() throws Exception {
245: insertChar("<% x = '\\^' %>", '\'', "<% x = '\\'^' %>");
246: }
247:
248: public void testDoubleQuotes1() throws Exception {
249: insertChar("<% x = ^ %>", '"', "<% x = \"^\" %>");
250: }
251:
252: public void testBrackets1() throws Exception {
253: insertChar("<% x = ^ %>", '[', "<% x = [^] %>");
254: }
255:
256: public void testBrackets2() throws Exception {
257: insertChar("<% x = [^] %>", ']', "<% x = []^ %>");
258: }
259:
260: public void testBracketsSpecialName() throws Exception {
261: insertChar("<% def ^ %>", '[', "<% def [^] %>");
262: }
263:
264: public void testBracketsSpecialName2() throws Exception {
265: insertChar("<% def [^] %>", ']', "<% def []^ %>");
266: }
267:
268: public void testBrackets3() throws Exception {
269: insertChar("<% x = [^] %>", 'a', "<% x = [a^] %>");
270: }
271:
272: public void testBrackets4() throws Exception {
273: insertChar("<% x = [^] %>", '[', "<% x = [[^]] %>");
274: }
275:
276: public void testBrackets5() throws Exception {
277: insertChar("<% x = [[^]] %>", ']', "<% x = [[]^] %>");
278: }
279:
280: public void testBrackets6() throws Exception {
281: insertChar("<% x = [[]^] %>", ']', "<% x = [[]]^ %>");
282: }
283:
284: public void testParens1() throws Exception {
285: insertChar("<% x = ^ %>", '(', "<% x = (^) %>");
286: }
287:
288: public void testParens2() throws Exception {
289: insertChar("<% x = (^) %>", ')', "<% x = ()^ %>");
290: }
291:
292: public void testParens3() throws Exception {
293: insertChar("<% x = (^) %>", 'a', "<% x = (a^) %>");
294: }
295:
296: public void testParens4() throws Exception {
297: insertChar("<% x = (^) %>", '(', "<% x = ((^)) %>");
298: }
299:
300: public void testParens5() throws Exception {
301: insertChar("<% x = ((^)) %>", ')', "<% x = (()^) %>");
302: }
303:
304: public void testParens6() throws Exception {
305: insertChar("<% x = (()^) %>", ')', "<% x = (())^ %>");
306: }
307:
308: public void testRegexp1() throws Exception {
309: insertChar("<% x = ^ %>", '/', "<% x = /^/ %>");
310: }
311:
312: public void testRegexp2() throws Exception {
313: insertChar("<% x = /^/ %>", '/', "<% x = //^ %>");
314: }
315:
316: public void testRegexp3() throws Exception {
317: insertChar("<% x = /^/ %>", 'a', "<% x = /a^/ %>");
318: }
319:
320: public void testRegexp4() throws Exception {
321: insertChar("<% x = /\\^/ %>", '/', "<% x = /\\/^/ %>");
322: }
323:
324: public void testRegexp5() throws Exception {
325: insertChar(
326: "<% regexp = /fofo^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in %>",
327: '/',
328: "<% regexp = /fofo/^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in %>");
329: }
330:
331: public void testRegexp6() throws Exception {
332: insertChar("<% regexp = /fofo^\n %>", '/',
333: "<% regexp = /fofo/^\n %>");
334: }
335:
336: public void testRegexp7() throws Exception {
337: insertChar("<% x = ^\n %>", '/', "<% x = /^/\n %>");
338: }
339:
340: public void testRegexp8() throws Exception {
341: insertChar("<% x = /^/\n %>", '/', "<% x = //^\n %>");
342: }
343:
344: public void testRegexp9() throws Exception {
345: insertChar("<% x = /^/\n %>", 'a', "<% x = /a^/\n %>");
346: }
347:
348: public void testRegexp10() throws Exception {
349: insertChar("<% x = /\\^/\n %>", '/', "<% x = /\\/^/\n %>");
350: }
351:
352: public void testRegexp11() throws Exception {
353: insertChar("<% /foo^ %>", '/', "<% /foo/^ %>");
354: }
355:
356: public void testNotRegexp1() throws Exception {
357: insertChar("<% x = 10 ^ %>", '/', "<% x = 10 /^ %>");
358: }
359:
360: public void testNotRegexp2() throws Exception {
361: insertChar("<% x = 3.14 ^ %>", '/', "<% x = 3.14 /^ %>");
362: }
363:
364: public void testNotRegexp4() throws Exception {
365: insertChar("<% x = y^ %>", '/', "<% x = y/^ %>");
366: }
367:
368: public void testRegexpPercent1() throws Exception {
369: insertChar("<% x = %r^ %>", '(', "<% x = %r(^) %>");
370: }
371:
372: public void testRegexpPercent2() throws Exception {
373: insertChar("<% x = %r(^) %>", ')', "<% x = %r()^ %>");
374: }
375:
376: public void testSinglePercent1() throws Exception {
377: insertChar("<% x = %q^ %>", '(', "<% x = %q(^) %>");
378: }
379:
380: public void testSinglePercent2() throws Exception {
381: insertChar("<% x = %q(^) %>", ')', "<% x = %q()^ %>");
382: }
383:
384: public void testSinglePercent5() throws Exception {
385: insertChar("<% x = %q((^)) %>", 'a', "<% x = %q((a^)) %>");
386: }
387:
388: public void testSinglePercent6() throws Exception {
389: insertChar("<% x = %q^ %>", '-', "<% x = %q-^- %>");
390: }
391:
392: public void testSinglePercent7() throws Exception {
393: insertChar("<% x = %q-^- %>", '-', "<% x = %q--^ %>");
394: }
395:
396: public void testSinglePercent8() throws Exception {
397: insertChar("<% x = %q^ %>", ' ', "<% x = %q ^ %>");
398: }
399:
400: public void testSinglePercent10() throws Exception {
401: insertChar("<% x = %q ^ %>", 'x', "<% x = %q x^ %>");
402: }
403:
404: public void testSinglePercent11() throws Exception {
405: insertChar("<% x = %q-\\^- %>", '-', "<% x = %q-\\-^- %>");
406: }
407:
408: public void testNoInsertPercentElsewhere() throws Exception {
409: insertChar("<% x = ^ %>", '#', "<% x = #^ %>");
410: }
411:
412: public void testInsertPercentInRegexp() throws Exception {
413: insertChar("<% x = /foo ^/ %>", '#', "<% x = /foo #{^}/ %>");
414: }
415:
416: public void testInsertPercentInRegexp2() throws Exception {
417: // Make sure type-through works
418: insertChar("<% x = /foo #{^}/ %>", '}', "<% x = /foo #{}^/ %>");
419: }
420:
421: public void testInsertPercentInRegexp3() throws Exception {
422: insertChar("<% x = /foo #{^}/ %>", '{', "<% x = /foo #{^}/ %>");
423: }
424:
425: public void testInsertPercentInRegexp4() throws Exception {
426: insertChar("<% x = /foo #{^a}/ %>", '}',
427: "<% x = /foo #{}^a}/ %>");
428: }
429:
430: public void testInsertPercentInRegexp5() throws Exception {
431: insertChar("<% x = /foo {^}/ %>", '}', "<% x = /foo {}^}/ %>");
432: }
433:
434: public void testInsertPercentInRegexp6() throws Exception {
435: insertChar("<% x = /foo {^}/ %>", '{', "<% x = /foo {{^}/ %>");
436: }
437:
438: public void testReplaceSelection1() throws Exception {
439: insertChar("<% x = foo^ %>", 'y', "<% x = y^ %>", "foo");
440: }
441:
442: public void testReplaceSelection2() throws Exception {
443: insertChar("<% x = foo^ %>", '"', "<% x = \"foo\"^ %>", "foo");
444: }
445:
446: public void testReplaceSelection3() throws Exception {
447: insertChar("<% x = \"foo^bar\" %>", '#',
448: "<% x = \"#{foo}^bar\" %>", "foo");
449: }
450:
451: public void testReplaceSelection4() throws Exception {
452: insertChar("<% x = 'foo^bar' %>", '#', "<% x = '#^bar' %>",
453: "foo");
454: }
455:
456: public void testReplaceCommentSelectionBold() throws Exception {
457: insertChar("<% # foo^ %>", '*', "<% # *foo*^ %>", "foo");
458: }
459:
460: public void testReplaceCommentSelectionTerminal() throws Exception {
461: insertChar("<% # foo^ %>", '+', "<% # +foo+^ %>", "foo");
462: }
463:
464: public void testReplaceCommentSelectionItalic() throws Exception {
465: insertChar("<% # foo^ %>", '_', "<% # _foo_^ %>", "foo");
466: }
467:
468: public void testReplaceCommentSelectionWords() throws Exception {
469: // No replacement if it contains multiple lines
470: insertChar("<% # foo bar^ %>", '*', "<% # *^ %>", "foo bar");
471: }
472:
473: public void testReplaceCommentOther() throws Exception {
474: // No replacement if it's not one of the three chars
475: insertChar("<% # foo^ %>", 'x', "<% # x^ %>", "foo");
476: }
477:
478: public void test108889() throws Exception {
479: // Reproduce 108889: AIOOBE and AE during editing
480: // NOTE: While the test currently throws an exception, when the
481: // exception is fixed the test won't actually pass; that's an expected
482: // fail I will deal with later
483: insertChar("<% x = %q((^)) %>", 'a', "<% x = %q((a^)) %>");
484: }
485:
486: public void testPipes1() throws Exception {
487: insertChar("<% 5.each { ^ %>", '|', "<% 5.each { |^| %>");
488: }
489:
490: public void testPipes2() throws Exception {
491: insertChar("<% 5.each { ^} %>", '|', "<% 5.each { |^|} %>");
492: }
493:
494: public void testPipes3() throws Exception {
495: insertChar("<% 5.each { |^|} %>", '|', "<% 5.each { ||^} %>");
496: }
497:
498: public void testPipes4() throws Exception {
499: insertChar("<% 5.each { |foo^|} %>", '|',
500: "<% 5.each { |foo|^} %>");
501: }
502:
503: public void testNegativePipes1() throws Exception {
504: insertChar("<% '^' %>", '|', "<% '|^' %>");
505: }
506:
507: public void testNegativePipes2() throws Exception {
508: insertChar("<% /^/ %>", '|', "<% /|^/ %>");
509: }
510:
511: public void testNegativePipes3() throws Exception {
512: insertChar("<% #^ %>", '|', "<% #|^ %>");
513: }
514:
515: public void testNegativePipes4() throws Exception {
516: insertChar("<% \"^\" %>", '|', "<% \"|^\" %>");
517: }
518:
519: public void testNegativePipes5() throws Exception {
520: insertChar("<% 5.each { |f^oo|} %>", '|',
521: "<% 5.each { |f|^oo|} %>");
522: }
523:
524: public void testNegativePipes6() throws Exception {
525: insertChar("<% 5.each { |^|foo|} %>", '|',
526: "<% 5.each { ||^foo|} %>");
527: }
528:
529: public void testNegativePipes7() throws Exception {
530: insertChar("<% x = true ^ %>", '|', "<% x = true |^ %>");
531: }
532:
533: public void testNegativePipes8() throws Exception {
534: insertChar("<% x = true |^ %>", '|', "<% x = true ||^ %>");
535: }
536:
537: // ----------- Comment toggling
538:
539: public void testToggleComment1() throws Exception {
540: toggleComment("fo^o", "<%#*foo%>");
541: }
542:
543: public void testToggleComment2() throws Exception {
544: toggleComment("<%#*f^oo%>", "foo");
545: }
546:
547: public void testToggleComment3() throws Exception {
548: toggleComment("<% ruby^ %>", "<%# ruby %>");
549: }
550:
551: public void testToggleComment4() throws Exception {
552: toggleComment("<%# ruby^ %>", "<% ruby %>");
553: }
554:
555: public void testToggleComment5() throws Exception {
556: toggleComment(
557: "foo\n<div>\n <span>^</span> \n <%= rubyexp %> \n",
558: "foo\n<div>\n <%#*<span></span>%> \n <%= rubyexp %> \n");
559: }
560:
561: public void testToggleComment6() throws Exception {
562: toggleComment(
563: "foo\n<div>\n $start$<span></span>$end$ \n \n <%= rubyexp %> \n",
564: "foo\n<div>\n <%#*<span></span>%> \n \n <%= rubyexp %> \n");
565: }
566:
567: public void testToggleComment7() throws Exception {
568: toggleComment(
569: "$start$foo\n<div>\n <span></span> \n \n <%= rubyexp %> \n$end$",
570: "<%#*foo%>\n<%#*<div>%>\n <%#*<span></span>%> \n \n <%#= rubyexp %> \n");
571: }
572:
573: public void testToggleComment8() throws Exception {
574: toggleComment(
575: "$start$<%#*foo%>\n<%#*<div>%>\n <%#*<span></span>%> \n \n <%#= rubyexp %> \n$end$",
576: "foo\n<div>\n <span></span> \n \n <%= rubyexp %> \n");
577: }
578:
579: public void testToggleComment9() throws Exception {
580: toggleComment(
581: "<div>\n <% ruby1\n ru^by2\n ruby3 %> \n</div>\n",
582: "<div>\n <% ruby1\n #ruby2\n ruby3 %> \n</div>\n");
583: }
584:
585: public void testToggleComment10() throws Exception {
586: toggleComment(
587: "<div>\n <% ruby1\n #ru^by2\n ruby3 %> \n</div>\n",
588: "<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n");
589: }
590:
591: public void testToggleComment11() throws Exception {
592: toggleComment(
593: "$start$<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n$end$",
594: "<%#*<div>%>\n <%# ruby1\n ruby2\n ruby3 %> \n<%#*</div>%>\n");
595: }
596:
597: public void testToggleComment12() throws Exception {
598: toggleComment(
599: "$start$<%#*<div>%>\n <%# ruby1\n ruby2\n ruby3 %> \n<%#*</div>%>\n$end$",
600: "<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n");
601: }
602:
603: public void testToggleComment13() throws Exception {
604: toggleComment("<% #ruby^ %>", "<% ruby %>");
605: }
606:
607: // test insert break; in particular, entering out of <% else %> doesn't work at the end of input!
608: }
|