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.checks.metrics;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.metrics.ClassDataAbstractionCouplingCheck.MSG_KEY;
24  
25  import org.antlr.v4.runtime.CommonToken;
26  import org.junit.jupiter.api.Test;
27  
28  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
29  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
30  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
31  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
32  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
34  
35  public class ClassDataAbstractionCouplingCheckTest extends AbstractModuleTestSupport {
36  
37      @Override
38      protected String getPackageLocation() {
39          return "com/puppycrawl/tools/checkstyle/checks/metrics/classdataabstractioncoupling";
40      }
41  
42      @Test
43      public void testTokens() {
44          final ClassDataAbstractionCouplingCheck check = new ClassDataAbstractionCouplingCheck();
45          assertWithMessage("Required tokens should not be null")
46              .that(check.getRequiredTokens())
47              .isNotNull();
48          assertWithMessage("Acceptable tokens should not be null")
49              .that(check.getAcceptableTokens())
50              .isNotNull();
51          assertWithMessage("Invalid default tokens")
52              .that(check.getAcceptableTokens())
53              .isEqualTo(check.getDefaultTokens());
54          assertWithMessage("Invalid acceptable tokens")
55              .that(check.getRequiredTokens())
56              .isEqualTo(check.getDefaultTokens());
57      }
58  
59      @Test
60      public void test() throws Exception {
61  
62          final String[] expected = {
63              "16:1: " + getCheckMessage(MSG_KEY, 4, 0, "[AnotherInnerClass, HashMap, HashSet, int]"),
64              "17:5: " + getCheckMessage(MSG_KEY, 1, 0, "[ArrayList]"),
65              "37:1: " + getCheckMessage(MSG_KEY, 2, 0, "[HashMap, HashSet]"),
66          };
67  
68          verifyWithInlineConfigParser(
69                  getPath("InputClassDataAbstractionCoupling.java"), expected);
70      }
71  
72      @Test
73      public void testExcludedPackageDirectPackages() throws Exception {
74          final String[] expected = {
75              "28:1: " + getCheckMessage(MSG_KEY, 1, 0, "[StrTokenizer]"),
76              "32:5: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
77              "38:1: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
78          };
79  
80          verifyWithInlineConfigParser(
81                  getPath("InputClassDataAbstractionCouplingExcludedPackagesDirectPackages.java"),
82                  expected);
83      }
84  
85      @Test
86      public void testExcludedPackageCommonPackages() throws Exception {
87          final String[] expected = {
88              "28:1: " + getCheckMessage(MSG_KEY, 2, 0, "[ImmutablePair, StrTokenizer]"),
89              "32:5: " + getCheckMessage(MSG_KEY, 2, 0, "[BasicThreadFactory.Builder, MutablePair]"),
90              "38:1: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
91          };
92  
93          verifyWithInlineConfigParser(
94                  getPath("InputClassDataAbstractionCouplingExcludedPackagesCommonPackage.java"),
95                  expected);
96      }
97  
98      @Test
99      public void testExcludedPackageWithEndingDot() throws Exception {
100         final DefaultConfiguration checkConfig =
101             createModuleConfig(ClassDataAbstractionCouplingCheck.class);
102 
103         checkConfig.addProperty("max", "0");
104         checkConfig.addProperty("excludedPackages",
105             "com.puppycrawl.tools.checkstyle.checks.metrics.inputs.a.");
106 
107         try {
108             createChecker(checkConfig);
109             assertWithMessage("exception expected").fail();
110         }
111         catch (CheckstyleException exc) {
112             assertWithMessage("Invalid exception message")
113                 .that(exc.getMessage())
114                 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
115                     + "cannot initialize module com.puppycrawl.tools.checkstyle.checks."
116                     + "metrics.ClassDataAbstractionCouplingCheck - "
117                     + "Cannot set property 'excludedPackages' to "
118                     + "'com.puppycrawl.tools.checkstyle.checks.metrics.inputs.a.'");
119             assertWithMessage("Invalid exception message,")
120                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
121                 .isEqualTo("the following values are not valid identifiers: ["
122                     + "com.puppycrawl.tools.checkstyle.checks.metrics.inputs.a.]");
123         }
124     }
125 
126     @Test
127     public void testExcludedPackageCommonPackagesAllIgnored() throws Exception {
128         final String[] expected = {
129             "28:1: " + getCheckMessage(MSG_KEY, 1, 0, "[StrTokenizer]"),
130             "32:5: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
131             "38:1: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
132         };
133 
134         verifyWithInlineConfigParser(
135                 getPath("InputClassDataAbstractionCouplingExcludedPackagesDirectPackages.java"),
136                 expected);
137     }
138 
139     @Test
140     public void testDefaultConfiguration() throws Exception {
141         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
142         verifyWithInlineConfigParser(
143                 getPath("InputClassDataAbstractionCoupling2.java"), expected);
144     }
145 
146     @Test
147     public void testWrongToken() {
148         final ClassDataAbstractionCouplingCheck classDataAbstractionCouplingCheckObj =
149             new ClassDataAbstractionCouplingCheck();
150         final DetailAstImpl ast = new DetailAstImpl();
151         ast.initialize(new CommonToken(TokenTypes.CTOR_DEF, "ctor"));
152         try {
153             classDataAbstractionCouplingCheckObj.visitToken(ast);
154             assertWithMessage("exception expected").fail();
155         }
156         catch (IllegalArgumentException exc) {
157             assertWithMessage("Invalid exception message")
158                 .that(exc.getMessage())
159                 .isEqualTo("Unknown type: ctor[0x-1]");
160         }
161     }
162 
163     @Test
164     public void testRegularExpression() throws Exception {
165 
166         final String[] expected = {
167             "22:1: " + getCheckMessage(MSG_KEY, 2, 0, "[AnotherInnerClass, int]"),
168             "23:5: " + getCheckMessage(MSG_KEY, 1, 0, "[ArrayList]"),
169         };
170 
171         verifyWithInlineConfigParser(
172                 getPath("InputClassDataAbstractionCoupling3.java"), expected);
173     }
174 
175     @Test
176     public void testEmptyRegularExpression() throws Exception {
177 
178         final String[] expected = {
179             "22:1: " + getCheckMessage(MSG_KEY, 4, 0, "[AnotherInnerClass, HashMap, HashSet, int]"),
180             "23:5: " + getCheckMessage(MSG_KEY, 1, 0, "[ArrayList]"),
181             "43:1: " + getCheckMessage(MSG_KEY, 2, 0, "[HashMap, HashSet]"),
182         };
183 
184         verifyWithInlineConfigParser(
185                 getPath("InputClassDataAbstractionCoupling4.java"), expected);
186     }
187 
188     @Test
189     public void testClassDataAbstractionCouplingRecords() throws Exception {
190 
191         final int maxAbstraction = 1;
192         final String[] expected = {
193             "31:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
194             "36:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
195             "46:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
196             "55:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
197             "67:5: " + getCheckMessage(MSG_KEY, 3, maxAbstraction, "[Date, Place, Time]"),
198         };
199 
200         verifyWithInlineConfigParser(
201                 getPath("InputClassDataAbstractionCouplingRecords.java"),
202             expected);
203     }
204 
205     @Test
206     public void testNew() throws Exception {
207 
208         final String[] expected = {
209             "19:1: " + getCheckMessage(MSG_KEY, 2, 0, "[File, Random]"),
210         };
211         verifyWithInlineConfigParser(
212                 getPath("InputClassDataAbstractionCoupling5.java"), expected);
213     }
214 
215 }