/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
*
* Oracle and Java are registered trademarks of Oracle and/or its affiliates.
* Other names may be trademarks of their respective owners.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* Portions Copyrighted 2007 Sun Microsystems, Inc.
*/
package org.netbeans.modules.ruby.rhtml.editor;
import javax.swing.text.BadLocationException;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.mimelookup.test.MockMimeLookup;
import org.netbeans.api.html.lexer.HTMLTokenId;
import org.netbeans.api.lexer.Language;
import org.netbeans.api.ruby.platform.RubyInstallation;
import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.BaseKit;
import org.netbeans.lib.lexer.test.TestLanguageProvider;
//import org.netbeans.modules.gsf.api.CompilationInfo;
//import org.netbeans.modules.gsf.api.Formatter;
//import org.netbeans.modules.gsf.spi.DefaultLanguageConfig;
import org.netbeans.modules.csl.api.Formatter;
import org.netbeans.modules.csl.spi.DefaultLanguageConfig;
import org.netbeans.modules.html.editor.indent.HtmlIndentTaskFactory;
import org.netbeans.modules.ruby.RubyFormatter;
import org.netbeans.modules.ruby.RubyTestBase;
import org.netbeans.modules.ruby.rhtml.RhtmlIndentTaskFactory;
import org.netbeans.modules.ruby.rhtml.RhtmlLanguage;
import org.netbeans.modules.ruby.rhtml.lexer.api.RhtmlTokenId;
import org.openide.util.Exceptions;
/**
*
* @author Tor Norbye
*/
public class RhtmlKitTest extends RubyTestBase {
public RhtmlKitTest(String testName) {
super(testName);
}
@Override
protected void setUp() throws Exception {
super.setUp();
try {
TestLanguageProvider.register(RhtmlTokenId.language());
} catch (IllegalStateException ise) {
// Already registered?
}
try {
TestLanguageProvider.register(HTMLTokenId.language());
} catch (IllegalStateException ise) {
// Already registered?
}
RhtmlIndentTaskFactory rhtmlReformatFactory = new RhtmlIndentTaskFactory();
MockMimeLookup.setInstances(MimePath.parse(RubyInstallation.RHTML_MIME_TYPE), rhtmlReformatFactory);
HtmlIndentTaskFactory htmlReformatFactory = new HtmlIndentTaskFactory();
MockMimeLookup.setInstances(MimePath.parse("text/html"), htmlReformatFactory);
}
// @Override
// protected void configureIndenters(final BaseDocument document, final Formatter formatter,
// final CompilationInfo compilationInfo, boolean indentOnly, String mimeType) throws BadLocationException {
// super.configureIndenters(null, new RubyFormatter(), null, true, RubyInstallation.RUBY_MIME_TYPE);
// }
@Override
public BaseDocument getDocument(String s, final String mimeType, final Language language) {
BaseDocument doc = super.getDocument(s, mimeType, language);
doc.putProperty("mimeType", RubyInstallation.RHTML_MIME_TYPE);
doc.putProperty(org.netbeans.api.lexer.Language.class, RhtmlTokenId.language());
return doc;
}
@Override
protected String getPreferredMimeType() {
return RubyInstallation.RHTML_MIME_TYPE;
}
@Override
protected BaseKit getEditorKit(String mimeType) {
return new RhtmlKit();
}
@Override
protected boolean runInEQ() {
// Must run in AWT thread (BaseKit.install() checks for that)
return true;
}
@Override
protected DefaultLanguageConfig getPreferredLanguage() {
return new RhtmlLanguage();
}
private void insertChar(String original, char insertText, String expected) throws BadLocationException, Exception {
insertChar(original, insertText, expected, null);
}
private void insertChar(String original, char insertText, String expected, String selection) throws BadLocationException, Exception {
insertChar(original, insertText, expected, selection, false);
}
public void testInsertTag() throws Exception {
insertChar("<^", '%', "<%^%>");
}
public void testInsertTag2a() throws Exception {
insertChar("<^\n", '%', "<%^%>\n");
}
public void testInsertTag2b() throws Exception {
insertChar("<%^", '%', "<%%^");
}
public void testInsertTag2c() throws Exception {
insertChar("<^f\n", '%', "<%^f\n");
}
public void testInsertTag3() throws Exception {
insertChar("<%%^", '>', "<%%>^");
}
public void testInsertTag4() throws Exception {
insertChar("<%^ ", '%', "<%%^ ");
}
// Fails - problem with Ruby completion itself
//public void testInsertTag5() throws Exception {
// insertChar("<%%^ ", '>', "<%%>^ ");
//}
public void testInsertTag5b() throws Exception {
insertChar("<%#%^ ", '>', "<%#%>^ ");
}
public void testInsertTag6() throws Exception {
insertChar("<%^% ", '%', "<%%^% ");
}
public void testInsertTag8() throws Exception {
insertChar("<%^%>", '%', "<%%^>");
}
public void testInsertTag9() throws Exception {
insertChar("<%%^>", '>', "<%%>^");
}
public void testInsertTag10() throws Exception {
insertChar("<%%^> ", '>', "<%%>^ ");
}
public void testInsertTag11() throws Exception {
insertChar("<%foo^%>", '%', "<%foo%^>");
}
public void testInsertTag12() throws Exception {
insertChar("<%foo%^>", '>', "<%foo%>^");
}
public void testInsertTag13() throws Exception {
insertChar("<%foo%^> ", '>', "<%foo%>^ ");
}
public void testDeleteTag() throws Exception {
deleteChar("<%^%>", "<^");
}
public void testDeleteTag2() throws Exception {
deleteChar("<%^%> ", "<^ ");
}
public void testDeleteTag3() throws Exception {
deleteChar("<%^%><div>", "<^<div>");
}
public void testInsertX() throws Exception {
insertChar("c^ass", 'l', "cl^ass");
}
public void testDeleteX() throws Exception {
deleteChar("cl^ass", "c^ass");
}
public void testInsertX2() throws Exception {
insertChar("clas^", 's', "class^");
}
public void testInsertX3() throws Exception {
insertChar("<% ^ %>", '"', "<% \"^\" %>");
}
public void testInsertX4() throws Exception {
insertChar(" ^ ", '"', " \"^ ");
}
public void testDeleteX3() throws Exception {
deleteChar("<% \"^\" %>", "<% ^ %>");
}
public void testNoMatchInComments() throws Exception {
insertChar("<% # Hello^ %>", '\'', "<% # Hello'^ %>");
insertChar("<% # Hello^ %>", '"', "<% # Hello\"^ %>");
insertChar("<% # Hello^ %>", '[', "<% # Hello[^ %>");
insertChar("<% # Hello^ %>", '(', "<% # Hello(^ %>");
}
public void testSingleQuotes1() throws Exception {
insertChar("<% x = ^ %>", '\'', "<% x = '^' %>");
}
public void testSingleQuotes2() throws Exception {
insertChar("<% x = '^' %>", '\'', "<% x = ''^ %>");
}
public void testSingleQuotes3() throws Exception {
insertChar("<% x = '^' %>", 'a', "<% x = 'a^' %>");
}
public void testSingleQuotes4() throws Exception {
insertChar("<% x = '\\^' %>", '\'', "<% x = '\\'^' %>");
}
public void testDoubleQuotes1() throws Exception {
insertChar("<% x = ^ %>", '"', "<% x = \"^\" %>");
}
public void testBrackets1() throws Exception {
insertChar("<% x = ^ %>", '[', "<% x = [^] %>");
}
public void testBrackets2() throws Exception {
insertChar("<% x = [^] %>", ']', "<% x = []^ %>");
}
public void testBracketsSpecialName() throws Exception {
insertChar("<% def ^ %>", '[', "<% def [^] %>");
}
public void testBracketsSpecialName2() throws Exception {
insertChar("<% def [^] %>", ']', "<% def []^ %>");
}
public void testBrackets3() throws Exception {
insertChar("<% x = [^] %>", 'a', "<% x = [a^] %>");
}
public void testBrackets4() throws Exception {
insertChar("<% x = [^] %>", '[', "<% x = [[^]] %>");
}
public void testBrackets5() throws Exception {
insertChar("<% x = [[^]] %>", ']', "<% x = [[]^] %>");
}
public void testBrackets6() throws Exception {
insertChar("<% x = [[]^] %>", ']', "<% x = [[]]^ %>");
}
public void testParens1() throws Exception {
insertChar("<% x = ^ %>", '(', "<% x = (^) %>");
}
public void testParens2() throws Exception {
insertChar("<% x = (^) %>", ')', "<% x = ()^ %>");
}
public void testParens3() throws Exception {
insertChar("<% x = (^) %>", 'a', "<% x = (a^) %>");
}
public void testParens4() throws Exception {
insertChar("<% x = (^) %>", '(', "<% x = ((^)) %>");
}
public void testParens5() throws Exception {
insertChar("<% x = ((^)) %>", ')', "<% x = (()^) %>");
}
public void testParens6() throws Exception {
insertChar("<% x = (()^) %>", ')', "<% x = (())^ %>");
}
public void testRegexp1() throws Exception {
insertChar("<% x = ^ %>", '/', "<% x = /^/ %>");
}
public void testRegexp2() throws Exception {
insertChar("<% x = /^/ %>", '/', "<% x = //^ %>");
}
public void testRegexp3() throws Exception {
insertChar("<% x = /^/ %>", 'a', "<% x = /a^/ %>");
}
public void testRegexp4() throws Exception {
insertChar("<% x = /\\^/ %>", '/', "<% x = /\\/^/ %>");
}
public void testRegexp5() throws Exception {
insertChar("<% regexp = /fofo^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in %>", '/',
"<% regexp = /fofo/^\n # Subsequently, you can make calls to it by name with <tt>yield</tt> in %>");
}
public void testRegexp6() throws Exception {
insertChar("<% regexp = /fofo^\n %>", '/',
"<% regexp = /fofo/^\n %>");
}
public void testRegexp7() throws Exception {
insertChar("<% x = ^\n %>", '/', "<% x = /^/\n %>");
}
public void testRegexp8() throws Exception {
insertChar("<% x = /^/\n %>", '/', "<% x = //^\n %>");
}
public void testRegexp9() throws Exception {
insertChar("<% x = /^/\n %>", 'a', "<% x = /a^/\n %>");
}
public void testRegexp10() throws Exception {
insertChar("<% x = /\\^/\n %>", '/', "<% x = /\\/^/\n %>");
}
public void testRegexp11() throws Exception {
insertChar("<% /foo^ %>", '/',
"<% /foo/^ %>");
}
public void testNotRegexp1() throws Exception {
insertChar("<% x = 10 ^ %>", '/', "<% x = 10 /^ %>");
}
public void testNotRegexp2() throws Exception {
insertChar("<% x = 3.14 ^ %>", '/', "<% x = 3.14 /^ %>");
}
public void testNotRegexp4() throws Exception {
insertChar("<% x = y^ %>", '/', "<% x = y/^ %>");
}
public void testRegexpPercent1() throws Exception {
insertChar("<% x = %r^ %>", '(', "<% x = %r(^) %>");
}
public void testRegexpPercent2() throws Exception {
insertChar("<% x = %r(^) %>", ')', "<% x = %r()^ %>");
}
public void testSinglePercent1() throws Exception {
insertChar("<% x = %q^ %>", '(', "<% x = %q(^) %>");
}
public void testSinglePercent2() throws Exception {
insertChar("<% x = %q(^) %>", ')', "<% x = %q()^ %>");
}
public void testSinglePercent5() throws Exception {
insertChar("<% x = %q((^)) %>", 'a', "<% x = %q((a^)) %>");
}
public void testSinglePercent6() throws Exception {
insertChar("<% x = %q^ %>", '-', "<% x = %q-^- %>");
}
public void testSinglePercent7() throws Exception {
insertChar("<% x = %q-^- %>", '-', "<% x = %q--^ %>");
}
public void testSinglePercent8() throws Exception {
insertChar("<% x = %q^ %>", ' ', "<% x = %q ^ %>");
}
public void testSinglePercent10() throws Exception {
insertChar("<% x = %q ^ %>", 'x', "<% x = %q x^ %>");
}
public void testSinglePercent11() throws Exception {
insertChar("<% x = %q-\\^- %>", '-', "<% x = %q-\\-^- %>");
}
public void testNoInsertPercentElsewhere() throws Exception {
insertChar("<% x = ^ %>", '#', "<% x = #^ %>");
}
public void testInsertPercentInRegexp() throws Exception {
insertChar("<% x = /foo ^/ %>", '#', "<% x = /foo #{^}/ %>");
}
public void testInsertPercentInRegexp2() throws Exception {
// Make sure type-through works
insertChar("<% x = /foo #{^}/ %>", '}', "<% x = /foo #{}^/ %>");
}
public void testInsertPercentInRegexp3() throws Exception {
insertChar("<% x = /foo #{^}/ %>", '{', "<% x = /foo #{^}/ %>");
}
public void testInsertPercentInRegexp4() throws Exception {
insertChar("<% x = /foo #{^a}/ %>", '}', "<% x = /foo #{}^a}/ %>");
}
public void testInsertPercentInRegexp5() throws Exception {
insertChar("<% x = /foo {^}/ %>", '}', "<% x = /foo {}^}/ %>");
}
public void testInsertPercentInRegexp6() throws Exception {
insertChar("<% x = /foo {^}/ %>", '{', "<% x = /foo {{^}/ %>");
}
public void testReplaceSelection1() throws Exception {
insertChar("<% x = foo^ %>", 'y', "<% x = y^ %>", "foo");
}
public void testReplaceSelection2() throws Exception {
insertChar("<% x = foo^ %>", '"', "<% x = \"foo\"^ %>", "foo");
}
public void testReplaceSelection3() throws Exception {
insertChar("<% x = \"foo^bar\" %>", '#', "<% x = \"#{foo}^bar\" %>", "foo");
}
public void testReplaceSelection4() throws Exception {
insertChar("<% x = 'foo^bar' %>", '#', "<% x = '#^bar' %>", "foo");
}
public void testReplaceCommentSelectionBold() throws Exception {
insertChar("<% # foo^ %>", '*', "<% # *foo*^ %>", "foo");
}
public void testReplaceCommentSelectionTerminal() throws Exception {
insertChar("<% # foo^ %>", '+', "<% # +foo+^ %>", "foo");
}
public void testReplaceCommentSelectionItalic() throws Exception {
insertChar("<% # foo^ %>", '_', "<% # _foo_^ %>", "foo");
}
public void testReplaceCommentSelectionWords() throws Exception {
// No replacement if it contains multiple lines
insertChar("<% # foo bar^ %>", '*', "<% # *^ %>", "foo bar");
}
public void testReplaceCommentOther() throws Exception {
// No replacement if it's not one of the three chars
insertChar("<% # foo^ %>", 'x', "<% # x^ %>", "foo");
}
public void test108889() throws Exception {
// Reproduce 108889: AIOOBE and AE during editing
// NOTE: While the test currently throws an exception, when the
// exception is fixed the test won't actually pass; that's an expected
// fail I will deal with later
insertChar("<% x = %q((^)) %>", 'a', "<% x = %q((a^)) %>");
}
public void testPipes1() throws Exception {
insertChar("<% 5.each { ^ %>", '|', "<% 5.each { |^| %>");
}
public void testPipes2() throws Exception {
insertChar("<% 5.each { ^} %>", '|', "<% 5.each { |^|} %>");
}
public void testPipes3() throws Exception {
insertChar("<% 5.each { |^|} %>", '|', "<% 5.each { ||^} %>");
}
public void testPipes4() throws Exception {
insertChar("<% 5.each { |foo^|} %>", '|', "<% 5.each { |foo|^} %>");
}
public void testNegativePipes1() throws Exception {
insertChar("<% '^' %>", '|', "<% '|^' %>");
}
public void testNegativePipes2() throws Exception {
insertChar("<% /^/ %>", '|', "<% /|^/ %>");
}
public void testNegativePipes3() throws Exception {
insertChar("<% #^ %>", '|', "<% #|^ %>");
}
public void testNegativePipes4() throws Exception {
insertChar("<% \"^\" %>", '|', "<% \"|^\" %>");
}
public void testNegativePipes5() throws Exception {
insertChar("<% 5.each { |f^oo|} %>", '|', "<% 5.each { |f|^oo|} %>");
}
public void testNegativePipes6() throws Exception {
insertChar("<% 5.each { |^|foo|} %>", '|', "<% 5.each { ||^foo|} %>");
}
public void testNegativePipes7() throws Exception {
insertChar("<% x = true ^ %>", '|', "<% x = true |^ %>");
}
public void testNegativePipes8() throws Exception {
insertChar("<% x = true |^ %>", '|', "<% x = true ||^ %>");
}
// ----------- Comment toggling
public void testToggleComment1() throws Exception {
toggleComment("fo^o", "<%#*foo%>");
}
public void testToggleComment2() throws Exception {
toggleComment("<%#*f^oo%>", "foo");
}
public void testToggleComment3() throws Exception {
toggleComment("<% ruby^ %>", "<%# ruby %>");
}
public void testToggleComment4() throws Exception {
toggleComment("<%# ruby^ %>", "<% ruby %>");
}
public void testToggleComment5() throws Exception {
toggleComment("foo\n<div>\n <span>^</span> \n <%= rubyexp %> \n",
"foo\n<div>\n <%#*<span></span>%> \n <%= rubyexp %> \n");
}
public void testToggleComment6() throws Exception {
toggleComment("foo\n<div>\n $start$<span></span>$end$ \n \n <%= rubyexp %> \n",
"foo\n<div>\n <%#*<span></span>%> \n \n <%= rubyexp %> \n");
}
public void testToggleComment7() throws Exception {
toggleComment("$start$foo\n<div>\n <span></span> \n \n <%= rubyexp %> \n$end$",
"<%#*foo%>\n<%#*<div>%>\n <%#*<span></span>%> \n \n <%#= rubyexp %> \n");
}
public void testToggleComment8() throws Exception {
toggleComment("$start$<%#*foo%>\n<%#*<div>%>\n <%#*<span></span>%> \n \n <%#= rubyexp %> \n$end$",
"foo\n<div>\n <span></span> \n \n <%= rubyexp %> \n");
}
public void testToggleComment9() throws Exception {
toggleComment("<div>\n <% ruby1\n ru^by2\n ruby3 %> \n</div>\n",
"<div>\n <% ruby1\n #ruby2\n ruby3 %> \n</div>\n");
}
public void testToggleComment10() throws Exception {
toggleComment("<div>\n <% ruby1\n #ru^by2\n ruby3 %> \n</div>\n",
"<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n");
}
public void testToggleComment11() throws Exception {
toggleComment("$start$<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n$end$",
"<%#*<div>%>\n <%# ruby1\n ruby2\n ruby3 %> \n<%#*</div>%>\n");
}
public void testToggleComment12() throws Exception {
toggleComment("$start$<%#*<div>%>\n <%# ruby1\n ruby2\n ruby3 %> \n<%#*</div>%>\n$end$",
"<div>\n <% ruby1\n ruby2\n ruby3 %> \n</div>\n");
}
public void testToggleComment13() throws Exception {
toggleComment("<% #ruby^ %>", "<% ruby %>");
}
// test insert break; in particular, entering out of <% else %> doesn't work at the end of input!
public void testNewline1() throws Exception {
insertNewline("<div>^", "<div>\n ^", new IndentPrefs(2, 2));
}
public void testNewline2() throws Exception {
insertNewline("<div></div>^", "<div></div>\n^", new IndentPrefs(2, 2));
}
public void testNewline3a() throws Exception {
insertNewline("<div>^</div>", "<div>\n ^\n</div>", new IndentPrefs(2, 2));
}
public void testNewline3b() throws Exception {
insertNewline("<div>^</div>\n", "<div>\n ^\n</div>\n", new IndentPrefs(2, 2));
}
public void testNewline4a() throws Exception {
failingDueToIssue160612("<% if true %>^\n", "<% if true %>\n ^\n", new IndentPrefs(2, 2));
// insertNewline("<% if true %>^\n", "<% if true %>\n ^\n", new IndentPrefs(2, 2));
}
public void testNewline4b() throws Exception {
failingDueToIssue160612(" <% if true %>^\n", " <% if true %>\n ^\n", new IndentPrefs(2, 2));
// insertNewline(" <% if true %>^\n", " <% if true %>\n ^\n", new IndentPrefs(2, 2));
}
public void testNewline5a() throws Exception {
failingDueToIssue160612("<% if true %>^", "<% if true %>\n ^", new IndentPrefs(2, 2));
// insertNewline("<% if true %>^", "<% if true %>\n ^", new IndentPrefs(2, 2));
}
public void testNewline5b() throws Exception {
failingDueToIssue160612(" <% if true %>^", " <% if true %>\n ^", new IndentPrefs(2, 2));
// insertNewline(" <% if true %>^", " <% if true %>\n ^", new IndentPrefs(2, 2));
}
public void testNewline5c() throws Exception {
insertNewline(" <% if ^true %>", " <% if \n ^true %>", new IndentPrefs(2, 2));
}
public void testNewline6() throws Exception {
failingDueToIssue160612(" <% foo %>^\n", " <% foo %>\n ^\n", new IndentPrefs(2, 2));
// insertNewline(" <% foo %>^\n", " <% foo %>\n ^\n", new IndentPrefs(2, 2));
}
public void testNewline7() throws Exception {
failingDueToIssue160612(" <% foo %>^", " <% foo %>\n ^", new IndentPrefs(2, 2));
}
public void testNewline8() throws Exception {
failingDueToIssue160612(" <% foo %>^<span>", " <% foo %>\n ^<span>", new IndentPrefs(2, 2));
// insertNewline(" <% foo %>^<span>", " <% foo %>\n ^<span>", new IndentPrefs(2, 2));
}
private void failingDueToIssue160612(String source, String reformatted, IndentPrefs prefs) throws Exception {
try {
insertNewline(source, reformatted, prefs);
} catch (AssertionError ae) {
String msg = "Skipping failing test: " + getName() + " -- see https://netbeans.org/bugzilla/show_bug.cgi?id=160612. Error: " + ae.getMessage();
log(msg);
System.out.println(msg);
}
}
}