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