diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/AbstractJFlexTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/AbstractJFlexTokenMaker.java index 987cff447..402f27ec7 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/AbstractJFlexTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/AbstractJFlexTokenMaker.java @@ -58,5 +58,14 @@ protected void yybegin(int state, int languageIndex) { } + public abstract char yycharat(int pos); + + + public abstract int yylength(); + + + public abstract int yystate(); + + public abstract String yytext(); } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManager.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManager.java index 0932e814d..f2d36a3b2 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManager.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManager.java @@ -18,11 +18,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; +import java.util.*; import javax.swing.text.BadLocationException; import javax.swing.text.Document; @@ -104,8 +100,7 @@ public synchronized CodeTemplate getTemplate(RSyntaxTextArea textArea) { int index = Collections.binarySearch(templates, s, comparator); return index>=0 ? templates.get(index) : null; } catch (BadLocationException ble) { - ble.printStackTrace(); - throw new InternalError("Error in CodeTemplateManager"); + throw new InternalError("Error in CodeTemplateManager", ble); } } @@ -219,9 +214,6 @@ public synchronized void replaceTemplates(CodeTemplate[] newTemplates) { */ public synchronized boolean saveTemplates() { - if (templates==null) { - return true; - } if (directory==null || !directory.isDirectory()) { return false; } @@ -292,10 +284,13 @@ public synchronized int setTemplateDirectory(File dir) { } temp.add((CodeTemplate)obj); d.close(); - } catch (/*IO, NoSuchElement*/Exception e) { + } catch (IOException | ArrayIndexOutOfBoundsException | NoSuchElementException e) { // NoSuchElementException can be thrown when reading // an XML file not in the format expected by XMLDecoder. // (e.g. CodeTemplates in an old format). + // ArrayIndexOutOfBoundsException is thrown by XMLDecoder + // in certain circumstances for XML that isn't an encoded + // Java object. e.printStackTrace(); } } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/ParserManager.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/ParserManager.java index 43cc62448..30116ca0d 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/ParserManager.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/ParserManager.java @@ -42,7 +42,6 @@ import org.fife.ui.rtextarea.RTextAreaHighlighter.HighlightInfo; - /** * Manages running a parser object for an RSyntaxTextArea. * @@ -84,7 +83,7 @@ class ParserManager implements DocumentListener, ActionListener, /** * Whether to print debug messages while running parsers. */ - private static final boolean DEBUG_PARSING; + private boolean debugParsing; /** * The default delay between the last key press and when the document @@ -113,6 +112,7 @@ class ParserManager implements DocumentListener, ActionListener, * parsing. */ ParserManager(int delay, RSyntaxTextArea textArea) { + debugParsing = getDefaultDebugParsing(); this.textArea = textArea; textArea.getDocument().addDocumentListener(this); textArea.addPropertyChangeListener("document", this); @@ -138,7 +138,7 @@ public void actionPerformed(ActionEvent e) { } long begin = 0; - if (DEBUG_PARSING) { + if (debugParsing) { begin = System.currentTimeMillis(); } @@ -150,7 +150,7 @@ public void actionPerformed(ActionEvent e) { int lastLine = lastOffsetModded==null ? root.getElementCount()-1 : root.getElementIndex(lastOffsetModded.getOffset()); firstOffsetModded = lastOffsetModded = null; - if (DEBUG_PARSING) { + if (debugParsing) { System.out.println("[DEBUG]: Minimum lines to parse: " + firstLine + "-" + lastLine); } @@ -172,7 +172,7 @@ public void actionPerformed(ActionEvent e) { doc.readUnlock(); } - if (DEBUG_PARSING) { + if (debugParsing) { float time = (System.currentTimeMillis()-begin)/1000f; System.out.println("Total parsing time: " + time + " seconds"); } @@ -220,7 +220,7 @@ private void addParserNoticeHighlights(ParseResult res) { return; } - if (DEBUG_PARSING) { + if (debugParsing) { System.out.println("[DEBUG]: Adding parser notices from " + res.getParser()); } @@ -238,7 +238,7 @@ private void addParserNoticeHighlights(ParseResult res) { textArea.getHighlighter(); for (ParserNotice notice : notices) { - if (DEBUG_PARSING) { + if (debugParsing) { System.out.println("[DEBUG]: ... adding: " + notice); } try { @@ -255,7 +255,7 @@ private void addParserNoticeHighlights(ParseResult res) { } - if (DEBUG_PARSING) { + if (debugParsing) { System.out.println("[DEBUG]: Done adding parser notices from " + res.getParser()); } @@ -348,6 +348,18 @@ public void forceReparsing(int parser) { } + private static boolean getDefaultDebugParsing() { + boolean debugParsing; + try { + debugParsing = Boolean.getBoolean(PROPERTY_DEBUG_PARSING); + } catch (AccessControlException ace) { + // Likely an applet's security manager. + debugParsing = false; // FindBugs + } + return debugParsing; + } + + /** * Returns the delay between the last "concurrent" edit and when the * document is reparsed. @@ -664,7 +676,7 @@ private void removeParserNotices(ParseResult res) { i.remove(); removed = true; } - if (DEBUG_PARSING) { + if (debugParsing) { String text = removed ? "[DEBUG]: ... notice removed: " : "[DEBUG]: ... notice not removed: "; System.out.println(text + pair.notice); @@ -716,6 +728,18 @@ public void restartParsing() { } + /** + * Toggles whether debug information about parsing is + * written to stdout. + * + * @param debugParsing Whether debug parsing information + * is enabled. + */ + public void setDebugParsing(boolean debugParsing) { + this.debugParsing = debugParsing; + } + + /** * Sets the delay between the last "concurrent" edit and when the document * is reparsed. @@ -747,7 +771,7 @@ public void setDelay(int millis) { private boolean shouldRemoveNotice(ParserNotice notice, ParseResult res) { - if (DEBUG_PARSING) { + if (debugParsing) { System.out.println("[DEBUG]: ... ... shouldRemoveNotice " + notice + ": " + (notice.getParser()==res.getParser())); } @@ -791,16 +815,4 @@ private static class NoticeHighlightPair { } - static { - boolean debugParsing; - try { - debugParsing = Boolean.getBoolean(PROPERTY_DEBUG_PARSING); - } catch (AccessControlException ace) { - // Likely an applet's security manager. - debugParsing = false; // FindBugs - } - DEBUG_PARSING = debugParsing; - } - - } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKit.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKit.java index 85957318b..c1e038deb 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKit.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKit.java @@ -12,6 +12,7 @@ import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; +import java.text.BreakIterator; import java.text.CharacterIterator; import java.util.ResourceBundle; import java.util.Stack; @@ -1048,7 +1049,7 @@ protected int getPreviousWord(RTextArea textArea, int offs) } else { // offs == start => previous word is on previous line if (line == 0) { - return -1; + return BreakIterator.DONE; } elem = root.getElement(--line); offs = elem.getEndOffset() - 1; @@ -1169,6 +1170,25 @@ private static boolean isIdentifierChar(char ch) { } + /** + * Moves the caret to the end of the document, taking into account code + * folding. + */ + public static class EndAction extends RTextAreaEditorKit.EndAction { + + public EndAction(String name, boolean select) { + super(name, select); + } + + @Override + protected int getVisibleEnd(RTextArea textArea) { + RSyntaxTextArea rsta = (RSyntaxTextArea)textArea; + return rsta.getLastVisibleOffset(); + } + + } + + /** * Positions the caret at the end of the word. This class is here to * better handle finding the "end of the word" in programming languages. @@ -1322,24 +1342,6 @@ protected Fold getClosestFold(RSyntaxTextArea textArea) { public static class GoToMatchingBracketAction extends RecordableTextAction { - /** - * Moves the caret to the end of the document, taking into account code - * folding. - */ - public static class EndAction extends RTextAreaEditorKit.EndAction { - - public EndAction(String name, boolean select) { - super(name, select); - } - - @Override - protected int getVisibleEnd(RTextArea textArea) { - RSyntaxTextArea rsta = (RSyntaxTextArea)textArea; - return rsta.getLastVisibleOffset(); - } - - } - private static final long serialVersionUID = 1L; private Point bracketInfo; @@ -1956,7 +1958,7 @@ protected int getNextWord(RTextArea textArea, int offs) Element root = doc.getDefaultRootElement(); int line = root.getElementIndex(offs); int end = root.getElement(line).getEndOffset() - 1; - if (offs==end) {// If we're already at the end of the line... + if (offs==end) { // If we're already at the end of the line... RSyntaxTextArea rsta = (RSyntaxTextArea)textArea; if (rsta.isCodeFoldingEnabled()) { // Start of next visible line FoldManager fm = rsta.getFoldManager(); @@ -2033,34 +2035,28 @@ public void actionPerformedImpl(ActionEvent e, RTextArea textArea) { if (RSyntaxTextArea.getTemplatesEnabled()) { - Document doc = textArea.getDocument(); - if (doc != null) { - - try { - - CodeTemplateManager manager = RSyntaxTextArea. - getCodeTemplateManager(); - CodeTemplate template = manager==null ? null : - manager.getTemplate(rsta); - - // A non-null template means modify the text to insert! - if (template!=null) { - template.invoke(rsta); - } + try { - // No template - insert default text. This is - // exactly what DefaultKeyTypedAction does. - else { - doDefaultInsert(rsta); - } + CodeTemplateManager manager = RSyntaxTextArea. + getCodeTemplateManager(); + CodeTemplate template = manager==null ? null : + manager.getTemplate(rsta); - } catch (BadLocationException ble) { - UIManager.getLookAndFeel(). - provideErrorFeedback(textArea); + // A non-null template means modify the text to insert! + if (template!=null) { + template.invoke(rsta); } + // No template - insert default text. This is + // exactly what DefaultKeyTypedAction does. + else { + doDefaultInsert(rsta); + } - } // End of if (doc!=null). + } catch (BadLocationException ble) { + UIManager.getLookAndFeel(). + provideErrorFeedback(textArea); + } } // End of if (textArea.getTemplatesEnabled()). diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java index 5995567c3..8af5f2c03 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java @@ -105,7 +105,7 @@ void changeBaseFont(Font oldFont, Font newFont) { for (Style style : styles) { if (style != null && style.font != null) { if (style.font.getFamily().equals(oldFont.getFamily()) && - style.font.getSize() == oldFont.getSize()) { + style.font.getSize2D() == oldFont.getSize2D()) { int styleFontStyle = style.font.getStyle(); // Keep bold or italic style.font = newFont.deriveFont(styleFontStyle); } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/FocusableTip.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/FocusableTip.java index 7f3574044..49ee6f601 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/FocusableTip.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/FocusableTip.java @@ -374,7 +374,7 @@ public void keyPressed(KeyEvent e) { } else if (e.getKeyCode()==KeyEvent.VK_F2) { if (tipWindow!=null && !tipWindow.getFocusableWindowState()) { - tipWindow.actionPerformed(null); + tipWindow.actionPerformed(); e.consume(); // Don't do bookmarking stuff } } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindow.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindow.java index 740cf4700..cd2f2b36b 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindow.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindow.java @@ -17,8 +17,6 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; @@ -54,7 +52,7 @@ * @author Robert Futrell * @version 1.0 */ -class TipWindow extends JWindow implements ActionListener { +class TipWindow extends JWindow { private FocusableTip ft; private JEditorPane textArea; @@ -130,9 +128,7 @@ public void keyPressed(KeyEvent e) { } - @Override - public void actionPerformed(ActionEvent e) { - + public void actionPerformed() { if (!getFocusableWindowState()) { setFocusableWindowState(true); setBottomPanel(); @@ -145,11 +141,8 @@ public void windowLostFocus(WindowEvent e) { } }); ft.removeListeners(); - if (e==null) { // Didn't get here via our mouseover timer - requestFocus(); - } + requestFocus(); } - } @@ -252,6 +245,11 @@ private static Border getReplacementForFlatLafBorder(Border border) { } + protected String getText() { + return textArea.getText(); + } + + private static Border getToolTipBorder() { Border border = TipUtil.getToolTipBorder(); @@ -375,7 +373,7 @@ private TipListener() { @Override public void mousePressed(MouseEvent e) { - actionPerformed(null); // Manually create "real" window + actionPerformed(); // Manually create "real" window } @Override diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.flex index b70532210..7d1c5251e 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.flex @@ -138,11 +138,7 @@ import org.fife.ui.rsyntaxtextarea.*; this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; - switch (initialTokenType) { - default: - state = Token.NULL; - } + int state = YYINITIAL; s = text; try { diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.java index 86ed54d71..f18a99d86 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMaker.java @@ -1463,11 +1463,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; - switch (initialTokenType) { - default: - state = Token.NULL; - } + int state = YYINITIAL; s = text; try { diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.flex index 0d154581d..77f13a1f1 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.flex @@ -69,7 +69,7 @@ import org.fife.ui.rsyntaxtextarea.*; * a nestable multi-line comment. The nested depth is embedded in the * actual end token type. */ - private static final int INTERNAL_IN_NESTABLE_MLC = -(1<<11); + static final int INTERNAL_IN_NESTABLE_MLC = -(1<<11); /** * When in a (possibly) nested MLC, this is the current nested depth. @@ -182,6 +182,7 @@ import org.fife.ui.rsyntaxtextarea.*; * @return The first Token in a linked list representing * the syntax highlighted text. */ + @Override public Token getTokenList(Segment text, int initialTokenType, int startOffset) { resetTokenList(); @@ -189,7 +190,7 @@ import org.fife.ui.rsyntaxtextarea.*; nestedMlcDepth = 0; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case Token.LITERAL_BACKQUOTE: state = WYSIWYG_STRING_2; @@ -535,7 +536,7 @@ URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?) {HexStringLiteral} { addToken(Token.LITERAL_STRING_DOUBLE_QUOTE); } {UnclosedHexStringLiteral} { addToken(Token.ERROR_STRING_DOUBLE); addNullToken(); return firstToken; } {WysiwygStringLiteralStart} { addToken(Token.LITERAL_STRING_DOUBLE_QUOTE); yybegin(WYSIWYG_STRING_1); } - {WysiwygStringLiteralStart2} { addToken(Token.LITERAL_BACKQUOTE); yybegin(WYSIWYG_STRING_2); } + {WysiwygStringLiteralStart2} { start = zzMarkedPos-1; yybegin(WYSIWYG_STRING_2); } /* Comment literals. */ "/**/" { addToken(Token.COMMENT_MULTILINE); } @@ -608,7 +609,6 @@ URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?) "/" {} "+/" { - System.out.println("... " + nestedMlcDepth); if (--nestedMlcDepth==0) { addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); yybegin(YYINITIAL); } @@ -648,12 +648,7 @@ URL = (((https?|f(tp|ile))"://"|"www.")({URLCharacters}{URLEndCharacter})?) } { - [^\`]+ { addToken(Token.LITERAL_BACKQUOTE); } - \` { addToken(Token.LITERAL_BACKQUOTE); yybegin(YYINITIAL); } - <> { - if (firstToken==null) { - addToken(Token.LITERAL_BACKQUOTE); - } - return firstToken; - } + [^\`]+ {} + \` { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_BACKQUOTE); } + <> { addToken(start,zzStartRead-1, Token.LITERAL_BACKQUOTE); return firstToken; } } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.java index d6334158e..051cc095e 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMaker.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.1 on 6/21/15 7:13 PM */ +/* The following code was generated by JFlex 1.4.1 on 10/6/24, 4:53 PM */ /* * 09/08/2014 @@ -100,22 +100,22 @@ public class DTokenMaker extends AbstractJFlexCTokenMaker { "\1\1\1\7\4\2\1\10\3\11\2\2\1\11\6\2"+ "\1\12\1\2\4\11\1\13\6\2\1\14\1\15\4\14"+ "\1\16\5\14\1\17\3\14\1\20\3\14\1\21\1\22"+ - "\1\23\1\24\1\25\1\1\1\2\2\26\1\27\1\3"+ - "\1\26\1\27\2\26\1\30\2\26\1\4\1\31\1\0"+ - "\1\4\16\2\2\6\1\22\13\2\1\6\1\32\1\2"+ - "\1\33\1\34\1\35\4\2\1\36\24\2\1\0\1\11"+ - "\1\13\4\2\3\36\10\2\3\0\1\37\4\0\1\40"+ - "\1\0\1\41\1\42\4\0\1\1\10\2\1\3\1\27"+ - "\1\0\4\30\1\3\1\4\1\43\1\31\2\4\1\31"+ - "\1\4\11\2\1\36\1\6\1\44\1\6\1\22\12\2"+ - "\2\6\2\2\1\45\1\46\37\2\1\1\6\2\1\47"+ - "\12\2\14\0\1\1\11\2\1\30\2\26\1\43\1\4"+ - "\2\2\1\47\4\2\1\44\1\6\2\2\2\6\1\2"+ - "\1\50\6\2\1\51\13\2\1\1\13\2\1\0\1\52"+ - "\2\0\1\53\2\0\1\54\1\0\1\1\10\2\1\4"+ - "\1\2\1\36\1\2\1\6\1\2\1\6\10\2\1\1"+ + "\1\23\1\14\1\24\1\1\1\2\2\25\1\26\1\3"+ + "\1\25\1\26\2\25\1\27\2\25\1\4\1\30\1\0"+ + "\1\4\16\2\2\6\1\22\13\2\1\6\1\31\1\2"+ + "\1\32\1\33\1\34\4\2\1\35\24\2\1\0\1\11"+ + "\1\13\4\2\3\35\10\2\3\0\1\36\4\0\1\37"+ + "\1\0\1\40\1\41\4\0\1\1\10\2\1\3\1\26"+ + "\1\0\4\27\1\3\1\4\1\42\1\30\2\4\1\30"+ + "\1\4\11\2\1\35\1\6\1\43\1\6\1\22\12\2"+ + "\2\6\2\2\1\44\1\45\37\2\1\1\6\2\1\46"+ + "\12\2\14\0\1\1\11\2\1\27\2\25\1\42\1\4"+ + "\2\2\1\46\4\2\1\43\1\6\2\2\2\6\1\2"+ + "\1\47\6\2\1\50\13\2\1\1\13\2\1\0\1\51"+ + "\2\0\1\52\2\0\1\53\1\0\1\1\10\2\1\4"+ + "\1\2\1\35\1\2\1\6\1\2\1\6\10\2\1\1"+ "\12\2\6\0\1\1\6\2\1\4\2\2\1\6\1\2"+ - "\1\6\1\55\2\2\1\1\12\2\1\36\1\6\1\2"+ + "\1\6\1\54\2\2\1\1\12\2\1\35\1\6\1\2"+ "\1\1\21\2"; private static int [] zzUnpackAction() { @@ -1273,7 +1273,7 @@ the source of the yytext() string */ * a nestable multi-line comment. The nested depth is embedded in the * actual end token type. */ - private static final int INTERNAL_IN_NESTABLE_MLC = -(1<<11); + static final int INTERNAL_IN_NESTABLE_MLC = -(1<<11); /** * When in a (possibly) nested MLC, this is the current nested depth. @@ -1394,7 +1394,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { nestedMlcDepth = 0; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case Token.LITERAL_BACKQUOTE: state = WYSIWYG_STRING_2; @@ -1708,186 +1708,182 @@ else if (zzAtEOF) { case 14: { yybegin(YYINITIAL); addToken(start,zzEndRead, Token.COMMENT_DOCUMENTATION); return firstToken; } - case 46: break; + case 45: break; case 2: { addToken(Token.IDENTIFIER); } - case 47: break; - case 41: + case 46: break; + case 40: { addToken(Token.LITERAL_BOOLEAN); } - case 48: break; - case 25: + case 47: break; + case 24: { addToken(Token.ERROR_CHAR); } - case 49: break; - case 22: + case 48: break; + case 21: { addToken(Token.ERROR_NUMBER_FORMAT); } - case 50: break; + case 49: break; case 4: { addToken(Token.ERROR_CHAR); addNullToken(); return firstToken; } - case 51: break; + case 50: break; case 18: { addToken(Token.LITERAL_STRING_DOUBLE_QUOTE); } - case 52: break; + case 51: break; case 11: { addToken(Token.ANNOTATION); } - case 53: break; + case 52: break; case 6: { addToken(Token.ERROR_STRING_DOUBLE); addNullToken(); return firstToken; } - case 54: break; + case 53: break; case 1: { addToken(Token.ERROR_IDENTIFIER); } - case 55: break; - case 20: - { addToken(Token.LITERAL_BACKQUOTE); - } - case 56: break; - case 33: + case 54: break; + case 32: { nestedMlcDepth++; } - case 57: break; - case 37: + case 55: break; + case 36: { start = zzMarkedPos-3; yybegin(EOL_DOCCOMMENT); } - case 58: break; - case 43: + case 56: break; + case 42: { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_DOCUMENTATION); start = zzMarkedPos; } - case 59: break; - case 35: + case 57: break; + case 34: { addToken(Token.LITERAL_CHAR); } - case 60: break; - case 24: + case 58: break; + case 23: { addToken(Token.LITERAL_NUMBER_HEXADECIMAL); } - case 61: break; - case 28: + case 59: break; + case 27: { start = zzMarkedPos-2; yybegin(MLC); } - case 62: break; + case 60: break; case 17: { addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addNullToken(); return firstToken; } - case 63: break; + case 61: break; case 7: { addToken(Token.WHITESPACE); } - case 64: break; - case 32: + case 62: break; + case 31: { yybegin(YYINITIAL); addToken(start,zzStartRead+1, Token.COMMENT_DOCUMENTATION); } - case 65: break; - case 39: + case 63: break; + case 38: { addToken(Token.DATA_TYPE); } - case 66: break; - case 34: - { System.out.println("... " + nestedMlcDepth); - if (--nestedMlcDepth==0) { - addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); yybegin(YYINITIAL); - } - } - case 67: break; - case 31: + case 64: break; + case 30: { yybegin(YYINITIAL); addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); } - case 68: break; - case 21: - { addToken(Token.LITERAL_BACKQUOTE); yybegin(YYINITIAL); - } - case 69: break; + case 65: break; case 3: { addToken(Token.LITERAL_NUMBER_DECIMAL_INT); } - case 70: break; + case 66: break; case 19: { addToken(Token.LITERAL_STRING_DOUBLE_QUOTE); yybegin(YYINITIAL); } - case 71: break; - case 38: + case 67: break; + case 8: + { start = zzMarkedPos-1; yybegin(WYSIWYG_STRING_2); + } + case 68: break; + case 20: + { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_BACKQUOTE); + } + case 69: break; + case 37: { start = zzMarkedPos-3; yybegin(DOCCOMMENT); } - case 72: break; + case 70: break; case 15: { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addNestedMlcEndToken(); return firstToken; } - case 73: break; - case 30: + case 71: break; + case 29: { addToken(Token.RESERVED_WORD); } - case 74: break; - case 42: + case 72: break; + case 41: { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_MULTILINE); start = zzMarkedPos; } - case 75: break; - case 29: + case 73: break; + case 28: { start = zzMarkedPos-2; nestedMlcDepth = 1; yybegin(NESTABLE_MLC); } - case 76: break; - case 45: + case 74: break; + case 44: { addToken(Token.RESERVED_WORD_2); } - case 77: break; + case 75: break; case 16: { addToken(start,zzStartRead-1, Token.COMMENT_EOL); addNullToken(); return firstToken; } - case 78: break; + case 76: break; case 10: { addToken(Token.SEPARATOR); } - case 79: break; + case 77: break; + case 33: + { + if (--nestedMlcDepth==0) { + addToken(start,zzStartRead+1, Token.COMMENT_MULTILINE); yybegin(YYINITIAL); + } + } + case 78: break; case 5: { addNullToken(); return firstToken; } - case 80: break; + case 79: break; case 13: { addToken(start,zzStartRead-1, Token.COMMENT_MULTILINE); return firstToken; } - case 81: break; - case 8: - { addToken(Token.LITERAL_BACKQUOTE); yybegin(WYSIWYG_STRING_2); - } - case 82: break; + case 80: break; case 9: { addToken(Token.OPERATOR); } - case 83: break; - case 23: + case 81: break; + case 22: { addToken(Token.LITERAL_NUMBER_FLOAT); } - case 84: break; - case 26: + case 82: break; + case 25: { addToken(Token.LITERAL_STRING_DOUBLE_QUOTE); yybegin(WYSIWYG_STRING_1); } - case 85: break; - case 44: + case 83: break; + case 43: { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_EOL); addHyperlinkToken(temp,zzMarkedPos-1, Token.COMMENT_EOL); start = zzMarkedPos; } - case 86: break; - case 40: + case 84: break; + case 39: { addToken(Token.COMMENT_MULTILINE); } - case 87: break; - case 27: + case 85: break; + case 26: { start = zzMarkedPos-2; yybegin(EOL_COMMENT); } - case 88: break; - case 36: - { addToken(Token.ERROR_STRING_DOUBLE); - } - case 89: break; + case 86: break; case 12: { } - case 90: break; + case 87: break; + case 35: + { addToken(Token.ERROR_STRING_DOUBLE); + } + case 88: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; @@ -1920,10 +1916,7 @@ else if (zzAtEOF) { } case 465: break; case WYSIWYG_STRING_2: { - if (firstToken==null) { - addToken(Token.LITERAL_BACKQUOTE); - } - return firstToken; + addToken(start,zzStartRead-1, Token.LITERAL_BACKQUOTE); return firstToken; } case 466: break; case EOL_DOCCOMMENT: { diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.flex index 303fa4c6f..87bfaac6c 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.flex @@ -73,22 +73,22 @@ import org.fife.ui.rsyntaxtextarea.*; /** * Token type specifying we're in an invalid multi-line JS string. */ - private static final int INTERNAL_IN_JS_STRING_INVALID = -10; + static final int INTERNAL_IN_JS_STRING_INVALID = -10; /** * Token type specifying we're in a valid multi-line JS string. */ - private static final int INTERNAL_IN_JS_STRING_VALID = -11; + static final int INTERNAL_IN_JS_STRING_VALID = -11; /** * Token type specifying we're in an invalid multi-line JS single-quoted string. */ - private static final int INTERNAL_IN_JS_CHAR_INVALID = -12; + static final int INTERNAL_IN_JS_CHAR_INVALID = -12; /** * Token type specifying we're in a valid multi-line JS single-quoted string. */ - private static final int INTERNAL_IN_JS_CHAR_VALID = -13; + static final int INTERNAL_IN_JS_CHAR_VALID = -13; /** * When in the JS_STRING state, whether the current string is valid. @@ -236,7 +236,7 @@ import org.fife.ui.rsyntaxtextarea.*; int languageIndex = LANG_INDEX_DEFAULT; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case Token.LITERAL_STRING_DOUBLE_QUOTE: state = DART_MULTILINE_STRING_DOUBLE; @@ -262,7 +262,7 @@ import org.fife.ui.rsyntaxtextarea.*; state = JS_CHAR; break; default: - state = YYINITIAL; // ??? + state = YYINITIAL; break; } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.java index f06620f76..3cbf0d907 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMaker.java @@ -1432,22 +1432,22 @@ the source of the yytext() string */ /** * Token type specifying we're in an invalid multi-line JS string. */ - private static final int INTERNAL_IN_JS_STRING_INVALID = -10; + static final int INTERNAL_IN_JS_STRING_INVALID = -10; /** * Token type specifying we're in a valid multi-line JS string. */ - private static final int INTERNAL_IN_JS_STRING_VALID = -11; + static final int INTERNAL_IN_JS_STRING_VALID = -11; /** * Token type specifying we're in an invalid multi-line JS single-quoted string. */ - private static final int INTERNAL_IN_JS_CHAR_INVALID = -12; + static final int INTERNAL_IN_JS_CHAR_INVALID = -12; /** * Token type specifying we're in a valid multi-line JS single-quoted string. */ - private static final int INTERNAL_IN_JS_CHAR_VALID = -13; + static final int INTERNAL_IN_JS_CHAR_VALID = -13; /** * When in the JS_STRING state, whether the current string is valid. @@ -1596,7 +1596,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { int languageIndex = LANG_INDEX_DEFAULT; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case Token.LITERAL_STRING_DOUBLE_QUOTE: state = DART_MULTILINE_STRING_DOUBLE; @@ -1622,7 +1622,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { state = JS_CHAR; break; default: - state = YYINITIAL; // ??? + state = YYINITIAL; break; } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.flex index 003c6d11e..604c8a2e6 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.flex @@ -179,7 +179,7 @@ import org.fife.ui.rsyntaxtextarea.*; this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.COMMENT_MULTILINE: state = MLC; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.java index 563cc1044..99b3d57ac 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMaker.java @@ -1149,7 +1149,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.COMMENT_MULTILINE: state = MLC; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex index 2241acbe4..d9c6af19a 100644 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.flex @@ -205,16 +205,6 @@ import org.fife.ui.rsyntaxtextarea.*; */ static final int INTERNAL_IN_HB_MLC_2 = -(6<<11); - /** - * Token type specifying we're in a Handlebars multiline string. - */ - static final int INTERNAL_IN_HB_STRING = -(7<<11); - - /** - * Token type specifying we're in a Handlebars multiline char. - */ - static final int INTERNAL_IN_HB_CHAR = -(8<<11); - /** * The state previous CSS-related state we were in before going into a CSS * string, multi-line comment, etc. @@ -541,18 +531,6 @@ import org.fife.ui.rsyntaxtextarea.*; hbInState = -initialTokenType&0xff; hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; break; - case INTERNAL_IN_HB_CHAR: - state = HB_CHAR_LITERAL; - languageIndex = LANG_INDEX_HANDLEBARS; - hbInState = -initialTokenType&0xff; - hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; - break; - case INTERNAL_IN_HB_STRING: - state = HB_STRING; - languageIndex = LANG_INDEX_HANDLEBARS; - hbInState = -initialTokenType&0xff; - hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; - break; case INTERNAL_IN_HB_MLC_1: state = HB_COMMENT_1; languageIndex = LANG_INDEX_HANDLEBARS; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java index c04c3908e..99cc9efd0 100644 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HandlebarsTokenMaker.java @@ -2158,16 +2158,6 @@ the source of the yytext() string */ */ static final int INTERNAL_IN_HB_MLC_2 = -(6<<11); - /** - * Token type specifying we're in a Handlebars multiline string. - */ - static final int INTERNAL_IN_HB_STRING = -(7<<11); - - /** - * Token type specifying we're in a Handlebars multiline char. - */ - static final int INTERNAL_IN_HB_CHAR = -(8<<11); - /** * The state previous CSS-related state we were in before going into a CSS * string, multi-line comment, etc. @@ -2494,18 +2484,6 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { hbInState = -initialTokenType&0xff; hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; break; - case INTERNAL_IN_HB_CHAR: - state = HB_CHAR_LITERAL; - languageIndex = LANG_INDEX_HANDLEBARS; - hbInState = -initialTokenType&0xff; - hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; - break; - case INTERNAL_IN_HB_STRING: - state = HB_STRING; - languageIndex = LANG_INDEX_HANDLEBARS; - hbInState = -initialTokenType&0xff; - hbInLangIndex = (-initialTokenType&0x00ff0000)>>16; - break; case INTERNAL_IN_HB_MLC_1: state = HB_COMMENT_1; languageIndex = LANG_INDEX_HANDLEBARS; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.flex index ed88cc29a..59180820a 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.flex @@ -182,7 +182,7 @@ import org.fife.ui.rsyntaxtextarea.*; this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case INTERNAL_ATTR_DOUBLE: state = INATTR_DOUBLE; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.java index 7a376088d..496a83f0a 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/HtaccessTokenMaker.java @@ -1092,7 +1092,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case INTERNAL_ATTR_DOUBLE: state = INATTR_DOUBLE; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.flex index c7da42ddd..d117f37a3 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.flex @@ -123,13 +123,13 @@ import org.fife.ui.rsyntaxtextarea.*; /** * Token type specifying we're in a JSP hidden comment ("<%-- ... --%>"). */ - private static final int INTERNAL_IN_HIDDEN_COMMENT = -10; + static final int INTERNAL_IN_HIDDEN_COMMENT = -10; /** * Token type specifying we're in a JSP directive (either include, page * or taglib). */ - private static final int INTERNAL_IN_JSP_DIRECTIVE = -11; + static final int INTERNAL_IN_JSP_DIRECTIVE = -11; /** * Token type specifying we're in JavaScript. @@ -413,7 +413,7 @@ import org.fife.ui.rsyntaxtextarea.*; int languageIndex = 0; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.MARKUP_COMMENT: state = COMMENT; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.java index 5d9ff68ed..533b51129 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JSPTokenMaker.java @@ -1,10 +1,6 @@ /* The following code was generated by JFlex 1.4.1 on 6/9/20 10:42 PM */ /* - * 02/11/2008 - * - * JSPTokenMaker.java - Generates tokens for JSP syntax highlighting. - * * This library is distributed under a modified BSD license. See the included * LICENSE file for details. */ @@ -6596,13 +6592,13 @@ the source of the yytext() string */ /** * Token type specifying we're in a JSP hidden comment ("<%-- ... --%>"). */ - private static final int INTERNAL_IN_HIDDEN_COMMENT = -10; + static final int INTERNAL_IN_HIDDEN_COMMENT = -10; /** * Token type specifying we're in a JSP directive (either include, page * or taglib). */ - private static final int INTERNAL_IN_JSP_DIRECTIVE = -11; + static final int INTERNAL_IN_JSP_DIRECTIVE = -11; /** * Token type specifying we're in JavaScript. @@ -6853,9 +6849,8 @@ public boolean getMarkOccurrencesOfTokenType(int type) { */ @Override public boolean getShouldIndentNextLineAfter(Token token) { - int languageIndex = token==null ? 0 : token.getLanguageIndex(); - if (getCurlyBracesDenoteCodeBlocks(languageIndex)) { - if (token!=null && token.length()==1) { + if (token != null && getCurlyBracesDenoteCodeBlocks(token.getLanguageIndex())) { + if (token.length() == 1) { char ch = token.charAt(0); return ch=='{' || ch=='('; } @@ -6886,7 +6881,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { int languageIndex = 0; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.MARKUP_COMMENT: state = COMMENT; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JavaScriptTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JavaScriptTokenMaker.java index 1ec88c01e..09cfcac20 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JavaScriptTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/JavaScriptTokenMaker.java @@ -1165,7 +1165,7 @@ the source of the yytext() string */ static final int INTERNAL_E4X_MARKUP_PROCESSING_INSTRUCTION = -16; - static final int INTERNAL_E4X_COMMENT = -17; + static final int INTERNAL_E4X_COMMENT = -(1<<11); static final int INTERNAL_E4X_DTD = -18; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.flex index 18c50e949..0640dce31 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.flex @@ -179,7 +179,7 @@ import org.fife.ui.rsyntaxtextarea.*; this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.LITERAL_STRING_DOUBLE_QUOTE: state = STRING; @@ -214,7 +214,7 @@ import org.fife.ui.rsyntaxtextarea.*; start = text.offset; break; default: - state = Token.NULL; + state = YYINITIAL; } s = text; @@ -692,11 +692,11 @@ ErrorIdentifier = ({NonSeparator}+) { [^\n\\\$\@\%\"]+ {} - \n { addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); return firstToken; } \\.? { /* Skip escaped chars. */ } {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; } {VariableStart} {} \" { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_STRING_DOUBLE_QUOTE); } + \n | <> { addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); return firstToken; } } @@ -704,19 +704,19 @@ ErrorIdentifier = ({NonSeparator}+) { [^\n\\\']+ {} \\.? { /* Skip escaped single quotes only, but this should still work. */ } - \n { addToken(start,zzStartRead-1, Token.LITERAL_CHAR); return firstToken; } \' { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_CHAR); } + \n | <> { addToken(start,zzStartRead-1, Token.LITERAL_CHAR); return firstToken; } } { [^\n\\\$\@\%\`]+ {} - \n { addToken(start,zzStartRead-1, Token.LITERAL_BACKQUOTE); return firstToken; } \\.? { /* Skip escaped chars. */ } {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.LITERAL_BACKQUOTE); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; } {VariableStart} {} \` { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_BACKQUOTE); } + \n | <> { addToken(start,zzStartRead-1, Token.LITERAL_BACKQUOTE); return firstToken; } } @@ -733,10 +733,10 @@ ErrorIdentifier = ({NonSeparator}+) /* syntactic rules. */ "EOF" { if (start==zzStartRead) { addToken(Token.PREPROCESSOR); addNullToken(); return firstToken; } } [^\n\\\$\@\%]+ {} - \n { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOF_UNQUOTED); return firstToken; } \\.? { /* Skip escaped chars. */ } {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.PREPROCESSOR); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; } {VariableStart} {} + \n | <> { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOF_UNQUOTED); return firstToken; } } @@ -750,8 +750,8 @@ ErrorIdentifier = ({NonSeparator}+) /* EOF and any other chars. */ "EOF" { if (start==zzStartRead) { addToken(Token.PREPROCESSOR); addNullToken(); return firstToken; } } [^\n\\]+ {} - \n { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOF_SINGLE_QUOTED); return firstToken; } \\.? { /* Skip escaped chars. */ } + \n | <> { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOF_SINGLE_QUOTED); return firstToken; } } @@ -768,10 +768,10 @@ ErrorIdentifier = ({NonSeparator}+) /* syntactic rules. */ "EOT" { if (start==zzStartRead) { addToken(Token.PREPROCESSOR); addNullToken(); return firstToken; } } [^\n\\\$\@\%]+ {} - \n { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOT_UNQUOTED); return firstToken; } \\.? { /* Skip escaped chars. */ } {Variable} { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.PREPROCESSOR); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; } {VariableStart} {} + \n | <> { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOT_UNQUOTED); return firstToken; } } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.java index c0b5bff7b..4deab5b4c 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/PerlTokenMaker.java @@ -1503,7 +1503,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { this.offsetShift = -text.offset + startOffset; // Start off in the proper state. - int state = Token.NULL; + int state; switch (initialTokenType) { case Token.LITERAL_STRING_DOUBLE_QUOTE: state = STRING; @@ -1538,7 +1538,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { start = text.offset; break; default: - state = Token.NULL; + state = YYINITIAL; } s = text; @@ -1874,117 +1874,117 @@ else if (zzAtEOF) { { addToken(Token.FUNCTION); } case 52: break; - case 36: - { boolean highlightedAsRegex = false; - if (firstToken==null) { - addToken(Token.REGEX); - highlightedAsRegex = true; - } - else { - // If this is *likely* to be a regex, based on - // the previous token, highlight it as such. - Token t = firstToken.getLastNonCommentNonWhitespaceToken(); - if (regexCanFollow(t)) { - addToken(Token.REGEX); - highlightedAsRegex = true; - } - } - // If it doesn't *appear* to be a regex, highlight it as - // individual tokens. - if (!highlightedAsRegex) { - int temp = zzStartRead + 1; - addToken(zzStartRead, zzStartRead, Token.OPERATOR); - zzStartRead = zzCurrentPos = zzMarkedPos = temp; - } - } - case 53: break; case 30: { addToken(Token.VARIABLE); } - case 54: break; + case 53: break; case 1: { addToken(Token.ERROR_IDENTIFIER); } - case 55: break; + case 54: break; case 24: { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOT_SINGLE_QUOTED); return firstToken; } - case 56: break; + case 55: break; case 4: { addToken(Token.COMMENT_EOL); addNullToken(); return firstToken; } - case 57: break; + case 56: break; case 29: { addToken(Token.PREPROCESSOR); addNullToken(); return firstToken; } - case 58: break; + case 57: break; case 41: { if (start==zzStartRead) { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.COMMENT_DOCUMENTATION); addToken(temp,zzMarkedPos-1, Token.COMMENT_EOL); start = zzMarkedPos; } } - case 59: break; + case 58: break; case 44: { start = zzStartRead; yybegin(HEREDOC_EOF_SINGLE_QUOTED); } - case 60: break; + case 59: break; case 45: { start = zzStartRead; yybegin(HEREDOC_EOT_SINGLE_QUOTED); } - case 61: break; + case 60: break; case 42: { start = zzStartRead; yybegin(HEREDOC_EOF_UNQUOTED); } - case 62: break; + case 61: break; case 13: { /* Skip escaped chars. */ } - case 63: break; + case 62: break; case 37: { addToken(Token.REGEX); } - case 64: break; + case 63: break; case 18: { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_CHAR); } - case 65: break; + case 64: break; case 28: { addToken(Token.LITERAL_NUMBER_HEXADECIMAL); } - case 66: break; + case 65: break; case 21: { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOF_UNQUOTED); return firstToken; } - case 67: break; + case 66: break; case 6: { addToken(Token.WHITESPACE); } - case 68: break; + case 67: break; case 10: { start = zzMarkedPos-1; yybegin(CHAR_LITERAL); } - case 69: break; + case 68: break; case 3: { addToken(Token.LITERAL_NUMBER_DECIMAL_INT); } - case 70: break; + case 69: break; case 33: { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.LITERAL_STRING_DOUBLE_QUOTE); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; } - case 71: break; + case 70: break; case 20: { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_BACKQUOTE); } - case 72: break; + case 71: break; case 15: { yybegin(YYINITIAL); addToken(start,zzStartRead, Token.LITERAL_STRING_DOUBLE_QUOTE); } - case 73: break; + case 72: break; case 16: { /* Skip escaped single quotes only, but this should still work. */ } - case 74: break; + case 73: break; case 23: { addToken(start,zzStartRead-1, Token.PREPROCESSOR); addEndToken(INTERNAL_HEREDOC_EOT_UNQUOTED); return firstToken; } + case 74: break; + case 36: + { boolean highlightedAsRegex = false; + if (firstToken==null) { + addToken(Token.REGEX); + highlightedAsRegex = true; + } + else { + // If this is *likely* to be a regex, based on + // the previous token, highlight it as such. + Token t = firstToken.getLastNonCommentNonWhitespaceToken(); + if (regexCanFollow(t)) { + addToken(Token.REGEX); + highlightedAsRegex = true; + } + } + // If it doesn't *appear* to be a regex, highlight it as + // individual tokens. + if (!highlightedAsRegex) { + int temp = zzStartRead + 1; + addToken(zzStartRead, zzStartRead, Token.OPERATOR); + zzStartRead = zzCurrentPos = zzMarkedPos = temp; + } + } case 75: break; case 35: { int temp=zzStartRead; addToken(start,zzStartRead-1, Token.PREPROCESSOR); addToken(temp,zzMarkedPos-1, Token.VARIABLE); start = zzMarkedPos; diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.flex b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.flex index 10bd6a622..8542bfad3 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.flex +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.flex @@ -99,7 +99,7 @@ import org.fife.ui.rsyntaxtextarea.*; static final int INTERNAL_E4X_MARKUP_PROCESSING_INSTRUCTION = -16; - static final int INTERNAL_IN_E4X_COMMENT = -17; + static final int INTERNAL_IN_E4X_COMMENT = -(1<<11); static final int INTERNAL_E4X_DTD = -18; @@ -282,7 +282,7 @@ import org.fife.ui.rsyntaxtextarea.*; int languageIndex = LANG_INDEX_DEFAULT; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case INTERNAL_IN_JS_MLC: state = JS_MLC; @@ -358,8 +358,8 @@ import org.fife.ui.rsyntaxtextarea.*; e4x_prevState = -initialTokenType&0xff; languageIndex = LANG_INDEX_E4X; } - else { // Shouldn't happen - state = Token.NULL; + else { + state = YYINITIAL; } } diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.java index a7c40baff..4454896d0 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/modes/TypeScriptTokenMaker.java @@ -1178,7 +1178,7 @@ the source of the yytext() string */ static final int INTERNAL_E4X_MARKUP_PROCESSING_INSTRUCTION = -16; - static final int INTERNAL_IN_E4X_COMMENT = -17; + static final int INTERNAL_IN_E4X_COMMENT = -(1<<11); static final int INTERNAL_E4X_DTD = -18; @@ -1361,7 +1361,7 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { int languageIndex = LANG_INDEX_DEFAULT; // Start off in the proper state. - int state = YYINITIAL; + int state; switch (initialTokenType) { case INTERNAL_IN_JS_MLC: state = JS_MLC; @@ -1437,8 +1437,8 @@ public Token getTokenList(Segment text, int initialTokenType, int startOffset) { e4x_prevState = -initialTokenType&0xff; languageIndex = LANG_INDEX_E4X; } - else { // Shouldn't happen - state = Token.NULL; + else { + state = YYINITIAL; } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/TestUtil.java b/RSyntaxTextArea/src/test/java/org/fife/TestUtil.java new file mode 100644 index 000000000..1741bcef9 --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/TestUtil.java @@ -0,0 +1,86 @@ +/** + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife; + +import org.fife.io.UnicodeWriter; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; + + +/** + * Utility methods for unit tests. + */ +public final class TestUtil { + + private static String DEFAULT_TEMP_FILE_EXTENSION = ".tmp"; + + + /** + * Private constructor to prevent instantiation. + */ + private TestUtil() { + // Do nothing + } + + + /** + * Creates a temporary file with extension {@code ".tmp"}. + * + * @param content The content of the file. + * @return The file. + * @throws IOException If an IO error occurs. + * @see #createFile(String, String) + * @see #createFile(String, String, File) + */ + public static File createFile(String content) throws IOException { + return createFile(DEFAULT_TEMP_FILE_EXTENSION, content); + } + + + /** + * Creates a temporary file. + * + * @param fileExtension The extension for the file. + * @param content The content of the file. + * @return The file. + * @throws IOException If an IO error occurs. + * @see #createFile(String) + * @see #createFile(String, String, File) + */ + public static File createFile(String fileExtension, String content) throws IOException { + File file = File.createTempFile("unitTest", fileExtension); + file.deleteOnExit(); + UnicodeWriter uw = new UnicodeWriter(file, "UTF-8"); + try (PrintWriter w = new PrintWriter(uw)) { + w.println(content); + } + return file; + } + + + /** + * Creates a temporary file. + * + * @param fileExtension The extension for the file. + * @param content The content of the file. + * @param directory The parent directory for the file. + * @return The file. + * @throws IOException If an IO error occurs. + * @see #createFile(String) + * @see #createFile(String, String) + */ + public static File createFile(String fileExtension, String content, File directory) + throws IOException { + File file = File.createTempFile("unitTest", fileExtension, directory); + file.deleteOnExit(); + UnicodeWriter uw = new UnicodeWriter(file, "UTF-8"); + try (PrintWriter w = new PrintWriter(uw)) { + w.println(content); + } + return file; + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManagerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManagerTest.java index a83e26a8b..08ff72a6e 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManagerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/CodeTemplateManagerTest.java @@ -4,7 +4,7 @@ */ package org.fife.ui.rsyntaxtextarea; - +import org.fife.TestUtil; import org.fife.ui.rsyntaxtextarea.templates.CodeTemplate; import org.fife.ui.rsyntaxtextarea.templates.StaticCodeTemplate; import org.junit.jupiter.api.Assertions; @@ -101,6 +101,7 @@ void testRemoveTemplate_codeTemplateArg_happyPath_found() { CodeTemplateManager manager = new CodeTemplateManager(); CodeTemplate template = new StaticCodeTemplate("id", "foo", "bar"); manager.addTemplate(template); + Assertions.assertEquals(1, manager.getTemplates().length); Assertions.assertTrue(manager.removeTemplate(template)); Assertions.assertEquals(0, manager.getTemplates().length); } @@ -129,6 +130,41 @@ void testReplaceTemplates() { } + @Test + void testSaveTemplates_nullDirectory() { + CodeTemplateManager manager = new CodeTemplateManager(); + Assertions.assertFalse(manager.saveTemplates()); + } + + + @Test + void testSaveTemplates_directoryDoesNotExist() throws IOException { + CodeTemplateManager manager = new CodeTemplateManager(); + // Because we ensure the directory exists when setting it, this + // can only happen if the directory is removed out form under us. + Path tempDir = Files.createTempDirectory("testDir"); + manager.setTemplateDirectory(tempDir.toFile()); + Files.delete(tempDir); + Assertions.assertFalse(manager.saveTemplates()); + } + + + @Test + void testSaveTemplates_deletesOldFiles() throws IOException { + + CodeTemplateManager manager = new CodeTemplateManager(); + + File tempDir = Files.createTempDirectory("testDir").toFile(); + manager.setTemplateDirectory(tempDir); + + File oldFile = TestUtil.createFile( + ".xml", "", tempDir); + + manager.saveTemplates(); + Assertions.assertEquals(0, tempDir.listFiles().length); + } + + @Test void testSetTemplateDirectory_dirExists() throws IOException { @@ -147,6 +183,17 @@ void testSetTemplateDirectory_dirExists() throws IOException { } + @Test + void testSetTemplateDirectory_dirExists_xmlFileThatIsNotACodeTemplate() throws IOException { + + CodeTemplateManager manager = new CodeTemplateManager(); + File file = TestUtil.createFile(".xml", ""); + + // The non-template XML file is ignored. + Assertions.assertEquals(0, manager.setTemplateDirectory(file.getParentFile())); + } + + @Test void testSetTemplateDirectory_dirDoesNotExist() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ErrorStripTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ErrorStripTest.java index 91343f05c..a2ad7a79f 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ErrorStripTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ErrorStripTest.java @@ -9,6 +9,7 @@ import org.fife.ui.rtextarea.SmartHighlightPainter; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -63,18 +64,44 @@ void testDoLayout() { } @Test - void testGetSetCaretMarkerColor() { + void testGetSetCaretMarkerColor_darkForeground() { Assertions.assertEquals(Color.BLACK, strip.getCaretMarkerColor()); strip.setCaretMarkerColor(Color.RED); Assertions.assertEquals(Color.RED, strip.getCaretMarkerColor()); } + @Test + void testGetSetCaretMarkerColor_nullDoesNothing() { + Assertions.assertEquals(Color.BLACK, strip.getCaretMarkerColor()); + strip.setCaretMarkerColor(null); + Assertions.assertEquals(Color.BLACK, strip.getCaretMarkerColor()); + } + + @Test + @Disabled("Can't set up LookAndFeel where this will have light FG early enough") + void testGetSetCaretMarkerColor_lightForeground() { + strip.setForeground(Color.WHITE); + Assertions.assertEquals(createTextArea().getCaretColor(), strip.getCaretMarkerColor()); + strip.setCaretMarkerColor(Color.RED); + Assertions.assertEquals(Color.RED, strip.getCaretMarkerColor()); + } + + @Test + void testGetSetCaretMarkerOnTop() { + Assertions.assertFalse(strip.isCaretMarkerOnTop()); + strip.setCaretMarkerOnTop(true); + Assertions.assertTrue(strip.isCaretMarkerOnTop()); + } + @Test void testGetSetFollowCaret() { Assertions.assertTrue(strip.getFollowCaret()); strip.setFollowCaret(false); Assertions.assertFalse(strip.getFollowCaret()); + // Repeating the same value does nothing + strip.setFollowCaret(false); + Assertions.assertFalse(strip.getFollowCaret()); } @@ -91,6 +118,9 @@ void testGetSetShowMarkAll() { Assertions.assertTrue(strip.getShowMarkAll()); strip.setShowMarkAll(false); Assertions.assertFalse(strip.getShowMarkAll()); + // Calling again with the same value does nothing + strip.setShowMarkAll(false); + Assertions.assertFalse(strip.getShowMarkAll()); } @@ -99,6 +129,9 @@ void testGetSetShowMarkedOccurrences() { Assertions.assertTrue(strip.getShowMarkedOccurrences()); strip.setShowMarkedOccurrences(false); Assertions.assertFalse(strip.getShowMarkedOccurrences()); + // Calling again with the same values does nothing + strip.setShowMarkedOccurrences(false); + Assertions.assertFalse(strip.getShowMarkedOccurrences()); } @@ -125,7 +158,17 @@ void testGetToolTipText_invalidMouseEvent() { @Test void testPaint() { + strip.addNotify(); + strip.setSize(strip.getPreferredSize()); + strip.doLayout(); + Graphics g = createTestGraphics(); + strip.paint(g); + } + + @Test + void testPaint_paintCaretMarkerOnTop() { + strip.setCaretMarkerOnTop(true); strip.addNotify(); strip.setSize(strip.getPreferredSize()); strip.doLayout(); @@ -160,7 +203,11 @@ public ParseResult parse(RSyntaxDocument doc, String style) { // Note some notices on the same line result.addNotice(new DefaultParserNotice(this, "test notice", 1)); result.addNotice(new DefaultParserNotice(this, "second notice", 1)); - result.addNotice(new DefaultParserNotice(this, "third notice", 2)); + DefaultParserNotice thirdNotice = + new DefaultParserNotice(this, "third notice", 2); + thirdNotice.setColor(null); + result.addNotice(thirdNotice); + return result; } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ParserManagerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ParserManagerTest.java index 18d29e686..9a14e8bee 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ParserManagerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/ParserManagerTest.java @@ -7,11 +7,10 @@ import org.fife.ui.SwingRunnerExtension; import org.fife.ui.rsyntaxtextarea.parser.*; import org.fife.ui.rtextarea.RTextScrollPane; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; @@ -27,43 +26,34 @@ @ExtendWith(SwingRunnerExtension.class) class ParserManagerTest extends AbstractRSyntaxTextAreaTest { - private boolean origDebugParsing; - - @BeforeEach - void setUp() { - origDebugParsing = Boolean.getBoolean(ParserManager.PROPERTY_DEBUG_PARSING); - System.setProperty(ParserManager.PROPERTY_DEBUG_PARSING, "true"); - } - - - @AfterEach - void tearDown() { - System.setProperty(ParserManager.PROPERTY_DEBUG_PARSING, Boolean.toString(origDebugParsing)); - } - - - @Test - void testConstructor_oneArg() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testConstructor_oneArg(String debugParsing) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); Assertions.assertEquals(1250, manager.getDelay()); } - @Test - void testConstructor_twoArg() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testConstructor_twoArg(String debugParsing) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(2000, textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); Assertions.assertEquals(2000, manager.getDelay()); } - @Test - void testActionPerformed_noParsers() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testActionPerformed_noParsers(String debugParsing) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); Assertions.assertEquals(0, manager.getParserNotices().size()); manager.actionPerformed(new ActionEvent(textArea, 0, null)); @@ -71,8 +61,9 @@ void testActionPerformed_noParsers() { } - @Test - void testActionPerformed_parsersFireChangeEvents() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testActionPerformed_parsersFireChangeEvents(String debugParsing) { AbstractParser parser = new AbstractParser() { @Override @@ -86,6 +77,7 @@ public ParseResult parse(RSyntaxDocument doc, String style) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); manager.addParser(parser); Assertions.assertEquals(0, manager.getParserNotices().size()); @@ -95,11 +87,13 @@ public ParseResult parse(RSyntaxDocument doc, String style) { } - @Test - void testAddRemoveParser() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testAddRemoveParser(String debugParsing) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); Assertions.assertEquals(0, manager.getParserCount()); @@ -118,8 +112,9 @@ public ParseResult parse(RSyntaxDocument doc, String style) { } - @Test - void testClearParsers() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testClearParsers(String debugParsing) { AbstractParser parser = new AbstractParser() { @Override @@ -133,6 +128,7 @@ public ParseResult parse(RSyntaxDocument doc, String style) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); manager.addParser(parser); Assertions.assertEquals(1, manager.getParserCount()); @@ -146,8 +142,9 @@ public ParseResult parse(RSyntaxDocument doc, String style) { } - @Test - void testForceReparsing_parsersFireChangeEvents() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testForceReparsing_parsersFireChangeEvents(String debugParsing) { boolean[] parserNoticeChangeEventFired = { false }; @@ -167,14 +164,66 @@ public ParseResult parse(RSyntaxDocument doc, String style) { PropertyChangeListener listener = evt -> parserNoticeChangeEventFired[0] = true; textArea.addPropertyChangeListener(RSyntaxTextArea.PARSER_NOTICES_PROPERTY, listener); - textArea.forceReparsing(parser); + Assertions.assertTrue(textArea.forceReparsing(parser)); Assertions.assertTrue(parserNoticeChangeEventFired[0]); } - @Test - void testGetToolTipText() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testForceReparsing_disabledParserClearsItsNotices(String debugParsing) { + + AbstractParser parser = new AbstractParser() { + @Override + public ParseResult parse(RSyntaxDocument doc, String style) { + DefaultParseResult result = new DefaultParseResult(this); + result.addNotice(new DefaultParserNotice(this, "test", 1)); + return result; + } + }; + + RSyntaxTextArea textArea = createTextArea(); + // Remove the fold parser so our test parser is the only one + textArea.setCodeFoldingEnabled(false); + textArea.addParser(parser); + + // Initial run - adds notices to the text area. + Assertions.assertTrue(textArea.forceReparsing(parser)); + Assertions.assertFalse(textArea.getParserNotices().isEmpty()); + + // After being disabled and rerun - clears notices from the text area. + parser.setEnabled(false); + Assertions.assertTrue(textArea.forceReparsing(parser)); + Assertions.assertTrue(textArea.getParserNotices().isEmpty()); + + } + + + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testGetSetDelay(String debugParsing) { + + RSyntaxTextArea textArea = createTextArea(); + ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); + + manager.setDelay(12345); + Assertions.assertEquals(12345, manager.getDelay()); + + manager.restartParsing(); + try { + manager.setDelay(54321); + Assertions.assertEquals(54321, manager.getDelay()); + } finally { + manager.stopParsing(); + } + } + + + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testGetToolTipText(String debugParsing) { AbstractParser parser = new AbstractParser() { @Override @@ -190,6 +239,7 @@ public ParseResult parse(RSyntaxDocument doc, String style) { textArea.setAntiAliasingEnabled(false); // Needed to initialize font metrics cache RTextScrollPane sp = new RTextScrollPane(textArea); // text area needs a parent ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); manager.addParser(parser); manager.forceReparsing(0); @@ -200,12 +250,25 @@ public ParseResult parse(RSyntaxDocument doc, String style) { } - @Test - void testPropertyChange_document() { + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testInsertUpdate(String debugParsing) { RSyntaxTextArea textArea = createTextArea(); ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); + + textArea.insert("inserted text", 5); + } + + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testPropertyChange_document(String debugParsing) { + + RSyntaxTextArea textArea = createTextArea(); + ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); RSyntaxDocument origDocument = (RSyntaxDocument)textArea.getDocument(); RSyntaxDocument newDocument = new RSyntaxDocument(SyntaxConstants.SYNTAX_STYLE_C); @@ -215,4 +278,16 @@ void testPropertyChange_document() { // listener removed (along with all others) Assertions.assertEquals(0, origDocument.getDocumentListeners().length); } + + + @ParameterizedTest + @ValueSource(strings = { "true", "false" }) + void testRemoveUpdate(String debugParsing) { + + RSyntaxTextArea textArea = createTextArea(); + ParserManager manager = new ParserManager(textArea); + manager.setDebugParsing(Boolean.parseBoolean(debugParsing)); + + textArea.replaceRange("", 5, 9); + } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitBeginWordActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitBeginWordActionTest.java new file mode 100644 index 000000000..6da883abf --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitBeginWordActionTest.java @@ -0,0 +1,136 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.fife.ui.SwingRunnerExtension; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + + +/** + * Unit tests for this action. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class RSyntaxTextAreaEditorKitBeginWordActionTest extends AbstractRSyntaxTextAreaTest { + + + @Test + void testActionPerformedImpl_inWhitespace_middleOfWhitespace() { + + String text = "word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(7); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + // Moves to the beginning of whitespace between words + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(4, textArea.getSelectionStart()); + Assertions.assertEquals(4, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_inWhitespace_endOfWhitespace() { + + String text = "word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(text.lastIndexOf(' ')); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + // Moves to the beginning of whitespace between words + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(4, textArea.getSelectionStart()); + Assertions.assertEquals(4, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_inWord_beginningOfWord() { + + String text = "word word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(5); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(5, textArea.getSelectionStart()); + Assertions.assertEquals(5, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_inWord_endOfWord() { + + String text = "word word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(8); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(5, textArea.getSelectionStart()); + Assertions.assertEquals(5, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_inWord_middleOfWord() { + + String text = "word word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(7); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(5, textArea.getSelectionStart()); + Assertions.assertEquals(5, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_offset0() { + + String text = "word word word"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(0); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(0, textArea.getSelectionStart()); + Assertions.assertEquals(0, textArea.getSelectionEnd()); + } + + + @Test + void testActionPerformedImpl_startOfLineOtherThanTheFirst() { + + String text = "line 1\nline 2"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + int secondLineStartOffs = text.indexOf('\n') + 1; + textArea.setCaretPosition(secondLineStartOffs); + + RSyntaxTextAreaEditorKit.BeginWordAction action = + new RSyntaxTextAreaEditorKit.BeginWordAction("name", false); + + action.actionPerformedImpl(null, textArea); + Assertions.assertEquals(secondLineStartOffs, textArea.getSelectionStart()); + Assertions.assertEquals(secondLineStartOffs, textArea.getSelectionEnd()); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitChangeFoldStateActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitChangeFoldStateActionTest.java new file mode 100644 index 000000000..388bd2946 --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitChangeFoldStateActionTest.java @@ -0,0 +1,65 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.fife.ui.SwingRunnerExtension; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import javax.swing.*; + + +/** + * Unit tests for this action. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class RSyntaxTextAreaEditorKitChangeFoldStateActionTest extends AbstractRSyntaxTextAreaTest { + + + @Test + void testConstructor_4Arg() { + Action a = new RSyntaxTextAreaEditorKit.ChangeFoldStateAction( + "name", null, "desc", 1, null + ); + Assertions.assertEquals("name", a.getValue(Action.NAME)); + Assertions.assertNull(a.getValue(Action.LARGE_ICON_KEY)); + Assertions.assertNull(a.getValue(Action.SMALL_ICON)); + Assertions.assertEquals("desc", a.getValue(Action.SHORT_DESCRIPTION)); + Assertions.assertEquals(1, a.getValue(Action.MNEMONIC_KEY)); + Assertions.assertNull(a.getValue(Action.ACCELERATOR_KEY)); + } + + + @Test + void testActionPerformedImpl_codeFoldingNotEnabled() { + RSyntaxTextArea textArea = createTextArea(); + textArea.setCodeFoldingEnabled(false); + + RSyntaxTextAreaEditorKit.ChangeFoldStateAction a = + new RSyntaxTextAreaEditorKit.ChangeFoldStateAction("name", true); + + a.actionPerformedImpl(null, textArea); + // TODO: Mock and verify error feedback is triggered + } + + + @Test + void testActionPerformedImpl_codeFoldingEnabled_closesClosestFold() { + RSyntaxTextArea textArea = createTextArea(); + textArea.setCaretPosition(0); // On the first fold's line + + Assertions.assertFalse(textArea.getFoldManager().getFold(0).isCollapsed()); + + RSyntaxTextAreaEditorKit.ChangeFoldStateAction a = + new RSyntaxTextAreaEditorKit.ChangeFoldStateAction("name", true); + + a.actionPerformedImpl(null, textArea); + Assertions.assertTrue(textArea.getFoldManager().getFold(0).isCollapsed()); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseCurlyBraceActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseCurlyBraceActionTest.java new file mode 100644 index 000000000..569ab1d82 --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseCurlyBraceActionTest.java @@ -0,0 +1,125 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.fife.ui.SwingRunnerExtension; +import org.fife.ui.rtextarea.RecordableTextAction; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + + +/** + * Unit tests for this action. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class RSyntaxTextAreaEditorKitCloseCurlyBraceActionTest extends AbstractRSyntaxTextAreaTest { + + + @Test + void testActionPerformedImpl_enabledAndEditable_alignCurlyBraces_emptyDocument() { + + RSyntaxTextArea textArea = createTextArea(""); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + + String expected = "}"; + Assertions.assertEquals(expected, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_enabledAndEditable_alignCurlyBraces_newCloseCurly() { + + RSyntaxTextArea textArea = createTextArea("{\n printf(\"hi\");\n "); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + + // Verify the last line's whitespace is removed + String expected = "{\n printf(\"hi\");\n}"; + Assertions.assertEquals(expected, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_enabledAndEditable_alignCurlyBraces_newCloseCurly_languageWithoutCurlies() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_CSV, "{\n hi\n "); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + + // Verify the closing curly is simply inserted since it's not semantically meaningful + String expected = "{\n hi\n }"; + Assertions.assertEquals(expected, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_enabledAndEditable_alignCurlyBraces_newCloseCurly_nonWhitespace() { + + RSyntaxTextArea textArea = createTextArea("{\n printf(\"hi\");\n xxx "); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + + // Verify the last line's whitespace isn't removed due to "xxx" + String expected = "{\n printf(\"hi\");\n xxx }"; + Assertions.assertEquals(expected, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_enabledAndEditable_alignCurlyBracesFalse_newCloseCurly() { + + RSyntaxTextArea textArea = createTextArea("{\n printf(\"hi\");\n "); + textArea.setCaretPosition(textArea.getDocument().getLength()); + textArea.setAutoIndentEnabled(false); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + + // Verify the last line's whitespace isn't removed + String expected = "{\n printf(\"hi\");\n }"; + Assertions.assertEquals(expected, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_notEditable() { + RSyntaxTextArea textArea = createTextArea(); + textArea.setEditable(false); + String origText = textArea.getText(); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(origText, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_notEnabled() { + RSyntaxTextArea textArea = createTextArea(); + textArea.setEnabled(false); + String origText = textArea.getText(); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(origText, textArea.getText()); + } + + + @Test + void getGetMacroId() { + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseCurlyBraceAction(); + Assertions.assertEquals(RSyntaxTextAreaEditorKit.rstaCloseCurlyBraceAction, a.getMacroID()); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseMarkupTagActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseMarkupTagActionTest.java new file mode 100644 index 000000000..36a6c4cbf --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitCloseMarkupTagActionTest.java @@ -0,0 +1,237 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.fife.ui.SwingRunnerExtension; +import org.fife.ui.rsyntaxtextarea.modes.XMLTokenMaker; +import org.fife.ui.rtextarea.RecordableTextAction; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + + +/** + * Unit tests for this action. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class RSyntaxTextAreaEditorKitCloseMarkupTagActionTest extends AbstractRSyntaxTextAreaTest { + + private boolean xmlDefaultClosingTags; + + @BeforeEach + void setUp() { + xmlDefaultClosingTags = XMLTokenMaker.getCompleteCloseMarkupTags(); + } + + + @AfterEach + void tearDown() { + XMLTokenMaker.setCompleteCloseTags(xmlDefaultClosingTags); + } + + + @Test + void testActionPerformedImpl_markup_typingClosingTag() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, + "<"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = ""; + Assertions.assertEquals(expected, textArea.getText()); + Assertions.assertEquals(textArea.getDocument().getLength(), textArea.getCaretPosition()); + } + + + @Test + void testActionPerformedImpl_markup_typingClosingTag_nested() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, + "<"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = ""; + Assertions.assertEquals(expected, textArea.getText()); + Assertions.assertEquals(textArea.getDocument().getLength(), textArea.getCaretPosition()); + } + + + @Test + void testActionPerformedImpl_markup_typingClosingTag_attributesAreSkipped() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, + "<"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = ""; + Assertions.assertEquals(expected, textArea.getText()); + Assertions.assertEquals(textArea.getDocument().getLength(), textArea.getCaretPosition()); + } + + + @Test + void testActionPerformedImpl_markup_typingClosingTag_spaceBeforeTagName() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, + "< foo><"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = "< foo>"; + Assertions.assertEquals(expected, textArea.getText()); + Assertions.assertEquals(textArea.getDocument().getLength(), textArea.getCaretPosition()); + } + + + @Test + void testActionPerformedImpl_markup_typingClosingTag_butDisabledForLanguage() { + + XMLTokenMaker.setCompleteCloseTags(false); + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, + "<"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = "<"); + textArea.setCaretPosition(textArea.getDocument().getLength()); + textArea.setCloseMarkupTags(false); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CloseMarkupTagAction(); + a.actionPerformedImpl(null, textArea); + + String expected = " after the first "{" + Assertions.assertEquals(1, textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_folding_selectTrue() { + + String text = "{\n printf(\"Hi\");\n {\n printf(\"Bye\");\n }\n}"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, text); + textArea.setCaretPosition(0); + textArea.getFoldManager().getFold(0).setCollapsed(true); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.EndAction("foo", true).actionPerformedImpl(e, textArea); + + // Caret is at the end of the first line (last visible offset => after the first "{" + Assertions.assertEquals(1, textArea.getCaretPosition()); + Assertions.assertEquals("{", textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_noFolding_selectFalse() { + + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_NONE, text); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.EndAction("foo", false).actionPerformedImpl(e, textArea); + + Assertions.assertEquals(text.length(), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_noFolding_selectTrue() { + + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_NONE, text); + textArea.setCaretPosition(0); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.EndAction("foo", true).actionPerformedImpl(e, textArea); + + Assertions.assertEquals(text.length(), textArea.getCaretPosition()); + Assertions.assertNotNull(textArea.getSelectedText()); + } + + + @Test + void testGetMacroID() { + Assertions.assertEquals("foo", + new RSyntaxTextAreaEditorKit.EndAction("foo", false).getMacroID()); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitEndWordActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitEndWordActionTest.java index 463e60b83..2a908d0a6 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitEndWordActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitEndWordActionTest.java @@ -66,4 +66,37 @@ void testGetWordEnd_noSelection_happyPath() { } + @Test + void testGetWordEnd_noSelection_atNonWordChar() { + EndWordAction action = new EndWordAction("endWordAction", false); + String TEXT = "!@#$%^&*()"; + RSyntaxTextArea textArea = createTextArea(TEXT); + textArea.setCaretPosition(TEXT.indexOf('#')); + action.actionPerformed(createActionEvent(textArea)); + Assertions.assertEquals(TEXT.indexOf('#'), textArea.getCaretPosition()); + } + + + @Test + void testGetWordEnd_noSelection_endOfLine() { + EndWordAction action = new EndWordAction("endWordAction", false); + String TEXT = "111 111\n222 222"; + RSyntaxTextArea textArea = createTextArea(TEXT); + textArea.setCaretPosition(TEXT.indexOf('\n')); + action.actionPerformed(createActionEvent(textArea)); + Assertions.assertEquals("111 111".length(), textArea.getCaretPosition()); + } + + + @Test + void testGetWordEnd_noSelection_startOfLineOtherThanFirst() { + EndWordAction action = new EndWordAction("endWordAction", false); + String TEXT = "111 111\n222 222"; + RSyntaxTextArea textArea = createTextArea(TEXT); + textArea.setCaretPosition(TEXT.indexOf('\n') + 1); + action.actionPerformed(createActionEvent(textArea)); + Assertions.assertEquals("111 111\n222".length(), textArea.getCaretPosition()); + } + + } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitExpandAllFoldsActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitExpandAllFoldsActionTest.java index cadd2d13a..01feeb3d0 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitExpandAllFoldsActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitExpandAllFoldsActionTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import javax.swing.*; import java.awt.event.ActionEvent; @@ -25,6 +26,19 @@ @ExtendWith(SwingRunnerExtension.class) class RSyntaxTextAreaEditorKitExpandAllFoldsActionTest extends AbstractRSyntaxTextAreaTest { + @Test + void testConstructor_5Arg() { + Action a = new RSyntaxTextAreaEditorKit.ExpandAllFoldsAction( + "name", null, "desc", 1, null + ); + Assertions.assertEquals("name", a.getValue(Action.NAME)); + Assertions.assertNull(a.getValue(Action.LARGE_ICON_KEY)); + Assertions.assertNull(a.getValue(Action.SMALL_ICON)); + Assertions.assertEquals("desc", a.getValue(Action.SHORT_DESCRIPTION)); + Assertions.assertEquals(1, a.getValue(Action.MNEMONIC_KEY)); + Assertions.assertNull(a.getValue(Action.ACCELERATOR_KEY)); + } + @Test void testActionPerformedImpl_expandAllFolds() { @@ -58,6 +72,39 @@ void testActionPerformedImpl_expandAllFolds() { Assertions.assertFalse(foldManager.getFold(1).getChild(0).isCollapsed()); } + @Test + void testActionPerformedImpl_codeFoldingDisabled() { + + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_JAVA, + "/*\n" + + "* comment\n" + + "*/\n" + + "public void foo() {\n" + + " /* comment\n" + + " two */\n" + + "}"); + + textArea.setCaretPosition(textArea.getDocument().getLength()); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.CollapseAllFoldsAction(); + ActionEvent e = createActionEvent(textArea, RSyntaxTextAreaEditorKit.rstaCollapseAllFoldsAction); + a.actionPerformedImpl(e, textArea); + + FoldManager foldManager = textArea.getFoldManager(); + Assertions.assertEquals(2, foldManager.getFoldCount()); + Assertions.assertTrue(foldManager.getFold(0).isCollapsed()); + Assertions.assertTrue(foldManager.getFold(1).isCollapsed()); + Assertions.assertTrue(foldManager.getFold(1).getChild(0).isCollapsed()); + + // Now disable code folding and expand all folds (irrelevant since folds should be destroyed) + textArea.setCodeFoldingEnabled(false); + a = new RSyntaxTextAreaEditorKit.ExpandAllFoldsAction(); + e = createActionEvent(textArea, RSyntaxTextAreaEditorKit.rstaExpandAllFoldsAction); + a.actionPerformedImpl(e, textArea); + + Assertions.assertEquals(0, foldManager.getFoldCount()); + } + @Test void testGetMacroId() { RSyntaxTextAreaEditorKit.ExpandAllFoldsAction a = new RSyntaxTextAreaEditorKit.ExpandAllFoldsAction(); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitGoToMatchingBracketActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitGoToMatchingBracketActionTest.java index 405d4fd8e..bd1f4a007 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitGoToMatchingBracketActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitGoToMatchingBracketActionTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import javax.swing.*; import java.awt.event.ActionEvent; @@ -24,6 +25,19 @@ @ExtendWith(SwingRunnerExtension.class) class RSyntaxTextAreaEditorKitGoToMatchingBracketActionTest extends AbstractRSyntaxTextAreaTest { + @Test + void testConstructor_5Arg() { + Action a = new RSyntaxTextAreaEditorKit.GoToMatchingBracketAction( + "name", null, "desc", 1, null + ); + Assertions.assertEquals("name", a.getValue(Action.NAME)); + Assertions.assertNull(a.getValue(Action.LARGE_ICON_KEY)); + Assertions.assertNull(a.getValue(Action.SMALL_ICON)); + Assertions.assertEquals("desc", a.getValue(Action.SHORT_DESCRIPTION)); + Assertions.assertEquals(1, a.getValue(Action.MNEMONIC_KEY)); + Assertions.assertNull(a.getValue(Action.ACCELERATOR_KEY)); + } + @Test void testActionPerformedImpl_goToMatchingBracket() { @@ -44,6 +58,27 @@ void testActionPerformedImpl_goToMatchingBracket() { Assertions.assertEquals(expectedOffset, textArea.getCaretPosition()); } + @Test + void testActionPerformedImpl_noMatchingBracket() { + + // Missing the final closing bracket + String origContent = "public void foo() {\n" + + " if (something) {\n" + + " System.out.println(\"Hello world\");\n" + + " }"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_JAVA, origContent); + + int firstCurlyOffs = origContent.indexOf('{'); + textArea.setCaretPosition(firstCurlyOffs); + + RecordableTextAction a = new RSyntaxTextAreaEditorKit.GoToMatchingBracketAction(); + ActionEvent e = createActionEvent(textArea, RSyntaxTextAreaEditorKit.rstaGoToMatchingBracketAction); + a.actionPerformedImpl(e, textArea); + + // Verify the caret hasn't moved + Assertions.assertEquals(firstCurlyOffs, textArea.getCaretPosition()); + } + @Test void testGetMacroId() { RSyntaxTextAreaEditorKit.GoToMatchingBracketAction a = new RSyntaxTextAreaEditorKit.GoToMatchingBracketAction(); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitIncreaseFontSizeActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitIncreaseFontSizeActionTest.java index 2501eb6cb..7ecb1fb37 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitIncreaseFontSizeActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitIncreaseFontSizeActionTest.java @@ -11,6 +11,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; @@ -24,9 +26,23 @@ class RSyntaxTextAreaEditorKitIncreaseFontSizeActionTest extends AbstractRSyntaxTextAreaTest { @Test - void testActionPerformedImpl_increaseFontSize() { + void testConstructor_5Arg() { + Action a = new RSyntaxTextAreaEditorKit.IncreaseFontSizeAction( + "name", null, "desc", 1, null + ); + Assertions.assertEquals("name", a.getValue(Action.NAME)); + Assertions.assertNull(a.getValue(Action.LARGE_ICON_KEY)); + Assertions.assertNull(a.getValue(Action.SMALL_ICON)); + Assertions.assertEquals("desc", a.getValue(Action.SHORT_DESCRIPTION)); + Assertions.assertEquals(1, a.getValue(Action.MNEMONIC_KEY)); + Assertions.assertNull(a.getValue(Action.ACCELERATOR_KEY)); + } + + @Test + void testActionPerformedImpl_increaseFontSize_happyPath() { RSyntaxTextArea textArea = createTextArea(); + JScrollPane sp = new JScrollPane(textArea); int origFontSize = 0; for (Style style : textArea.getSyntaxScheme().getStyles()) { @@ -51,6 +67,55 @@ void testActionPerformedImpl_increaseFontSize() { Assertions.assertTrue(newFontSize > origFontSize); } + @Test + void testActionPerformedImpl_increaseFontSize_capsAtMaxSize() { + + // This action change the font size in increments of 1f, so we start + // with a font size close enough to the cap to hit it + float maxSize = 40f; + RSyntaxTextArea textArea = createTextArea(); + Font font = textArea.getFont(); + textArea.setFont(font.deriveFont(maxSize - 0.5f)); + float origFontSize = textArea.getFont().getSize2D(); + + RSyntaxTextAreaEditorKit.IncreaseFontSizeAction a = new RSyntaxTextAreaEditorKit.IncreaseFontSizeAction(); + ActionEvent e = createActionEvent(textArea, RSyntaxTextAreaEditorKit.rtaIncreaseFontSizeAction); + a.actionPerformedImpl(e, textArea); + + for (Style style : textArea.getSyntaxScheme().getStyles()) { + if (style.font != null) { + float newFontSize = style.font.getSize2D(); + Assertions.assertEquals(maxSize, newFontSize, 0.0001f); + } + } + Assertions.assertEquals(maxSize, textArea.getFont().getSize2D(), 0.0001f); + } + + @Test + void testActionPerformedImpl_increaseFontSize_alreadyLargerThanMaxSize() { + + // This action change the font size in increments of 1f, so we start + // with a font size close enough to the cap to hit it + float maxSize = 40f; + RSyntaxTextArea textArea = createTextArea(); + Font font = textArea.getFont(); + textArea.setFont(font.deriveFont(maxSize + 1f)); + float origFontSize = textArea.getFont().getSize2D(); + + RSyntaxTextAreaEditorKit.IncreaseFontSizeAction a = new RSyntaxTextAreaEditorKit.IncreaseFontSizeAction(); + ActionEvent e = createActionEvent(textArea, RSyntaxTextAreaEditorKit.rtaIncreaseFontSizeAction); + a.actionPerformedImpl(e, textArea); + + // Verify fonts remain unchanged in size + for (Style style : textArea.getSyntaxScheme().getStyles()) { + if (style.font != null) { + float newFontSize = style.font.getSize2D(); + Assertions.assertEquals(origFontSize, newFontSize, 0.0001f); + } + } + Assertions.assertEquals(origFontSize, textArea.getFont().getSize2D(), 0.0001f); + } + @Test void testGetMacroId() { RSyntaxTextAreaEditorKit.IncreaseFontSizeAction a = new RSyntaxTextAreaEditorKit.IncreaseFontSizeAction(); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitInsertTabActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitInsertTabActionTest.java index e25884046..34a992d0a 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitInsertTabActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitInsertTabActionTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import javax.swing.*; import javax.swing.text.DefaultEditorKit; import java.awt.event.ActionEvent; @@ -23,6 +24,13 @@ class RSyntaxTextAreaEditorKitInsertTabActionTest extends AbstractRSyntaxTextAreaTest { + @Test + void testConstructor_nameArg() { + Action a = new RSyntaxTextAreaEditorKit.InsertTabAction("foo"); + Assertions.assertEquals("foo", a.getValue(Action.NAME)); + } + + @Test void testActionPerformedImpl_notEditable() { @@ -66,7 +74,28 @@ void testActionPerformedImpl_noSelection() { @Test - void testActionPerformedImpl_multiLineSelection() { + void testActionPerformedImpl_multiLineSelection_dotAtStartOfLine() { + + String origContent = "int main() {\n" + + "\tprintf(\"Hello world\n\");\n" + + "}"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, origContent); + textArea.setCaretPosition(0); + textArea.moveCaretPosition(origContent.indexOf('\t')); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.InsertTabAction().actionPerformedImpl(e, textArea); + + // End line does not get indented since the caret was at the start of it + String expectedContent = "\tint main() {\n" + + "\tprintf(\"Hello world\n\");\n" + + "}"; + Assertions.assertEquals(expectedContent, textArea.getText()); + } + + + @Test + void testActionPerformedImpl_multiLineSelection_dotNotAtStartOfLine() { String origContent = "int main() {\n" + "\tprintf(\"Hello world\n\");\n" + @@ -78,6 +107,7 @@ void testActionPerformedImpl_multiLineSelection() { ActionEvent e = new ActionEvent(textArea, 0, "command"); new RSyntaxTextAreaEditorKit.InsertTabAction().actionPerformedImpl(e, textArea); + // End line gets indented since the caret was NOT at the start of it String expectedContent = "\tint main() {\n" + "\t\tprintf(\"Hello world\n\");\n" + "}"; diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitNextWordActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitNextWordActionTest.java index 7a454defc..bf379a74c 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitNextWordActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitNextWordActionTest.java @@ -23,7 +23,126 @@ class RSyntaxTextAreaEditorKitNextWordActionTest extends AbstractRSyntaxTextArea @Test - void testActionPerformedImpl_noSelection() { + void testActionPerformedImpl_atEndOfDocument() { + + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(text.length()); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", true).actionPerformedImpl(e, textArea); + + Assertions.assertEquals(text.length(), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_codeFolding_noLaterVisibleLine_noSelection() { + + String text = "line 1 {\n foo;\n}"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + textArea.setCodeFoldingEnabled(true); + textArea.getFoldManager().getFold(0).setCollapsed(true); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", false).actionPerformedImpl(e, textArea); + + // Because of the fold, we're already on the last visible offset + Assertions.assertEquals(text.indexOf('\n'), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_codeFolding_noLaterVisibleLine_selection() { + + String text = "line 1 {\n foo;\n}"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + textArea.setCodeFoldingEnabled(true); + textArea.getFoldManager().getFold(0).setCollapsed(true); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", true).actionPerformedImpl(e, textArea); + + // Because of the fold, we're already on the last visible offset + Assertions.assertEquals(text.indexOf('\n'), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_codeFolding_laterVisibleLine_noSelection() { + + String text = "line 1 {\n foo;\n}\nlast line"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + textArea.setCodeFoldingEnabled(true); + textArea.getFoldManager().getFold(0).setCollapsed(true); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", false).actionPerformedImpl(e, textArea); + + // Just go to the start of the next line + Assertions.assertEquals(text.indexOf("last line"), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_codeFolding_laterVisibleLine_selection() { + + String text = "line 1 {\n foo;\n}\nlast line"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + textArea.setCodeFoldingEnabled(true); + textArea.getFoldManager().getFold(0).setCollapsed(true); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", true).actionPerformedImpl(e, textArea); + + // Just go to the start of the next line + Assertions.assertEquals(text.indexOf("last line"), textArea.getCaretPosition()); + Assertions.assertEquals("\n foo;\n}\n", textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_noCodeFolding_noSelection() { + + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", false).actionPerformedImpl(e, textArea); + + // Just go to the start of the next line + Assertions.assertEquals(text.indexOf('\n') + 1, textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_atEndOfLine_noCodeFolding_selection() { + + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(text.indexOf('\n')); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", true).actionPerformedImpl(e, textArea); + + // Just go to the start of the next line + Assertions.assertEquals(text.indexOf('\n') + 1, textArea.getCaretPosition()); + Assertions.assertEquals("\n", textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_noSelection_lettersAndNumbers() { RSyntaxTextArea textArea = new RSyntaxTextArea("line 1\nline 2\nline 3"); textArea.setCaretPosition(0); @@ -36,6 +155,38 @@ void testActionPerformedImpl_noSelection() { } + @Test + void testActionPerformedImpl_noSelection_symbolsWithTrailingWhitespace() { + + String text = "///// line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(0); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", false).actionPerformedImpl(e, textArea); + + // Skip the symbols and trailing whitespace to get to the next word + Assertions.assertEquals(text.indexOf("line 1"), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_noSelection_symbolsAdjacentToNextWord() { + + String text = "/////line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(text); + textArea.setCaretPosition(0); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.NextWordAction("foo", false).actionPerformedImpl(e, textArea); + + // Skip the symbols to get to the next word + Assertions.assertEquals(text.indexOf("line 1"), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + @Test void testActionPerformedImpl_noSelection_nextLine() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPossiblyInsertTemplateActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPossiblyInsertTemplateActionTest.java index 75e5fe719..0a490eab7 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPossiblyInsertTemplateActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPossiblyInsertTemplateActionTest.java @@ -5,6 +5,8 @@ package org.fife.ui.rsyntaxtextarea; import org.fife.ui.SwingRunnerExtension; +import org.fife.ui.rsyntaxtextarea.templates.CodeTemplate; +import org.fife.ui.rsyntaxtextarea.templates.StaticCodeTemplate; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -38,6 +40,21 @@ void tearDown() { } + @Test + void testActionPerformedImpl_notEditable() { + + String origContent = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); + RSyntaxTextArea.setTemplatesEnabled(true); + textArea.setEditable(false); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PossiblyInsertTemplateAction().actionPerformedImpl(e, textArea); + + Assertions.assertEquals(origContent, textArea.getText()); + } + + @Test void testActionPerformedImpl_notEnabled() { @@ -67,6 +84,24 @@ void testActionPerformedImpl_templatesNotEnabled() { } + @Test + void testActionPerformedImpl_templatesEnabled_matchingTemplate() { + + String origContent = "toReplace"; + RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); + RSyntaxTextArea.setTemplatesEnabled(true); + CodeTemplate template = new StaticCodeTemplate("toReplace", "foo", "bar"); + RSyntaxTextArea.getCodeTemplateManager().addTemplate(template); + textArea.setCaretPosition(origContent.length()); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PossiblyInsertTemplateAction().actionPerformedImpl(e, textArea); + + Assertions.assertEquals("foobar", textArea.getText()); + Assertions.assertEquals("foo".length(), textArea.getCaretPosition()); + } + + @Test void testActionPerformedImpl_templatesEnabled_noMatchingTemplate() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPreviousWordActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPreviousWordActionTest.java index 8e7cc61bc..d15e13c98 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPreviousWordActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitPreviousWordActionTest.java @@ -23,7 +23,22 @@ class RSyntaxTextAreaEditorKitPreviousWordActionTest extends AbstractRSyntaxText @Test - void testActionPerformedImpl_noSelection() { + void testActionPerformedImpl_atOffset0() { + + String origContent = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); + textArea.setCaretPosition(0); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PreviousWordAction("foo", false).actionPerformedImpl(e, textArea); + + Assertions.assertEquals(0, textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_middleOfLine_noSelection_letters() { String origContent = "line 1\nline 2\nline 3"; RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); @@ -38,7 +53,22 @@ void testActionPerformedImpl_noSelection() { @Test - void testActionPerformedImpl_noSelection_nextLine() { + void testActionPerformedImpl_middleOfLine_noSelection_symbols() { + + String origContent = "line 1\n@@@@ 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); + textArea.setCaretPosition(origContent.indexOf('2')); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PreviousWordAction("foo", false).actionPerformedImpl(e, textArea); + + Assertions.assertEquals(origContent.indexOf("@@@@ 2"), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_middleOfLine_noSelection_nextLine() { RSyntaxTextArea textArea = new RSyntaxTextArea("line 1\nline 2\nline 3"); textArea.setCaretPosition(textArea.getText().indexOf('\n')); @@ -53,7 +83,7 @@ void testActionPerformedImpl_noSelection_nextLine() { @Test - void testActionPerformedImpl_selection() { + void testActionPerformedImpl_middleOfLine_selection() { String origContent = "line 1\nline 2\nline 3"; RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); @@ -67,6 +97,56 @@ void testActionPerformedImpl_selection() { } + @Test + void testActionPerformedImpl_startOfLine_codeFolding_noSelection() { + + String origContent = "{\n exit(0);\n}"; + RSyntaxTextArea textArea = createTextArea(origContent); + textArea.setCaretPosition(origContent.indexOf('\n') + 1); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PreviousWordAction("foo", false).actionPerformedImpl(e, textArea); + + // End of the previous line + Assertions.assertEquals(origContent.indexOf('\n'), textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_startOfLine_codeFolding_noSelection_hiddenLinesAbove() { + + // The caret is at the start of the last line. Lines immediately above it are collapsed. + String origContent = "{\n {\n foo;\n }\n}"; + RSyntaxTextArea textArea = createTextArea(origContent); + textArea.getFoldManager().getFold(0).getChild(0).setCollapsed(true); + textArea.setCaretPosition(origContent.lastIndexOf('\n') + 1); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PreviousWordAction("foo", false).actionPerformedImpl(e, textArea); + + // End of the second line (where the collapsed section starts). + Assertions.assertEquals(origContent.indexOf(" {") + 3, textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + + @Test + void testActionPerformedImpl_startOfLine_noCodeFolding_noSelection() { + + String origContent = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = new RSyntaxTextArea(origContent); + textArea.setCaretPosition(origContent.indexOf("line 2")); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.PreviousWordAction("foo", false).actionPerformedImpl(e, textArea); + + // End of the previous line + Assertions.assertEquals(origContent.indexOf("1") + 1, textArea.getCaretPosition()); + Assertions.assertNull(textArea.getSelectedText()); + } + + @Test void testGetMacroID() { Assertions.assertEquals("foo", diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitTest.java new file mode 100644 index 000000000..5118efed5 --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitTest.java @@ -0,0 +1,32 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.fife.ui.SwingRunnerExtension; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + + +/** + * Unit tests for the {@code RSyntaxTextAreaEditorKit} class. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class RSyntaxTextAreaEditorKitTest { + + @Test + void testCreateDefaultDocument() { + RSyntaxTextAreaEditorKit kit = new RSyntaxTextAreaEditorKit(); + Assertions.assertInstanceOf(RSyntaxDocument.class, kit.createDefaultDocument()); + } + + @Test + void testGetString_validString() { + Assertions.assertNotNull(RSyntaxTextAreaEditorKit.getString("ContextMenu.Folding")); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCommentActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCommentActionTest.java index 2504a9f94..42d706da9 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCommentActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCommentActionTest.java @@ -5,12 +5,11 @@ package org.fife.ui.rsyntaxtextarea; import org.fife.ui.SwingRunnerExtension; +import org.fife.ui.rtextarea.RecordableTextAction; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import java.awt.event.ActionEvent; - /** * Unit tests for the {@link RSyntaxTextAreaEditorKit.ToggleCommentAction} class. @@ -24,95 +23,119 @@ class RSyntaxTextAreaEditorKitToggleCommentActionTest extends AbstractRSyntaxTex @Test void testActionPerformedImpl_notEditable() { - - String code = "line 1\nline 2\nline 3"; - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - code); - textArea.setCaretPosition(8); + RSyntaxTextArea textArea = createTextArea(); textArea.setEditable(false); - - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - - Assertions.assertEquals(code, textArea.getText()); + String origText = textArea.getText(); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(origText, textArea.getText()); } @Test void testActionPerformedImpl_notEnabled() { - - String code = "line 1\nline 2\nline 3"; - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - code); - textArea.setCaretPosition(8); + RSyntaxTextArea textArea = createTextArea(); textArea.setEnabled(false); - - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - - Assertions.assertEquals(code, textArea.getText()); + String origText = textArea.getText(); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(origText, textArea.getText()); } @Test - void testActionPerformedImpl_singleLine_addComment() { - - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - "line 1\nline 2\nline 3"); - textArea.setCaretPosition(8); + void testActionPerformedImpl_add_multiLine_endsAtStartOfLine() { + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('1')); + textArea.moveCaretPosition(text.indexOf("line 3")); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + + // Final line is not commented out + String expected = "//line 1\n//line 2\nline 3"; + Assertions.assertEquals(expected, textArea.getText()); + } - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - String expectedText = "line 1\n//line 2\nline 3"; - Assertions.assertEquals(expectedText, textArea.getText()); + @Test + void testActionPerformedImpl_add_multiLine_endsInMiddleOfLine() { + String text = "line 1\nline 2\nline 3"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf('1')); + textArea.moveCaretPosition(text.indexOf("ne 3")); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + String expected = "//line 1\n//line 2\n//line 3"; + Assertions.assertEquals(expected, textArea.getText()); } @Test - void testActionPerformedImpl_singleLine_removeComment() { - - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - "line 1\n//line 2\nline 3"); - textArea.setCaretPosition(8); + void testActionPerformedImpl_add_singleLine_startTokenOnly() { + String text = "this is code"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(0); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals("//" + text, textArea.getText()); + } - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - String expectedText = "line 1\nline 2\nline 3"; - Assertions.assertEquals(expectedText, textArea.getText()); + @Test + void testActionPerformedImpl_add_singleLine_startAndEnd_missingEnd() { + String text = "", textArea.getText()); } @Test - void testActionPerformedImpl_multipleLines_addComment() { - - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - "line 1\nline 2\nline 3"); - textArea.setCaretPosition(2); - textArea.moveCaretPosition(8); + void testActionPerformedImpl_add_singleLine_languageWithoutComments() { + String text = "this is code"; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_BBCODE, text); + textArea.setCaretPosition(0); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(text, textArea.getText()); + } - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - String expectedText = "//line 1\n//line 2\nline 3"; - Assertions.assertEquals(expectedText, textArea.getText()); + @Test + void testActionPerformedImpl_remove_singleLine_caretAtStartOfLine() { + String text = "// this is code"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(0); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(" this is code", textArea.getText()); } @Test - void testActionPerformedImpl_multipleLines_removeComment() { - - RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_C, - "//line 1\n//line 2\nline 3"); - textArea.setCaretPosition(2); - textArea.moveCaretPosition(11); + void testActionPerformedImpl_remove_singleLine_caretAtStartOfLine_startAndEnd() { + String text = ""; + RSyntaxTextArea textArea = createTextArea(SyntaxConstants.SYNTAX_STYLE_XML, text); + textArea.setCaretPosition(0); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(" this is code ", textArea.getText()); + } - ActionEvent e = new ActionEvent(textArea, 0, "command"); - new RSyntaxTextAreaEditorKit.ToggleCommentAction().actionPerformedImpl(e, textArea); - String expectedText = "line 1\nline 2\nline 3"; - Assertions.assertEquals(expectedText, textArea.getText()); + @Test + void testActionPerformedImpl_remove_singleLine_caretInMiddleOfLine() { + String text = "// this is code"; + RSyntaxTextArea textArea = createTextArea(text); + textArea.setCaretPosition(text.indexOf("is")); + RecordableTextAction a = new RSyntaxTextAreaEditorKit.ToggleCommentAction(); + a.actionPerformedImpl(null, textArea); + Assertions.assertEquals(" this is code", textArea.getText()); } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCurrentFoldActionTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCurrentFoldActionTest.java index 48c066086..e1f3cedbe 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCurrentFoldActionTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/RSyntaxTextAreaEditorKitToggleCurrentFoldActionTest.java @@ -10,6 +10,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import javax.swing.*; import java.awt.event.ActionEvent; @@ -22,6 +23,19 @@ @ExtendWith(SwingRunnerExtension.class) class RSyntaxTextAreaEditorKitToggleCurrentFoldActionTest extends AbstractRSyntaxTextAreaTest { + @Test + void testConstructor_5Arg() { + Action a = new RSyntaxTextAreaEditorKit.ToggleCurrentFoldAction( + "name", null, "desc", 1, null + ); + Assertions.assertEquals("name", a.getValue(Action.NAME)); + Assertions.assertNull(a.getValue(Action.LARGE_ICON_KEY)); + Assertions.assertNull(a.getValue(Action.SMALL_ICON)); + Assertions.assertEquals("desc", a.getValue(Action.SHORT_DESCRIPTION)); + Assertions.assertEquals(1, a.getValue(Action.MNEMONIC_KEY)); + Assertions.assertNull(a.getValue(Action.ACCELERATOR_KEY)); + } + @Test void testActionPerformedImpl_happyPath() { @@ -38,6 +52,20 @@ void testActionPerformedImpl_happyPath() { } + @Test + void testActionPerformedImpl_noFoldsInDocument() { + + RSyntaxTextArea textArea = createTextArea("this is code"); + textArea.setCaretPosition(1); + + ActionEvent e = new ActionEvent(textArea, 0, "command"); + new RSyntaxTextAreaEditorKit.ToggleCurrentFoldAction().actionPerformedImpl(e, textArea); + + FoldManager foldManager = textArea.getFoldManager(); + Assertions.assertEquals(0, foldManager.getFoldCount()); + } + + @Test void testActionPerformedImpl_foldingDisabled() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/TokenIteratorTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/TokenIteratorTest.java index f46c48aff..04ea925a9 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/TokenIteratorTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/TokenIteratorTest.java @@ -85,6 +85,17 @@ void testEmptyLines() throws Exception { } + @Test + void testRemove() { + Assertions.assertThrows(UnsupportedOperationException.class, () -> { + RSyntaxDocument doc = loadResource("TokenIteratorTest_JavaBasic.txt", + SyntaxConstants.SYNTAX_STYLE_JAVA); + TokenIterator iter = new TokenIterator(doc); + iter.remove(); + }); + } + + /** * Loads a text resource from the classpath into an instance of * {@link RSyntaxDocument}. diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/URLFileLocationTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/URLFileLocationTest.java new file mode 100644 index 000000000..2cf360900 --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/URLFileLocationTest.java @@ -0,0 +1,65 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +/** + * Unit tests for the {@link URLFileLocation} class. + * + * @author Robert Futrell + * @version 1.0 + */ +class URLFileLocationTest { + + + @Test + void testGetActualLastModified() { + String url = "https://google.com"; + FileLocation loc = FileLocation.create(url); + Assertions.assertInstanceOf(URLFileLocation.class, loc); + Assertions.assertEquals(TextEditorPane.LAST_MODIFIED_UNKNOWN, loc.getActualLastModified()); + } + + + @Test + void testGetFileFullPath() { + String url = "https://google.com"; + FileLocation loc = FileLocation.create(url); + Assertions.assertInstanceOf(URLFileLocation.class, loc); + Assertions.assertEquals(url, loc.getFileFullPath()); + } + + + @Test + void testGetFileName() { + String url = "https://google.com"; + FileLocation loc = FileLocation.create(url); + Assertions.assertInstanceOf(URLFileLocation.class, loc); + Assertions.assertEquals("", loc.getFileName()); + } + + + @Test + void testIsLocal_https() { + String url = "https://google.com"; + FileLocation loc = FileLocation.create(url); + Assertions.assertInstanceOf(URLFileLocation.class, loc); + Assertions.assertFalse(loc.isLocal()); + } + + + @Test + void testIsLocalAndExists() { + String url = "https://google.com"; + FileLocation loc = FileLocation.create(url); + Assertions.assertInstanceOf(URLFileLocation.class, loc); + Assertions.assertFalse(loc.isLocalAndExists()); + } + + +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindowTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindowTest.java new file mode 100644 index 000000000..6f6f2ef8b --- /dev/null +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/focusabletip/TipWindowTest.java @@ -0,0 +1,117 @@ +/* + * This library is distributed under a modified BSD license. See the included + * LICENSE file for details. + */ +package org.fife.ui.rsyntaxtextarea.focusabletip; + +import org.fife.ui.SwingRunnerExtension; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import javax.swing.*; +import java.io.IOException; +import java.net.URL; + + +/** + * Unit tests for the {@link TipWindow} class. + * + * @author Robert Futrell + * @version 1.0 + */ +@ExtendWith(SwingRunnerExtension.class) +class TipWindowTest { + + @Test + void testConstructor_nullTitle() { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + TipWindow tw = new TipWindow(owner, focusableTip, null); + Assertions.assertTrue(tw.getText().startsWith("")); + Assertions.assertFalse(tw.getText().contains("null")); + } + + @Test + void testConstructor_title_short() { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + TipWindow tw = new TipWindow(owner, focusableTip, "test"); + Assertions.assertTrue(tw.getText().startsWith("")); + Assertions.assertTrue(tw.getText().contains("test")); + } + + @Test + void testConstructor_title_long_plainText() { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + String text = "A very long string of content"; + TipWindow tw = new TipWindow(owner, focusableTip, text); + Assertions.assertTrue(tw.getText().startsWith("")); + Assertions.assertTrue(tw.getText().contains(text)); + } + + @Test + void testConstructor_title_long_plainText_escapedForHtml() { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + String text = "A very long string of content"; + TipWindow tw = new TipWindow(owner, focusableTip, text); + Assertions.assertTrue(tw.getText().startsWith("")); + Assertions.assertTrue(tw.getText().contains("A very <em>long</em> string of content")); + } + + @Test + void testConstructor_title_long_html() { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + String text = "This rocks!"; + TipWindow tw = new TipWindow(owner, focusableTip, text); + Assertions.assertTrue(tw.getText().startsWith("")); + Assertions.assertTrue(tw.getText().contains("This rocks!")); + } + + @Test + void testConstructor_imageBaseInstalledOnTextArea() throws IOException { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + focusableTip.setImageBase(new URL("https://google.com")); + + new TipWindow(owner, focusableTip, "test"); + } + + @Test + void testActionPerformed() throws IOException { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + + TipWindow tw = new TipWindow(owner, focusableTip, "test"); + tw.actionPerformed(); + } + + @Test + void testGetSetHyperlinkListener() throws IOException { + JFrame owner = new JFrame(); + RSyntaxTextArea textArea = new RSyntaxTextArea(); + FocusableTip focusableTip = new FocusableTipTest.TestableFocusableTip(textArea, null); + focusableTip.setImageBase(new URL("https://google.com")); + + TipWindow tw = new TipWindow(owner, focusableTip, "test"); + tw.setHyperlinkListener(e -> {}); + tw.setHyperlinkListener(null); + tw.setHyperlinkListener(e -> {}); + } +} diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java index be7064712..93cc52f0f 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AbstractTokenMakerTest.java @@ -24,6 +24,68 @@ abstract class AbstractTokenMakerTest { + /** + * Verifies that the second token in an array of token lists is always a regex. + * + * @param codes The array of token lists. + */ + protected void assertAllSecondTokensAreRegexes(String... codes) { + assertAllSecondTokensAreRegexes(TokenTypes.NULL, codes); + } + + + /** + * Verifies that the second token in an array of token lists is always a regex. + * + * @param initialTokenType The initial token tpe of the line. + * @param codes The array of token lists. + */ + protected void assertAllSecondTokensAreRegexes(int initialTokenType, String... codes) { + for (String code : codes) { + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, initialTokenType, 0); + + // Skip the first token + token = token.getNextToken(); + Assertions.assertEquals(TokenTypes.REGEX, token.getType(), "not a regex: " + + token + " (code snippet: \"" + code + "\""); + } + } + + + /** + * Verifies that the second token in an array of token lists is always NOT a regex. + * + * @param codes The array of token lists. + */ + protected void assertAllSecondTokensAreNotRegexes(String... codes) { + assertAllSecondTokensAreNotRegexes(TokenTypes.NULL, codes); + } + + + /** + * Verifies that the second token in an array of token lists is always NOT a regex. + * + * @param initialTokenType The initial token tpe of the line. + * @param codes The array of token lists. + */ + protected void assertAllSecondTokensAreNotRegexes(int initialTokenType, String... codes) { + for (String code : codes) { + + Segment segment = createSegment(code); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, initialTokenType, 0); + + // Skip the first token + token = token.getNextToken(); + Assertions.assertNotEquals(TokenTypes.REGEX, token.getType(), "is a regex: " + + token + " (code snippet: \"" + code + "\""); + } + } + + /** * Verifies that all tokens in an array have a specific token type. * @@ -193,6 +255,18 @@ protected void testCommonHelper_getShouldIndentNextLineAfterCurliesAndParensForL } + @Test + public void testCommon_yycharat() { + TokenMaker tm = createTokenMaker(); + if (tm instanceof AbstractJFlexTokenMaker) { + Segment segment = createSegment("foo\nbar"); + tm.getTokenList(segment, TokenTypes.NULL, 0); + // We always parse entire lines so the next token is empty + Assertions.assertEquals('\n', ((AbstractJFlexTokenMaker)tm).yycharat(0)); + } + } + + @Test void testCommon_yyclose() throws IOException { TokenMaker tm = createTokenMaker(); @@ -200,4 +274,38 @@ void testCommon_yyclose() throws IOException { ((AbstractJFlexTokenMaker)tm).yyclose(); } } + + + @Test + void testCommon_yylength() { + TokenMaker tm = createTokenMaker(); + if (tm instanceof AbstractJFlexTokenMaker) { + Segment segment = createSegment("foo"); + tm.getTokenList(segment, TokenTypes.NULL, 0); + Assertions.assertEquals(0, ((AbstractJFlexTokenMaker)tm).yylength()); + } + } + + + @Test + void testCommon_yystate() { + TokenMaker tm = createTokenMaker(); + if (tm instanceof AbstractJFlexTokenMaker) { + Segment segment = createSegment("foo"); + tm.getTokenList(segment, TokenTypes.NULL, 0); + Assertions.assertEquals(0, ((AbstractJFlexTokenMaker)tm).yystate()); + } + } + + + @Test + void testCommon_yytext() { + TokenMaker tm = createTokenMaker(); + if (tm instanceof AbstractJFlexTokenMaker) { + Segment segment = createSegment("foo"); + tm.getTokenList(segment, TokenTypes.NULL, 0); + // We always parse entire lines so the next token is empty + Assertions.assertEquals("", ((AbstractJFlexTokenMaker)tm).yytext()); + } + } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMakerTest.java index 68c840047..d49b73b76 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/AssemblerX86TokenMakerTest.java @@ -59,6 +59,38 @@ public void testCommon_getMarkOccurrencesOfTokenType() { } + @Test + void testCharLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + "'Hello world'" + ); + } + + + @Test + void testCharLiterals_errors() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + "'Hello world unterminated" + ); + } + + + @Test + void testComments() { + assertAllTokensOfType(TokenTypes.COMMENT_EOL, + "; This is a comment"); + } + + + @Test + void testIdentifier() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + "foo", + "foo123" + ); + } + + @Test void testPreprocessor() { assertAllTokensOfType(TokenTypes.PREPROCESSOR, @@ -854,8 +886,58 @@ void testP3Instructions() { @Test - void testComments() { - assertAllTokensOfType(TokenTypes.COMMENT_EOL, - "; This is a comment"); + void testNumbers() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, + "0", + "11", + "1234567890" + ); + } + + + @Test + void testOperators() { + assertAllTokensOfType(TokenTypes.OPERATOR, + "+", + "-", + "*", + "/", + //"%", + "^", + "|", + "&", + "~", + "!", + "=", + "<", + ">" + ); + } + + + @Test + void testStrings() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + "\"Hello world\"" + ); + } + + + @Test + void testStrings_errors() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + "\"Hello world unterminated" + ); + } + + + @Test + void testWhitespace() { + assertAllTokensOfType(TokenTypes.WHITESPACE, + " ", + " ", + " \t ", + "\t\t" + ); } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMakerTest.java index 76fbf037c..603fef8a8 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DTokenMakerTest.java @@ -50,6 +50,50 @@ public void testCommon_getMarkOccurrencesOfTokenType() { } + @Test + void testAnnotations() { + assertAllTokensOfType(TokenTypes.ANNOTATION, + "@", + "@foo", + "@foobar123" + ); + } + + + @Test + void testBackquoteLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_BACKQUOTE, + "`Some text`", + "`Some text unterminated" + ); + } + + + @Test + void testBackquoteLiterals_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.LITERAL_BACKQUOTE, + TokenTypes.LITERAL_BACKQUOTE, + "Some text`", + "Some text unterminated" + ); + } + + + @Test + void testBinaryLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, + "0b0", + "0b1", + "0B0", + "0B1", + "0b010", + "0B010", + "0b0_10", + "0B0_10" + ); + } + + @Test void testBooleanLiterals() { @@ -106,6 +150,23 @@ void testDataTypes() { } + @Test + void testDocComments() { + assertAllTokensOfType(TokenTypes.COMMENT_DOCUMENTATION, + "/** Hello world */"); + } + + + @Test + void testDocComments_continuedFromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_DOCUMENTATION, + TokenTypes.COMMENT_DOCUMENTATION, + "continued from a previous line", + "continued from a previous line */" + ); + } + + @Test void testEolComments() { @@ -148,6 +209,26 @@ void testEolComments_URL() { } + @Test + void testErrorNumberFormat() { + assertAllTokensOfType(TokenTypes.ERROR_NUMBER_FORMAT, + "54for", + "0b10xxx" + ); + } + + + @Test + void testErrorStringLiterals() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + "\"", + "\"hi", + "\"\\\"", + "\"unterminated string" + ); + } + + @Test void testFloatingPointLiterals() { @@ -190,6 +271,22 @@ void testFloatingPointLiterals() { } + @Test + void testGetClosestStandardTokenTypeForInternalType() { + + TokenMaker tm = createTokenMaker(); + + Assertions.assertEquals( + TokenTypes.COMMENT_MULTILINE, + tm.getClosestStandardTokenTypeForInternalType(DTokenMaker.INTERNAL_IN_NESTABLE_MLC)); + + // One without a mapping + Assertions.assertEquals( + TokenTypes.RESERVED_WORD, + tm.getClosestStandardTokenTypeForInternalType(TokenTypes.RESERVED_WORD)); + } + + @Test void testHexLiterals() { @@ -224,6 +321,22 @@ void testHexLiterals() { } + @Test + void testIntegerLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, + "0", + "0l", + "0L", + "42", + "42l", + "42L", + "123_456", + "123_456l", + "123456L" + ); + } + + @Test void testKeywords() { @@ -393,7 +506,7 @@ void testMultiLineComments_fromPreviousLine() { void testMultiLineComments_URL() { String[] mlcLiterals = { - "/* Hello world https://www.sas.com */", + "/* Hello world https://www.google.com */", }; for (String code : mlcLiterals) { @@ -407,7 +520,7 @@ void testMultiLineComments_URL() { token = token.getNextToken(); Assertions.assertTrue(token.isHyperlink()); Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); - Assertions.assertEquals("https://www.sas.com", token.getLexeme()); + Assertions.assertEquals("https://www.google.com", token.getLexeme()); token = token.getNextToken(); Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); @@ -418,6 +531,48 @@ void testMultiLineComments_URL() { } + @Test + void testNestableMultiLineComments() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + "/+ Hello world +/", + "/+ 1 deep /+ 2 deep +/ back to 1 deep +/", + "/+ 1 deep /+ 2 deep /+ 3 deep +/ back to 2 deep +/ back to 1 deep +/" + ); + } + + + @Test + void testNestableMultiLineComment_fromPriorLine_1deep() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + DTokenMaker.INTERNAL_IN_NESTABLE_MLC, + "continuing +/", + "continuing and unterminated" + ); + } + + + @Test + void testNestableMultiLineComment_fromPriorLine_2deep() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + DTokenMaker.INTERNAL_IN_NESTABLE_MLC - 2, + "continuing 2-deep +/ continuing 1 deep +/", + "continuing 2-deep and unterminated", + "continuing 2-deep +/ continuing 1 deep and unterminated" + ); + } + + + @Test + void testNestableMultiLineComment_fromPriorLine_3deep() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + DTokenMaker.INTERNAL_IN_NESTABLE_MLC - 3, + "continuing 3 deep +/ continuing 2 deep +/ continuing 1 deep +/", + "continuing 3 deep and unterminated", + "continuing 3 deep +/ continuing 2 deep +/ continuing 1 deep and unterminated" + ); + } + + @Test void testOperators() { @@ -476,18 +631,11 @@ void testSeparators() { @Test void testStringLiterals() { - - String[] stringLiterals = { - "\"\"", "\"hi\"", "\"\\\"\"", - }; - - for (String code : stringLiterals) { - Segment segment = createSegment(code); - TokenMaker tm = createTokenMaker(); - Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); - Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, token.getType()); - } - + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + "\"\"", + "\"hi\"", + "\"\\\"\"" + ); } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMakerTest.java index 5a2f6ac4e..4c0afef2b 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DartTokenMakerTest.java @@ -30,6 +30,15 @@ protected TokenMaker createTokenMaker() { } + @Test + void testAnnotations() { + assertAllTokensOfType(TokenTypes.ANNOTATION, + "@foo", + "@foo123" + ); + } + + @Test @Override public void testCommon_GetLineCommentStartAndEnd() { @@ -85,6 +94,43 @@ void testCharLiterals() { } + @Test + void testCharLiterals_continuedFromPriorLine_valid() { + assertAllTokensOfType(TokenTypes.LITERAL_CHAR, + DartTokenMaker.INTERNAL_IN_JS_CHAR_VALID, + "continued from prior line and terminated'" + ); + } + + + @Test + void testCharLiterals_continuedFromPriorLine_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + DartTokenMaker.INTERNAL_IN_JS_CHAR_VALID, + "continued from prior line unterminated" + ); + } + + + @Test + void testCharLiteral_error() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + "'unterminated char", + "'string with an invalid \\x escape in it'" + ); + } + + + @Test + void testCharLiteral_error_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.ERROR_CHAR, + DartTokenMaker.INTERNAL_IN_JS_CHAR_INVALID, + "finally terminated'", + "still unterminated" + ); + } + + @Test void testDataTypes() { @@ -144,6 +190,15 @@ void testEolComments_URL() { } + @Test + void testErrorNumberFormat() { + assertAllTokensOfType(TokenTypes.ERROR_NUMBER_FORMAT, + "54for", + "0b10xxx" + ); + } + + @Test void testFloatingPointLiterals() { @@ -186,6 +241,39 @@ void testFloatingPointLiterals() { } + @Test + void testGetClosestStandardTokenTypeForInternalType() { + + TokenMaker tm = createTokenMaker(); + + Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, + tm.getClosestStandardTokenTypeForInternalType(DartTokenMaker.INTERNAL_IN_JS_MLC)); + Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + tm.getClosestStandardTokenTypeForInternalType(DartTokenMaker.INTERNAL_IN_JS_STRING_INVALID)); + Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + tm.getClosestStandardTokenTypeForInternalType(DartTokenMaker.INTERNAL_IN_JS_STRING_VALID)); + Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + tm.getClosestStandardTokenTypeForInternalType(DartTokenMaker.INTERNAL_IN_JS_CHAR_INVALID)); + Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + tm.getClosestStandardTokenTypeForInternalType(DartTokenMaker.INTERNAL_IN_JS_CHAR_VALID)); + Assertions.assertEquals(TokenTypes.IDENTIFIER, + tm.getClosestStandardTokenTypeForInternalType(TokenTypes.IDENTIFIER)); + } + + + @Test + void testGetJavaScriptVersion() { + String origVersion = DartTokenMaker.getJavaScriptVersion(); + try { + Assertions.assertEquals("1.0", DartTokenMaker.getJavaScriptVersion()); + DartTokenMaker.setJavaScriptVersion("1.5"); + Assertions.assertEquals("1.5", DartTokenMaker.getJavaScriptVersion()); + } finally { + DartTokenMaker.setJavaScriptVersion(origVersion); + } + } + + @Test void testHexLiterals() { @@ -214,6 +302,33 @@ void testHexLiterals() { } + @Test + void testIdentifiers() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + "foo", + "foo123" + ); + } + + + @Test + void testIdentifiers_error() { + assertAllTokensOfType(TokenTypes.ERROR_IDENTIFIER, + "foo\\bar" + ); + } + + + @Test + void testIsJavaScriptCompatible() { + Assertions.assertTrue(DartTokenMaker.isJavaScriptCompatible("0.9")); + Assertions.assertTrue(DartTokenMaker.isJavaScriptCompatible("1.0")); + Assertions.assertFalse(DartTokenMaker.isJavaScriptCompatible("1.1")); + Assertions.assertFalse(DartTokenMaker.isJavaScriptCompatible("1.2")); + Assertions.assertFalse(DartTokenMaker.isJavaScriptCompatible("1.3")); + } + + @Test void testStandardFunctions() { @@ -552,18 +667,58 @@ void testSeparators() { @Test void testStringLiterals() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + "\"\"", + "\"hi\"", + "\"\\u00fe\"", + "\"\\\"\"" + ); + } - String[] stringLiterals = { - "\"\"", "\"hi\"", "\"\\\"\"", - }; - for (String code : stringLiterals) { - Segment segment = createSegment(code); - TokenMaker tm = createTokenMaker(); - Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); - Assertions.assertEquals(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, token.getType()); - } + @Test + void testStringLiterals_continuedFromPriorLine_valid() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + DartTokenMaker.INTERNAL_IN_JS_STRING_VALID, + "continued from prior line and terminated\"" + ); + } + + + @Test + void testStringLiterals_continuedFromPriorLine_invalid() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + DartTokenMaker.INTERNAL_IN_JS_STRING_VALID, + "continued from prior line unterminated" + ); + } + + + @Test + void testStringLiterals_validEscapeSequences() { + assertAllTokensOfType(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, + "\"\\b\\s\\t\\n\\f\\r\\n\\\"\\'\\\\\"" + ); + } + + @Test + void testStringLiteral_error() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + "\"unterminated string", + "\"string with an invalid \\x escape in it\"", + "\"string with invalid \\u09KK unicode escape in it \"" + ); + } + + + @Test + void testStringLiteral_error_continuedFromPriorLine() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + DartTokenMaker.INTERNAL_IN_JS_STRING_INVALID, + "finally terminated\"", + "still unterminated" + ); } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMakerTest.java index 5c22c00db..bd550f7d0 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DelphiTokenMakerTest.java @@ -30,6 +30,53 @@ protected TokenMaker createTokenMaker() { } + @Test + void testBooleans() { + assertAllTokensOfType(TokenTypes.LITERAL_BOOLEAN, + "true", + "false" + ); + } + + + @Test + void testCompilerDirective1() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + "{$Hello world }", + "{$unterminated comment" + ); + } + + + @Test + void testCompilerDirective1_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + DelphiTokenMaker.INTERNAL_COMPILER_DIRECTIVE, + "continued from prior line }", + "continued from prior line and unterminated" + ); + } + + + @Test + void testCompilerDirective2() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + "(*$Hello world *)", + "(*$unterminated comment" + ); + } + + + @Test + void testCompilerDirective2_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + DelphiTokenMaker.INTERNAL_COMPILER_DIRECTIVE2, + "continued from prior line *)", + "continued from prior line and unterminated" + ); + } + + @Test void testDataTypes() { @@ -86,7 +133,7 @@ void testEolComments() { void testEolComments_URL() { String[] eolCommentLiterals = { - "// Hello world https://www.sas.com", + "// Hello world https://www.google.com", }; for (String code : eolCommentLiterals) { @@ -100,13 +147,23 @@ void testEolComments_URL() { token = token.getNextToken(); Assertions.assertTrue(token.isHyperlink()); Assertions.assertEquals(TokenTypes.COMMENT_EOL, token.getType()); - Assertions.assertEquals("https://www.sas.com", token.getLexeme()); + Assertions.assertEquals("https://www.google.com", token.getLexeme()); } } + @Test + void testEscapeSequences() { + assertAllTokensOfType(TokenTypes.PREPROCESSOR, + "#123", + "#1", + "#9876543210" + ); + } + + @Test void testFloatingPointLiterals() { @@ -249,6 +306,41 @@ void testStandardFunctions() { } + @Test + void testIdentifiers() { + assertAllTokensOfType(TokenTypes.IDENTIFIER, + "foo", + "foo123" + ); + } + + + @Test + void testIdentifiers_error() { + assertAllTokensOfType(TokenTypes.ERROR_IDENTIFIER, + "###" + ); + } + + + @Test + void testIntegers() { + assertAllTokensOfType(TokenTypes.LITERAL_NUMBER_DECIMAL_INT, + "44", + "0" + ); + } + + + @Test + void testIntegers_error() { + assertAllTokensOfType(TokenTypes.ERROR_NUMBER_FORMAT, + "334#", + "0x08#" + ); + } + + @Test void testKeywords() { @@ -335,18 +427,20 @@ void testKeywords() { @Test void testMultiLineComments() { - - String[] mlcLiterals = { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, "{Hello world }", - }; + "{unterminated comment" + ); + } - for (String code : mlcLiterals) { - Segment segment = createSegment(code); - TokenMaker tm = createTokenMaker(); - Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); - Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); - } + @Test + void testMultiLineComments_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + TokenTypes.COMMENT_MULTILINE, + "continued from prior line }", + "continued from prior line and unterminated" + ); } @@ -354,7 +448,7 @@ void testMultiLineComments() { void testMultiLineComments_URL() { String[] mlcLiterals = { - "{ Hello world https://www.sas.com }", + "{ Hello world https://www.google.com }", }; for (String code : mlcLiterals) { @@ -368,7 +462,7 @@ void testMultiLineComments_URL() { token = token.getNextToken(); Assertions.assertTrue(token.isHyperlink()); Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); - Assertions.assertEquals("https://www.sas.com", token.getLexeme()); + Assertions.assertEquals("https://www.google.com", token.getLexeme()); token = token.getNextToken(); Assertions.assertEquals(TokenTypes.COMMENT_MULTILINE, token.getType()); @@ -379,6 +473,25 @@ void testMultiLineComments_URL() { } + @Test + void testMultiLineComments2() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + "(*Hello world *)", + "(*unterminated comment" + ); + } + + + @Test + void testMultiLineComments2_fromPreviousLine() { + assertAllTokensOfType(TokenTypes.COMMENT_MULTILINE, + DelphiTokenMaker.INTERNAL_MLC2, + "continued from prior line *)", + "continued from prior line and unterminated" + ); + } + + @Test void testOperators() { @@ -450,4 +563,10 @@ void testStringLiterals() { } + @Test + void testStringLiterals_error() { + assertAllTokensOfType(TokenTypes.ERROR_STRING_DOUBLE, + "'Unterminated string" + ); + } } diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DtdTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DtdTokenMakerTest.java index 12b6b77e4..5b7fe49b4 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DtdTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/DtdTokenMakerTest.java @@ -8,6 +8,7 @@ import javax.swing.text.Segment; +import org.fife.ui.rsyntaxtextarea.AbstractJFlexTokenMaker; import org.fife.ui.rsyntaxtextarea.Token; import org.fife.ui.rsyntaxtextarea.TokenMaker; import org.fife.ui.rsyntaxtextarea.TokenTypes; @@ -47,6 +48,18 @@ public void testCommon_getMarkOccurrencesOfTokenType() { } + @Test + @Override + public void testCommon_yycharat() { + Segment segment = createSegment("foo\nbar"); + TokenMaker tm = createTokenMaker(); + tm.getTokenList(segment, TokenTypes.NULL, 0); + Assertions.assertThrows(ArrayIndexOutOfBoundsException.class, () -> + ((AbstractJFlexTokenMaker)tm).yycharat(0) + ); + } + + @Test void testDtd_comment() { diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java index 339d35065..48e5e348b 100755 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/modes/HTMLTokenMakerTest.java @@ -9,9 +9,11 @@ import javax.swing.text.Segment; import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.TokenImpl; import org.fife.ui.rsyntaxtextarea.TokenMaker; import org.fife.ui.rsyntaxtextarea.TokenTypes; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -166,7 +168,7 @@ void testCommon_getLineCommentStartAndEnd_js() { @Test - void testCommon_getSetCloseCompleteTags() { + void testCommon_getSetCompleteCloseTags() { HTMLTokenMaker tm = (HTMLTokenMaker)createTokenMaker(); Assertions.assertFalse(tm.getCompleteCloseTags()); try { @@ -191,6 +193,128 @@ public void testCommon_getMarkOccurrencesOfTokenType() { } + @Test + void testCommon_getShouldIndentNextLineAfter_null() { + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(null)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_nullToken() { + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(new TokenImpl())); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_css_afterCurly() { + Segment seg = createSegment("{"); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.SEPARATOR, HTMLTokenMaker.LANG_INDEX_CSS); + Assertions.assertTrue(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_css_afterParen() { + Segment seg = createSegment("("); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.SEPARATOR, HTMLTokenMaker.LANG_INDEX_CSS); + Assertions.assertTrue(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_css_afterRandomSingleCharToken() { + Segment seg = createSegment("x"); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.IDENTIFIER, HTMLTokenMaker.LANG_INDEX_CSS); + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_css_afterRandomMultiCharToken() { + Segment seg = createSegment("xx"); + Token token = new TokenImpl( + seg, 0, 1, 0, TokenTypes.IDENTIFIER, HTMLTokenMaker.LANG_INDEX_CSS); + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_js_afterCurly() { + Segment seg = createSegment("{"); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.SEPARATOR, HTMLTokenMaker.LANG_INDEX_JS); + Assertions.assertTrue(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_js_afterParen() { + Segment seg = createSegment("("); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.SEPARATOR, HTMLTokenMaker.LANG_INDEX_JS); + Assertions.assertTrue(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_js_afterRandomSingleCharToken() { + Segment seg = createSegment("x"); + Token token = new TokenImpl( + seg, 0, 0, 0, TokenTypes.IDENTIFIER, HTMLTokenMaker.LANG_INDEX_JS); + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_getShouldIndentNextLineAfter_js_afterRandomMultiCharToken() { + Segment seg = createSegment("xx"); + Token token = new TokenImpl( + seg, 0, 1, 0, TokenTypes.IDENTIFIER, HTMLTokenMaker.LANG_INDEX_JS); + Assertions.assertFalse(createTokenMaker().getShouldIndentNextLineAfter(token)); + } + + + @Test + void testCommon_isIdentifierChar_default() { + TokenMaker tm = createTokenMaker(); + + // letters + for (int ch = 'A'; ch <= 'Z'; ch++) { + Assertions.assertTrue(tm.isIdentifierChar(0, (char)ch)); + Assertions.assertTrue(tm.isIdentifierChar(0, (char)(ch+('a'-'A')))); + } + + // some other chars + Assertions.assertTrue(tm.isIdentifierChar(0, '-')); + Assertions.assertTrue(tm.isIdentifierChar(0, '_')); + Assertions.assertTrue(tm.isIdentifierChar(0, '.')); + + // Other stuff isn't identifier chars + Assertions.assertFalse(tm.isIdentifierChar(0, '%')); + } + + + @Test + void testCommon_isIdentifierChar_js() { + TokenMaker tm = createTokenMaker(); + + // letters + for (int ch = 'A'; ch <= 'Z'; ch++) { + Assertions.assertTrue(tm.isIdentifierChar(HTMLTokenMaker.LANG_INDEX_JS, (char)ch)); + Assertions.assertTrue(tm.isIdentifierChar(HTMLTokenMaker.LANG_INDEX_JS, (char)(ch+('a'-'A')))); + } + + // some other chars + Assertions.assertTrue(tm.isIdentifierChar(HTMLTokenMaker.LANG_INDEX_JS, '_')); + + // Other stuff isn't identifier chars + Assertions.assertFalse(tm.isIdentifierChar(HTMLTokenMaker.LANG_INDEX_JS, '%')); + } + + @Test void testCss_atRule() { assertAllTokensOfType(TokenTypes.REGEX, @@ -864,21 +988,12 @@ void testHtml_comment_URL() { @Test void testHtml_doctype() { - - String[] doctypes = { + assertAllTokensOfType(TokenTypes.MARKUP_DTD, "", "", "", - "", "", "", - ">=/foo/" + ); + } + + + @Test + void testJS_regex_notWhenFollowingCertainTokens() { + assertAllSecondTokensAreNotRegexes( + JS_PREV_TOKEN_TYPE, + "^/foo/", + ">>/foo/", + "<for"); + TokenMaker tm = createTokenMaker(); + Token token = tm.getTokenList(segment, TokenTypes.NULL, 0); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_DELIMITER, "<")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_NAME, "script")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.MARKUP_TAG_DELIMITER, ">")); + token = token.getNextToken(); + Assertions.assertTrue(token.is(TokenTypes.RESERVED_WORD, "for")); + } + + + @Test + void testHtml_inTag_scriptTag_withAttrs_startsJS() { + Segment segment = createSegment("