View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.grammar;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  
24  import java.io.File;
25  import java.nio.charset.StandardCharsets;
26  import java.util.Arrays;
27  
28  import org.junit.jupiter.api.Test;
29  
30  import com.puppycrawl.tools.checkstyle.AbstractTreeTestSupport;
31  import com.puppycrawl.tools.checkstyle.AstTreeStringPrinter;
32  import com.puppycrawl.tools.checkstyle.JavaParser;
33  import com.puppycrawl.tools.checkstyle.api.FileText;
34  
35  public class AstRegressionTest extends AbstractTreeTestSupport {
36  
37      @Override
38      protected String getPackageLocation() {
39          return "com/puppycrawl/tools/checkstyle/grammar";
40      }
41  
42      @Test
43      public void testClassAstTree1() throws Exception {
44          verifyAst(getPath("ExpectedRegressionJavaClass1Ast.txt"),
45                  getPath("InputRegressionJavaClass1.java"));
46      }
47  
48      @Test
49      public void testClassAstTree2() throws Exception {
50          verifyAst(getPath("ExpectedRegressionJavaClass2Ast.txt"),
51                  getPath("InputRegressionJavaClass2.java"));
52      }
53  
54      @Test
55      public void testJava8ClassAstTree1() throws Exception {
56          verifyAst(getPath("ExpectedRegressionJava8Class1Ast.txt"),
57                  getPath("InputRegressionJava8Class1.java"));
58      }
59  
60      @Test
61      public void testJava8ClassAstTree2() throws Exception {
62          verifyAst(getPath("ExpectedRegressionJava8Class2Ast.txt"),
63                  getPath("InputRegressionJava8Class2.java"));
64      }
65  
66      @Test
67      public void testJava9TryWithResourcesAstTree() throws Exception {
68          verifyAst(getPath("ExpectedJava9TryWithResources.txt"),
69                  getPath("/java9/InputJava9TryWithResources.java"));
70      }
71  
72      @Test
73      public void testAdvanceJava9TryWithResourcesAstTree() throws Exception {
74          verifyAst(getPath("ExpectedAdvanceJava9TryWithResources.txt"),
75                  getPath("/java9/InputAdvanceJava9TryWithResources.java"));
76      }
77  
78      @Test
79      public void testInputSemicolonBetweenImports() throws Exception {
80          verifyAst(getPath("ExpectedSemicolonBetweenImportsAst.txt"),
81                  getNonCompilablePath("InputSemicolonBetweenImports.java"));
82      }
83  
84      @Test
85      public void testInterfaceAstTree1() throws Exception {
86          verifyAst(getPath("ExpectedRegressionJavaInterface1Ast.txt"),
87                  getPath("InputRegressionJavaInterface1.java"));
88      }
89  
90      @Test
91      public void testInterfaceAstTree2() throws Exception {
92          verifyAst(getPath("ExpectedRegressionJavaInterface2Ast.txt"),
93                  getPath("InputRegressionJavaInterface2.java"));
94      }
95  
96      @Test
97      public void testJava8InterfaceAstTree1() throws Exception {
98          verifyAst(getPath("ExpectedRegressionJava8Interface1Ast.txt"),
99                  getPath("InputRegressionJava8Interface1.java"));
100     }
101 
102     @Test
103     public void testEnumAstTree1() throws Exception {
104         verifyAst(getPath("ExpectedRegressionJavaEnum1Ast.txt"),
105                 getPath("InputRegressionJavaEnum1.java"));
106     }
107 
108     @Test
109     public void testEnumAstTree2() throws Exception {
110         verifyAst(getPath("ExpectedRegressionJavaEnum2Ast.txt"),
111                 getPath("InputRegressionJavaEnum2.java"));
112     }
113 
114     @Test
115     public void testAnnotationAstTree1() throws Exception {
116         verifyAst(getPath("ExpectedRegressionJavaAnnotation1Ast.txt"),
117                 getPath("InputRegressionJavaAnnotation1.java"));
118     }
119 
120     @Test
121     public void testTypecast() throws Exception {
122         verifyAst(getPath("ExpectedRegressionJavaTypecastAst.txt"),
123                 getPath("InputRegressionJavaTypecast.java"));
124     }
125 
126     @Test
127     public void testJava14InstanceofWithPatternMatching() throws Exception {
128         verifyAst(getPath("java14/ExpectedJava14InstanceofWithPatternMatchingAST.txt"),
129                 getNonCompilablePath("java14/InputJava14InstanceofWithPatternMatching.java"));
130     }
131 
132     @Test
133     public void testCharLiteralSurrogatePair() throws Exception {
134         verifyAst(getPath("ExpectedCharLiteralSurrogatePair.txt"),
135                 getPath("InputCharLiteralSurrogatePair.java"));
136     }
137 
138     @Test
139     public void testCustomAstTree() throws Exception {
140         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\t");
141         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\r\n");
142         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\n");
143         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\r\r");
144         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\r");
145         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "\u000c\f");
146         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "// \n",
147                 JavaParser.Options.WITH_COMMENTS);
148         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "// \r",
149                 JavaParser.Options.WITH_COMMENTS);
150         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "// \r\n",
151                 JavaParser.Options.WITH_COMMENTS);
152         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "/* \n */",
153                 JavaParser.Options.WITH_COMMENTS);
154         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "/* \r\n */",
155                 JavaParser.Options.WITH_COMMENTS);
156         verifyAstRaw(getPath("ExpectedRegressionEmptyAst.txt"), "/* \r" + "\u0000\u0000" + " */",
157                 JavaParser.Options.WITH_COMMENTS);
158     }
159 
160     @Test
161     public void testNewlineCr() throws Exception {
162         verifyAst(getPath("ExpectedNewlineCrAtEndOfFileAst.txt"),
163                 getPath("InputAstRegressionNewlineCrAtEndOfFile.java"),
164                 JavaParser.Options.WITH_COMMENTS);
165     }
166 
167     @Test
168     public void testJava14Records() throws Exception {
169         verifyAst(getPath("java14/ExpectedJava14Records.txt"),
170                 getNonCompilablePath("java14/InputJava14Records.java"));
171     }
172 
173     @Test
174     public void testJava14RecordsTopLevel() throws Exception {
175         verifyAst(getPath("java14/ExpectedJava14RecordsTopLevel.txt"),
176                 getNonCompilablePath("java14/InputJava14RecordsTopLevel.java"));
177     }
178 
179     @Test
180     public void testJava14LocalRecordAnnotation() throws Exception {
181         verifyAst(getPath("java14/ExpectedJava14LocalRecordAnnotation.txt"),
182             getNonCompilablePath("java14/InputJava14LocalRecordAnnotation.java"));
183     }
184 
185     @Test
186     public void testJava14TextBlocks() throws Exception {
187         verifyAst(getPath("java14/ExpectedJava14TextBlocks.txt"),
188                 getNonCompilablePath("java14/InputJava14TextBlocks.java"));
189     }
190 
191     @Test
192     public void testJava14TextBlocksEscapes() throws Exception {
193         verifyAst(getPath("java14/ExpectedJava14TextBlocksEscapesAreOneChar.txt"),
194                 getNonCompilablePath("java14/InputJava14TextBlocksEscapesAreOneChar.java"));
195     }
196 
197     @Test
198     public void testJava14SwitchExpression() throws Exception {
199         verifyAst(getPath("java14/ExpectedJava14SwitchExpression.txt"),
200                 getNonCompilablePath("java14/InputJava14SwitchExpression.java"));
201     }
202 
203     @Test
204     public void testInputJava14TextBlocksTabSize() throws Exception {
205         verifyAst(getPath("java14/ExpectedJava14TextBlocksTabSize.txt"),
206             getNonCompilablePath("java14/InputJava14TextBlocksTabSize.java"));
207     }
208 
209     @Test
210     public void testInputEscapedS() throws Exception {
211         verifyAst(getPath("java14/ExpectedJava14EscapedS.txt"),
212                 getNonCompilablePath("java14/InputJava14EscapedS.java"));
213     }
214 
215     @Test
216     public void testInputSealedAndPermits() throws Exception {
217         verifyAst(getPath("java15/ExpectedAstRegressionSealedAndPermits.txt"),
218             getNonCompilablePath("java15/InputAstRegressionSealedAndPermits.java"));
219     }
220 
221     @Test
222     public void testInputTopLevelNonSealed() throws Exception {
223         verifyAst(getPath("java15/ExpectedTopLevelNonSealed.txt"),
224             getNonCompilablePath("java15/InputTopLevelNonSealed.java"));
225     }
226 
227     @Test
228     public void testPatternVariableWithModifiers() throws Exception {
229         verifyAst(getPath("java16/ExpectedPatternVariableWithModifiers.txt"),
230                 getNonCompilablePath("java16/InputPatternVariableWithModifiers.java"));
231     }
232 
233     @Test
234     public void testInputMethodDefArrayDeclarator() throws Exception {
235         verifyAst(getPath("ExpectedAstRegressionMethodDefArrayDeclarator.txt"),
236                 getPath("InputAstRegressionMethodDefArrayDeclarator.java"));
237     }
238 
239     @Test
240     public void testInputCstyleArrayDefinition() throws Exception {
241         verifyAst(getPath("ExpectedAstRegressionCStyleArrayDefinition.txt"),
242                 getPath("InputAstRegressionCStyleArrayDefinition.java"));
243     }
244 
245     @Test
246     public void testInputAnnotatedMethodVariableArityParam() throws Exception {
247         verifyAst(getPath("ExpectedAstRegressionAnnotatedMethodVariableArityParam.txt"),
248                 getPath("InputAstRegressionAnnotatedMethodVariableArityParam.java"));
249     }
250 
251     @Test
252     public void testInputManyAlternativesInMultiCatch() throws Exception {
253         verifyAst(getPath("ExpectedAstRegressionManyAlternativesInMultiCatch.txt"),
254                 getPath("InputAstRegressionManyAlternativesInMultiCatch.java"));
255     }
256 
257     private static void verifyAstRaw(String expectedTextPrintFileName, String actualJava)
258             throws Exception {
259         verifyAstRaw(expectedTextPrintFileName, actualJava, JavaParser.Options.WITHOUT_COMMENTS);
260     }
261 
262     private static void verifyAstRaw(String expectedTextPrintFileName, String actualJava,
263             JavaParser.Options withComments) throws Exception {
264         final File expectedFile = new File(expectedTextPrintFileName);
265         final String expectedContents = new FileText(expectedFile, System.getProperty(
266                 "file.encoding", StandardCharsets.UTF_8.name()))
267                 .getFullText().toString().replace("\r", "");
268 
269         final FileText actualFileContents = new FileText(new File(""),
270                 Arrays.asList(actualJava.split("\\n|\\r\\n?")));
271         final String actualContents = AstTreeStringPrinter.printAst(actualFileContents,
272                 withComments);
273 
274         assertWithMessage("Generated AST from Java code should match pre-defined AST")
275             .that(actualContents)
276             .isEqualTo(expectedContents);
277     }
278 }