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.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      public 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             assertWithMessage("Invalid exception message,")
118                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
119                 .isEqualTo("the following values are not valid identifiers: ["
120                     + "com.puppycrawl.tools.checkstyle.checks.metrics.inputs.a.]");
121         }
122     }
123 
124     @Test
125     public void testExcludedPackageCommonPackagesAllIgnored() throws Exception {
126         final String[] expected = {
127             "28:1: " + getCheckMessage(MSG_KEY, 1, 0, "[StrTokenizer]"),
128             "32:5: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
129             "38:1: " + getCheckMessage(MSG_KEY, 1, 0, "[BasicThreadFactory.Builder]"),
130         };
131 
132         verifyWithInlineConfigParser(
133                 getPath("InputClassDataAbstractionCouplingExcludedPackagesDirectPackages.java"),
134                 expected);
135     }
136 
137     @Test
138     public void testDefaultConfiguration() throws Exception {
139         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
140         verifyWithInlineConfigParser(
141                 getPath("InputClassDataAbstractionCoupling2.java"), expected);
142     }
143 
144     @Test
145     public void testWrongToken() {
146         final ClassDataAbstractionCouplingCheck classDataAbstractionCouplingCheckObj =
147             new ClassDataAbstractionCouplingCheck();
148         final DetailAstImpl ast = new DetailAstImpl();
149         ast.initialize(new CommonToken(TokenTypes.CTOR_DEF, "ctor"));
150         try {
151             classDataAbstractionCouplingCheckObj.visitToken(ast);
152             assertWithMessage("exception expected").fail();
153         }
154         catch (IllegalArgumentException exc) {
155             assertWithMessage("Invalid exception message")
156                 .that(exc.getMessage())
157                 .isEqualTo("Unknown type: ctor[0x-1]");
158         }
159     }
160 
161     @Test
162     public void testRegularExpression() throws Exception {
163 
164         final String[] expected = {
165             "22:1: " + getCheckMessage(MSG_KEY, 2, 0, "[AnotherInnerClass, int]"),
166             "23:5: " + getCheckMessage(MSG_KEY, 1, 0, "[ArrayList]"),
167         };
168 
169         verifyWithInlineConfigParser(
170                 getPath("InputClassDataAbstractionCoupling3.java"), expected);
171     }
172 
173     @Test
174     public void testEmptyRegularExpression() throws Exception {
175 
176         final String[] expected = {
177             "22:1: " + getCheckMessage(MSG_KEY, 4, 0, "[AnotherInnerClass, HashMap, HashSet, int]"),
178             "23:5: " + getCheckMessage(MSG_KEY, 1, 0, "[ArrayList]"),
179             "43:1: " + getCheckMessage(MSG_KEY, 2, 0, "[HashMap, HashSet]"),
180         };
181 
182         verifyWithInlineConfigParser(
183                 getPath("InputClassDataAbstractionCoupling4.java"), expected);
184     }
185 
186     @Test
187     public void testClassDataAbstractionCouplingRecords() throws Exception {
188 
189         final int maxAbstraction = 1;
190         final String[] expected = {
191             "31:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
192             "36:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
193             "46:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
194             "55:1: " + getCheckMessage(MSG_KEY, 2, maxAbstraction, "[Date, Time]"),
195             "67:5: " + getCheckMessage(MSG_KEY, 3, maxAbstraction, "[Date, Place, Time]"),
196         };
197 
198         verifyWithInlineConfigParser(
199                 getPath("InputClassDataAbstractionCouplingRecords.java"),
200             expected);
201     }
202 
203     @Test
204     public void testNew() throws Exception {
205 
206         final String[] expected = {
207             "19:1: " + getCheckMessage(MSG_KEY, 2, 0, "[File, Random]"),
208         };
209         verifyWithInlineConfigParser(
210                 getPath("InputClassDataAbstractionCoupling5.java"), expected);
211     }
212 
213 }