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,
118                 "findNodeButton", JButton.class);
119         final JTextArea xpathTextArea = findComponentByName(mainFrame,
120                 "xpathTextArea", JTextArea.class);
121         xpathTextArea.setText("//CLASS_DEF");
122         findNodeButton.doClick();
123 
124         final String expected =
125                 """
126                 /COMPILATION_UNIT/CLASS_DEF[./IDENT\
127                 [@text='InputTreeTableXpathAreaPanel']]
128                 /COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputTreeTableXpathAreaPanel']]\
129                 /OBJBLOCK/CLASS_DEF\
130                 [./IDENT[@text='Inner']]
131                 """;
132 
133         assertWithMessage("Expected and actual XPath queries should match.")
134                 .that(xpathTextArea.getText())
135                 .isEqualTo(expected);
136     }
137 
138     @Test
139     public void testFindNodesIdent() throws IOException {
140         final MainFrame mainFrame = new MainFrame();
141         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
142         final JButton findNodeButton = findComponentByName(mainFrame,
143                 "findNodeButton", JButton.class);
144         final JTextArea xpathTextArea = findComponentByName(mainFrame,
145                 "xpathTextArea", JTextArea.class);
146         xpathTextArea.setText("//IDENT");
147         findNodeButton.doClick();
148 
149         final String expected =
150                 """
151                 /COMPILATION_UNIT/CLASS_DEF/IDENT\
152                 [@text='InputTreeTableXpathAreaPanel']
153                 /COMPILATION_UNIT/PACKAGE_DEF/DOT/IDENT[@text='treetable']
154                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT/IDENT\
155                 [@text='gui']
156                 /COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputTreeTableXpathAreaPanel']]\
157                 /OBJBLOCK/CLASS_DEF/IDENT[@text='Inner']
158                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
159                 [@text='gui']]/DOT/IDENT[@text='checkstyle']
160                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
161                 [@text='gui']]/DOT[./IDENT[@text='checkstyle']]/DOT/IDENT[@text='tools']
162                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
163                 [@text='gui']]\
164                 /DOT[./IDENT[@text='checkstyle']]/DOT[./IDENT[@text='tools']]/DOT/IDENT\
165                 [@text='com']
166                 /COMPILATION_UNIT/PACKAGE_DEF/DOT[./IDENT[@text='treetable']]/DOT[./IDENT\
167                 [@text='gui']]\
168                 /DOT[./IDENT[@text='checkstyle']]/DOT[./IDENT[@text='tools']]/DOT[./IDENT\
169                 [@text='com']]/IDENT[@text='puppycrawl']
170                 """;
171 
172         assertWithMessage("Expected and actual XPath queries should match.")
173                 .that(xpathTextArea.getText())
174                 .isEqualTo(expected);
175     }
176 
177     @Test
178     public void testFindNodesMissingElements() throws IOException {
179         final MainFrame mainFrame = new MainFrame();
180         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
181         final JButton findNodeButton = findComponentByName(mainFrame,
182                 "findNodeButton", JButton.class);
183         final JTextArea xpathTextArea = findComponentByName(mainFrame,
184                 "xpathTextArea", JTextArea.class);
185         xpathTextArea.setText("//LITERAL_TRY");
186         findNodeButton.doClick();
187 
188         final String expected = "No elements matching XPath query '//LITERAL_TRY' found.";
189 
190         assertWithMessage("Unexpected XPath text area text")
191                 .that(xpathTextArea.getText())
192                 .isEqualTo(expected);
193     }
194 
195     @Test
196     public void testFindNodesUnexpectedTokenAtStart() throws IOException {
197         final MainFrame mainFrame = new MainFrame();
198         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
199         final JButton findNodeButton = findComponentByName(mainFrame,
200                 "findNodeButton", JButton.class);
201         final JTextArea xpathTextArea = findComponentByName(mainFrame,
202                 "xpathTextArea", JTextArea.class);
203         xpathTextArea.setText("!*7^");
204         findNodeButton.doClick();
205 
206         final String expected = "!*7^\nUnexpected token \"!\" at start of expression";
207 
208         assertWithMessage("Unexpected XPath text area text")
209                 .that(xpathTextArea.getText())
210                 .isEqualTo(expected);
211     }
212 
213     @Test
214     public void testFindNodesInvalidCharacterInExpression() throws IOException {
215         final MainFrame mainFrame = new MainFrame();
216         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
217         final JButton findNodeButton = findComponentByName(mainFrame,
218                 "findNodeButton", JButton.class);
219         final JTextArea xpathTextArea = findComponentByName(mainFrame,
220                 "xpathTextArea", JTextArea.class);
221         xpathTextArea.setText("//CLASS_DEF^");
222         findNodeButton.doClick();
223 
224         final String expected = "//CLASS_DEF^\nInvalid character '^' (x5e) in expression";
225 
226         assertWithMessage("Unexpected XPath text area text")
227                 .that(xpathTextArea.getText())
228                 .isEqualTo(expected);
229     }
230 
231     @Test
232     public void testTreeModelAdapterMethods() throws IOException {
233         final MainFrame mainFrame = new MainFrame();
234         mainFrame.openFile(new File(getPath("InputTreeTableXpathAreaPanel.java")));
235 
236         assertWithMessage("Value at Column (0, 3) expected to equal 0")
237                 .that(treeTable.getValueAt(0, 3).equals(0))
238                 .isEqualTo(true);
239 
240         assertWithMessage("getColumn class expected to return string class")
241                 .that(treeTable.getColumnClass(4).equals(String.class))
242                 .isEqualTo(true);
243 
244         assertWithMessage("Selected cell expected not be editable")
245                 .that(treeTable.isCellEditable(1, 0))
246                 .isEqualTo(false);
247     }
248 }