View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.gui;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static org.mockito.Mockito.mock;
24  
25  import java.awt.event.ActionEvent;
26  import java.awt.event.ActionListener;
27  import java.awt.event.MouseEvent;
28  import java.io.File;
29  import java.io.IOException;
30  
31  import javax.swing.JButton;
32  import javax.swing.JTextArea;
33  import javax.swing.KeyStroke;
34  import javax.swing.tree.TreePath;
35  
36  import org.junit.jupiter.api.BeforeEach;
37  import org.junit.jupiter.api.Test;
38  
39  import com.puppycrawl.tools.checkstyle.AbstractGuiTestSupport;
40  
41  public class TreeTableTest extends AbstractGuiTestSupport {
42  
43      private static final String TEST_FILE_NAME = "InputTreeTable.java";
44  
45      private TreeTable treeTable;
46  
47      @Override
48      protected String getPackageLocation() {
49          return "com/puppycrawl/tools/checkstyle/gui/treetable";
50      }
51  
52      @BeforeEach
53      public void prepare() throws Exception {
54          final MainFrameModel model = new MainFrameModel();
55          model.openFile(new File(getPath(TEST_FILE_NAME)));
56          treeTable = new TreeTable(model.getParseTreeTableModel());
57          treeTable.setLinePositionList(model.getLinesToPosition());
58          treeTable.setEditor(mock(JTextArea.class));
59          treeTable.setXpathEditor(mock(JTextArea.class));
60          treeTable.getTree().setSelectionPath(
61                  new TreePath(treeTable.getTree().getModel().getRoot()));
62      }
63  
64      @Test
65      public void testExpandOnMouseDoubleClick() {
66          final MouseEvent mouseDoubleClickEvent =
67                  new MouseEvent(treeTable, MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, 2, false);
68          assertWithMessage("The tree should be initially expanded")
69                  .that(treeTable.getTree().isExpanded(0))
70                  .isTrue();
71          treeTable.dispatchEvent(mouseDoubleClickEvent);
72          assertWithMessage("The tree should be collapsed after action")
73                  .that(treeTable.getTree().isExpanded(0))
74                  .isFalse();
75          treeTable.dispatchEvent(mouseDoubleClickEvent);
76          assertWithMessage("The tree should be expanded after action")
77                  .that(treeTable.getTree().isExpanded(0))
78                  .isTrue();
79      }
80  
81      @Test
82      public void testNothingChangedOnMouseSingleClick() {
83          final MouseEvent mouseSingleClickEvent =
84                  new MouseEvent(treeTable, MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, 1, false);
85          assertWithMessage("The tree should be initially expanded")
86                  .that(treeTable.getTree().isExpanded(0))
87                  .isTrue();
88          treeTable.dispatchEvent(mouseSingleClickEvent);
89          assertWithMessage("The tree should be still expanded")
90                  .that(treeTable.getTree().isExpanded(0))
91                  .isTrue();
92      }
93  
94      @Test
95      public void testExpandOnEnterKey() {
96          final ActionEvent expandCollapseActionEvent =
97                  new ActionEvent(treeTable, ActionEvent.ACTION_PERFORMED, "expand/collapse");
98          final ActionListener actionForEnter =
99                  treeTable.getActionForKeyStroke(KeyStroke.getKeyStroke("ENTER"));
100         assertWithMessage("The tree should be initially expanded")
101                 .that(treeTable.getTree().isExpanded(0))
102                 .isTrue();
103         actionForEnter.actionPerformed(expandCollapseActionEvent);
104         assertWithMessage("The tree should be collapsed after action")
105                 .that(treeTable.getTree().isExpanded(0))
106                 .isFalse();
107         actionForEnter.actionPerformed(expandCollapseActionEvent);
108         assertWithMessage("The tree should be expanded after action")
109                 .that(treeTable.getTree().isExpanded(0))
110                 .isTrue();
111     }
112 
113     @Test
114     public void testFindNodesAllClassDefs() throws IOException {
115         final MainFrame mainFrame = new MainFrame();
116         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
117         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
118         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
119         xpathTextArea.setText("//CLASS_DEF");
120         findNodeButton.doClick();
121 
122         final String expected = """
123                 /COMPILATION_UNIT/CLASS_DEF[./IDENT\
124                 [@text='InputTreeTableXpathAreaPanel']]
125                 /COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputTreeTableXpathAreaPanel']]\
126                 /OBJBLOCK/CLASS_DEF\
127                 [./IDENT[@text='Inner']]
128                 """;
129 
130         assertWithMessage("Expected and actual XPath queries should match.")
131                 .that(xpathTextArea.getText())
132                 .isEqualTo(expected);
133     }
134 
135     @Test
136     public void testFindNodesIdent() throws IOException {
137         final MainFrame mainFrame = new MainFrame();
138         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
139         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
140         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
141         xpathTextArea.setText("//IDENT");
142         findNodeButton.doClick();
143 
144         final String expected = """
145                 /COMPILATION_UNIT/CLASS_DEF/IDENT\
146                 [@text='InputTreeTableXpathAreaPanel']
147                 /COMPILATION_UNIT/PACKAGE_DEF/DOT/IDENT[@text='treetable']
148                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT/IDENT\
149                 [@text='gui']
150                 /COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputTreeTableXpathAreaPanel']]\
151                 /OBJBLOCK/CLASS_DEF/IDENT[@text='Inner']
152                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
153                 [@text='gui']]/DOT/IDENT[@text='checkstyle']
154                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
155                 [@text='gui']]/DOT[./IDENT[@text='checkstyle']]/DOT/IDENT[@text='tools']
156                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
157                 [@text='gui']]\
158                 /DOT[./IDENT[@text='checkstyle']]/DOT[./IDENT[@text='tools']]/DOT/IDENT\
159                 [@text='com']
160                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
161                 [@text='gui']]\
162                 /DOT[./IDENT[@text='checkstyle']]/DOT[./IDENT[@text='tools']]/DOT[./IDENT\
163                 [@text='com']]/IDENT[@text='puppycrawl']
164                 """;
165 
166         assertWithMessage("Expected and actual XPath queries should match.")
167                 .that(xpathTextArea.getText())
168                 .isEqualTo(expected);
169     }
170 
171     @Test
172     public void testFindNodesMissingElements() throws IOException {
173         final MainFrame mainFrame = new MainFrame();
174         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
175         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
176         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
177         xpathTextArea.setText("//LITERAL_TRY");
178         findNodeButton.doClick();
179 
180         final String expected = "No elements matching XPath query '//LITERAL_TRY' found.";
181 
182         assertWithMessage("Unexpected XPath text area text")
183                 .that(xpathTextArea.getText())
184                 .isEqualTo(expected);
185     }
186 
187     @Test
188     public void testFindNodesUnexpectedTokenAtStart() throws IOException {
189         final MainFrame mainFrame = new MainFrame();
190         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
191         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
192         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
193         xpathTextArea.setText("!*7^");
194         findNodeButton.doClick();
195 
196         final String expected = "!*7^\nUnexpected token \"!\" at start of expression";
197 
198         assertWithMessage("Unexpected XPath text area text")
199                 .that(xpathTextArea.getText())
200                 .isEqualTo(expected);
201     }
202 
203     @Test
204     public void testFindNodesInvalidCharacterInExpression() throws IOException {
205         final MainFrame mainFrame = new MainFrame();
206         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
207         final JButton findNodeButton = findComponentByName(mainFrame, "findNodeButton");
208         final JTextArea xpathTextArea = findComponentByName(mainFrame, "xpathTextArea");
209         xpathTextArea.setText("//CLASS_DEF^");
210         findNodeButton.doClick();
211 
212         final String expected = "//CLASS_DEF^\nInvalid character '^' (x5e) in expression";
213 
214         assertWithMessage("Unexpected XPath text area text")
215                 .that(xpathTextArea.getText())
216                 .isEqualTo(expected);
217     }
218 
219     @Test
220     public void testTreeModelAdapterMethods() throws IOException {
221         final MainFrame mainFrame = new MainFrame();
222         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
223 
224         assertWithMessage("Value at Column (0, 3) expected to equal 0")
225                 .that(treeTable.getValueAt(0, 3).equals(0))
226                 .isEqualTo(true);
227 
228         assertWithMessage("getColumn class expected to return string class")
229                 .that(treeTable.getColumnClass(4).equals(String.class))
230                 .isEqualTo(true);
231 
232         assertWithMessage("Selected cell expected not be editable")
233                 .that(treeTable.isCellEditable(1, 0))
234                 .isEqualTo(false);
235     }
236 }