View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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 com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
24  
25  import java.io.File;
26  
27  import org.junit.jupiter.api.BeforeEach;
28  import org.junit.jupiter.api.Test;
29  
30  import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
31  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
32  import com.puppycrawl.tools.checkstyle.JavaParser;
33  import com.puppycrawl.tools.checkstyle.api.DetailAST;
34  import com.puppycrawl.tools.checkstyle.api.DetailNode;
35  import com.puppycrawl.tools.checkstyle.api.JavadocCommentsTokenTypes;
36  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37  import com.puppycrawl.tools.checkstyle.gui.MainFrameModel.ParseMode;
38  import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
39  
40  public class ParseTreeTablePresentationTest extends AbstractPathTestSupport {
41  
42      private DetailAST tree;
43  
44      @Override
45      public String getPackageLocation() {
46          return "com/puppycrawl/tools/checkstyle/gui/parsetreetablepresentation";
47      }
48  
49      @BeforeEach
50      public void loadTree() throws Exception {
51          tree = JavaParser.parseFile(new File(getPath("InputParseTreeTablePresentation.java")),
52              JavaParser.Options.WITH_COMMENTS).getFirstChild().getNextSibling();
53      }
54  
55      @Test
56      public void testRoot() throws Exception {
57          final DetailAST root = JavaParser.parseFile(
58                  new File(getPath("InputParseTreeTablePresentation.java")),
59                  JavaParser.Options.WITH_COMMENTS);
60          assertWithMessage("Root node should have 2 children")
61                  .that(root.getChildCount())
62                  .isEqualTo(2);
63      }
64  
65      @Test
66      public void testChildCount() {
67          final int childCount = new ParseTreeTablePresentation(null).getChildCount(tree);
68          assertWithMessage("Invalid child count")
69              .that(childCount)
70              .isEqualTo(5);
71      }
72  
73      @Test
74      public void testChildCountInJavaAndJavadocMode() {
75          final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
76          parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
77          final int childCount = parseTree.getChildCount(tree);
78          assertWithMessage("Invalid child count")
79              .that(childCount)
80              .isEqualTo(5);
81      }
82  
83      @Test
84      public void testChild() {
85          final Object child = new ParseTreeTablePresentation(null).getChild(tree, 1);
86          assertWithMessage("Invalid child type")
87                  .that(child)
88                  .isInstanceOf(DetailAST.class);
89          final int type = ((DetailAST) child).getType();
90          assertWithMessage("Invalid child token type")
91              .that(type)
92              .isEqualTo(TokenTypes.BLOCK_COMMENT_BEGIN);
93      }
94  
95      @Test
96      public void testChildInJavaAndJavadocMode() {
97          final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
98          parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
99          final Object child = parseTree.getChild(tree, 1);
100         assertWithMessage("Invalid child type")
101                 .that(child)
102                 .isInstanceOf(DetailAST.class);
103         final int type = ((DetailAST) child).getType();
104         assertWithMessage("Invalid child token type")
105             .that(type)
106             .isEqualTo(TokenTypes.BLOCK_COMMENT_BEGIN);
107     }
108 
109     @Test
110     public void testCommentChildCount() {
111         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
112         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
113         parseTree.setParseMode(ParseMode.JAVA_WITH_COMMENTS);
114         final int javadocCommentChildCount = parseTree.getChildCount(commentContentNode);
115         assertWithMessage("Invalid child count")
116             .that(javadocCommentChildCount)
117             .isEqualTo(0);
118     }
119 
120     @Test
121     public void testCommentChildCountInJavaAndJavadocMode() {
122         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
123         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
124         final DetailAST commentContentNode = tree.getLastChild().getLastChild()
125                 .getPreviousSibling().getLastChild().getFirstChild().getFirstChild();
126         final int commentChildCount = parseTree.getChildCount(commentContentNode);
127         assertWithMessage("Invalid child count")
128             .that(commentChildCount)
129             .isEqualTo(0);
130     }
131 
132     @Test
133     public void testCommentChildInJavaAndJavadocMode() {
134         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
135         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
136         final DetailAST commentContentNode = tree.getLastChild().getLastChild()
137                 .getPreviousSibling().getLastChild().getFirstChild().getFirstChild();
138         final Object commentChild = parseTree.getChild(commentContentNode, 0);
139         assertWithMessage("Child must be null")
140             .that(commentChild)
141             .isNull();
142     }
143 
144     @Test
145     public void testJavadocCommentChildCount() {
146         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
147         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
148         final int commentChildCount = parseTree.getChildCount(commentContentNode);
149         assertWithMessage("Invalid child count")
150             .that(commentChildCount)
151             .isEqualTo(0);
152         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
153         final int javadocCommentChildCount = parseTree.getChildCount(commentContentNode);
154         assertWithMessage("Invalid child count")
155             .that(javadocCommentChildCount)
156             .isEqualTo(1);
157     }
158 
159     @Test
160     public void testJavadocCommentChild() {
161         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
162         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
163         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
164         final Object child = parseTree.getChild(commentContentNode, 0);
165         assertWithMessage("Invalid child type")
166                 .that(child)
167                 .isInstanceOf(DetailNode.class);
168         final int type = ((DetailNode) child).getType();
169         assertWithMessage("Invalid child token type")
170             .that(type)
171             .isEqualTo(JavadocCommentsTokenTypes.JAVADOC_CONTENT);
172         // get Child one more time to test cache of PModel
173         final Object childSame = parseTree.getChild(commentContentNode, 0);
174         assertWithMessage("Invalid child type")
175                 .that(childSame)
176                 .isInstanceOf(DetailNode.class);
177         final int sameType = ((DetailNode) childSame).getType();
178         assertWithMessage("Invalid child token type")
179             .that(sameType)
180             .isEqualTo(JavadocCommentsTokenTypes.JAVADOC_CONTENT);
181     }
182 
183     @Test
184     public void testJavadocChildCount() {
185         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
186         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
187         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
188         final Object javadoc = parseTree.getChild(commentContentNode, 0);
189         assertWithMessage("Invalid child type")
190                 .that(javadoc)
191                 .isInstanceOf(DetailNode.class);
192         final int type = ((DetailNode) javadoc).getType();
193         assertWithMessage("Invalid child token type")
194             .that(type)
195             .isEqualTo(JavadocCommentsTokenTypes.JAVADOC_CONTENT);
196         final int javadocChildCount = parseTree.getChildCount(javadoc);
197         assertWithMessage("Invalid child count")
198             .that(javadocChildCount)
199             .isEqualTo(4);
200     }
201 
202     @Test
203     public void testJavadocChild() {
204         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
205         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
206         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
207         final Object javadoc = parseTree.getChild(commentContentNode, 0);
208         assertWithMessage("Invalid child type")
209                 .that(javadoc)
210                 .isInstanceOf(DetailNode.class);
211         final int type = ((DetailNode) javadoc).getType();
212         assertWithMessage("Invalid child token type")
213             .that(type)
214             .isEqualTo(JavadocCommentsTokenTypes.JAVADOC_CONTENT);
215         final Object javadocChild = parseTree.getChild(javadoc, 2);
216         assertWithMessage("Invalid child type")
217                 .that(javadocChild)
218                 .isInstanceOf(DetailNode.class);
219         final int childType = ((DetailNode) javadocChild).getType();
220         assertWithMessage("Invalid child token type")
221             .that(childType)
222             .isEqualTo(JavadocCommentsTokenTypes.TEXT);
223     }
224 
225     @Test
226     public void testGetIndexOfChild() {
227         DetailAST ithChild = tree.getFirstChild();
228         assertWithMessage("Child must not be null")
229             .that(ithChild)
230             .isNotNull();
231         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
232         int index = 0;
233         while (ithChild != null) {
234             final int indexOfChild = parseTree.getIndexOfChild(tree, ithChild);
235             assertWithMessage("Invalid child index")
236                 .that(indexOfChild)
237                 .isEqualTo(index);
238             ithChild = ithChild.getNextSibling();
239             index++;
240         }
241 
242         final int indexOfChild = parseTree.getIndexOfChild(tree, new DetailAstImpl());
243         assertWithMessage("Invalid child index")
244             .that(indexOfChild)
245             .isEqualTo(-1);
246     }
247 
248     /**
249      * The path to class name in InputJavadocAttributesAndMethods.java.
250      * <pre>
251      * CLASS_DEF
252      *  - MODIFIERS
253      *  - Comment node
254      *  - LITERAL_CLASS
255      *  - IDENT -> this is the node that holds the class name
256      *  Line number 4 - first three lines are taken by javadoc
257      *  Column 6 - first five columns taken by 'class '
258      *  </pre>
259      */
260     @Test
261     public void testGetValueAt() {
262         final DetailAST node = tree.getFirstChild()
263             .getNextSibling()
264             .getNextSibling()
265             .getNextSibling();
266 
267         assertWithMessage("Expected a non-null identifier node here")
268             .that(node)
269             .isNotNull();
270         assertWithMessage("Expected identifier token")
271             .that(node.getType())
272             .isEqualTo(TokenTypes.IDENT);
273 
274         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
275         final Object treeModel = parseTree.getValueAt(node, 0);
276         final String type = (String) parseTree.getValueAt(node, 1);
277         final int line = (int) parseTree.getValueAt(node, 2);
278         final int column = (int) parseTree.getValueAt(node, 3);
279         final String text = (String) parseTree.getValueAt(node, 4);
280 
281         assertWithMessage("Node should be an Identifier")
282             .that(type)
283             .isEqualTo("IDENT");
284         assertWithMessage("Class identifier should start on line 6")
285             .that(line)
286             .isEqualTo(6);
287         assertWithMessage("Class name should start from column 6")
288             .that(column)
289             .isEqualTo(6);
290         assertWithMessage("Wrong class name")
291             .that(text)
292             .isEqualTo("InputParseTreeTablePresentation");
293         assertWithMessage("Root node should have null value")
294             .that(treeModel)
295             .isNull();
296 
297         final IllegalStateException exc =
298                 getExpectedThrowable(IllegalStateException.class, () -> {
299                     parseTree.getValueAt(node, parseTree.getColumnCount());
300                 }, "IllegalStateException expected");
301         assertWithMessage("Invalid error message")
302             .that(exc.getMessage())
303             .isEqualTo("Unknown column");
304     }
305 
306     @Test
307     public void testGetValueAtDetailNode() {
308         final DetailAST commentContentNode = tree.getFirstChild().getNextSibling().getFirstChild();
309         assertWithMessage("Comment node cannot be null")
310             .that(commentContentNode)
311             .isNotNull();
312         final int nodeType = commentContentNode.getType();
313         assertWithMessage("Comment node should be a comment type")
314                 .that(TokenUtil.isCommentType(nodeType))
315                 .isTrue();
316         assertWithMessage("This should be a javadoc comment")
317             .that(commentContentNode.getParent().getText())
318             .isEqualTo("/*");
319         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
320         parseTree.setParseMode(ParseMode.JAVA_WITH_JAVADOC_AND_COMMENTS);
321         final Object child = parseTree.getChild(commentContentNode, 0);
322 
323         assertWithMessage("Child has not to be leaf")
324                 .that(parseTree.isLeaf(child))
325                 .isFalse();
326         assertWithMessage("Child has to be leaf")
327                 .that(parseTree.isLeaf(tree.getFirstChild()))
328                 .isTrue();
329 
330         final Object treeModel = parseTree.getValueAt(child, 0);
331         final String type = (String) parseTree.getValueAt(child, 1);
332         final int line = (int) parseTree.getValueAt(child, 2);
333         final int column = (int) parseTree.getValueAt(child, 3);
334         final String text = (String) parseTree.getValueAt(child, 4);
335         final String expectedText = "JAVADOC_CONTENT";
336 
337         assertWithMessage("Tree model must be null")
338             .that(treeModel)
339             .isNull();
340         assertWithMessage("Invalid type")
341             .that(type)
342             .isEqualTo("JAVADOC_CONTENT");
343         assertWithMessage("Invalid line")
344             .that(line)
345             .isEqualTo(3);
346         assertWithMessage("Invalid column")
347             .that(column)
348             .isEqualTo(3);
349         assertWithMessage("Invalid text")
350             .that(text)
351             .isEqualTo(expectedText);
352 
353         final IllegalStateException exc =
354                 getExpectedThrowable(IllegalStateException.class, () -> {
355                     parseTree.getValueAt(child, parseTree.getColumnCount());
356                 }, "IllegalStateException expected");
357         assertWithMessage("Invalid error message")
358             .that(exc.getMessage())
359             .isEqualTo("Unknown column");
360     }
361 
362     @Test
363     public void testColumnMethods() {
364         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
365         assertWithMessage("Invalid type")
366             .that(parseTree.getColumnClass(0))
367             .isEqualTo(ParseTreeTableModel.class);
368         assertWithMessage("Invalid type")
369             .that(parseTree.getColumnClass(1))
370             .isEqualTo(String.class);
371         assertWithMessage("Invalid type")
372             .that(parseTree.getColumnClass(2))
373             .isEqualTo(Integer.class);
374         assertWithMessage("Invalid type")
375             .that(parseTree.getColumnClass(3))
376             .isEqualTo(Integer.class);
377         assertWithMessage("Invalid type")
378             .that(parseTree.getColumnClass(4))
379             .isEqualTo(String.class);
380 
381         final IllegalStateException exc =
382                 getExpectedThrowable(IllegalStateException.class, () -> {
383                     parseTree.getColumnClass(parseTree.getColumnCount());
384                 }, "IllegalStateException expected");
385         assertWithMessage("Invalid error message")
386             .that(exc.getMessage())
387             .isEqualTo("Unknown column");
388 
389         assertWithMessage("Invalid cell editable status")
390                 .that(parseTree.isCellEditable(1))
391                 .isFalse();
392     }
393 
394     @Test
395     public void testColumnNames() {
396         final ParseTreeTablePresentation parseTree = new ParseTreeTablePresentation(null);
397         assertWithMessage("Invalid column count")
398             .that(parseTree.getColumnCount())
399             .isEqualTo(5);
400         assertWithMessage("Invalid column name")
401             .that(parseTree.getColumnName(0))
402             .isEqualTo("Tree");
403         assertWithMessage("Invalid column name")
404             .that(parseTree.getColumnName(1))
405             .isEqualTo("Type");
406         assertWithMessage("Invalid column name")
407             .that(parseTree.getColumnName(2))
408             .isEqualTo("Line");
409         assertWithMessage("Invalid column name")
410             .that(parseTree.getColumnName(3))
411             .isEqualTo("Column");
412         assertWithMessage("Invalid column name")
413             .that(parseTree.getColumnName(4))
414             .isEqualTo("Text");
415     }
416 
417 }