1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.BooleanExpressionComplexityCheck.MSG_KEY;
24 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
25
26 import java.io.File;
27 import java.util.Deque;
28
29 import org.antlr.v4.runtime.CommonToken;
30 import org.junit.jupiter.api.Test;
31
32 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
34 import com.puppycrawl.tools.checkstyle.JavaParser;
35 import com.puppycrawl.tools.checkstyle.api.DetailAST;
36 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
38 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
39
40 public class BooleanExpressionComplexityCheckTest extends AbstractModuleTestSupport {
41
42 @Override
43 public String getPackageLocation() {
44 return "com/puppycrawl/tools/checkstyle/checks/metrics/booleanexpressioncomplexity";
45 }
46
47 @Test
48 public void test() throws Exception {
49
50 final String[] expected = {
51 "21:9: " + getCheckMessage(MSG_KEY, 4, 3),
52 "39:46: " + getCheckMessage(MSG_KEY, 4, 3),
53 "50:9: " + getCheckMessage(MSG_KEY, 6, 3),
54 "57:34: " + getCheckMessage(MSG_KEY, 4, 3),
55 "60:34: " + getCheckMessage(MSG_KEY, 4, 3),
56 };
57
58 verifyWithInlineConfigParser(
59 getPath("InputBooleanExpressionComplexity.java"), expected);
60 }
61
62 @Test
63 public void testNoBitwise() throws Exception {
64
65 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
66
67 verifyWithInlineConfigParser(
68 getPath("InputBooleanExpressionComplexity2.java"), expected);
69 }
70
71 @Test
72 public void testNullPointerException() throws Exception {
73
74 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
75
76 verifyWithInlineConfigParser(
77 getPath("InputBooleanExpressionComplexityNPE.java"), expected);
78 }
79
80 @Test
81 public void testWrongToken() {
82 final BooleanExpressionComplexityCheck booleanExpressionComplexityCheckObj =
83 new BooleanExpressionComplexityCheck();
84 final DetailAstImpl ast = new DetailAstImpl();
85 ast.initialize(new CommonToken(TokenTypes.INTERFACE_DEF, "interface"));
86 final IllegalArgumentException exc =
87 getExpectedThrowable(IllegalArgumentException.class,
88 () -> booleanExpressionComplexityCheckObj.visitToken(ast));
89 assertWithMessage("Invalid exception message")
90 .that(exc.getMessage())
91 .isEqualTo("Unknown type: interface[0x-1]");
92 }
93
94 @Test
95 public void testSmall() throws Exception {
96
97 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
98
99 verifyWithInlineConfigParser(
100 getPath("InputBooleanExpressionComplexitySmall.java"), expected);
101 }
102
103 @Test
104 public void testBooleanExpressionComplexityRecordsAndCompactCtors() throws Exception {
105
106 final int max = 3;
107
108 final String[] expected = {
109 "16:12: " + getCheckMessage(MSG_KEY, 4, max),
110 "25:23: " + getCheckMessage(MSG_KEY, 4, max),
111 "37:23: " + getCheckMessage(MSG_KEY, 4, max),
112 "48:27: " + getCheckMessage(MSG_KEY, 4, max),
113 };
114
115 verifyWithInlineConfigParser(
116 getPath(
117 "InputBooleanExpressionComplexityRecordsAndCompactCtors.java"),
118 expected);
119 }
120
121 @Test
122 public void testLeaves() throws Exception {
123
124 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
125
126 verifyWithInlineConfigParser(
127 getPath("InputBooleanExpressionComplexityLeaves.java"), expected);
128 }
129
130 @Test
131 public void testRecordLeaves() throws Exception {
132
133 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
134
135 verifyWithInlineConfigParser(
136 getPath("InputBooleanExpressionComplexityRecordLeaves.java"),
137 expected);
138 }
139
140 @Test
141 public void testWhenExpression() throws Exception {
142
143 final int max = 0;
144
145 final String[] expected = {
146 "17:21: " + getCheckMessage(MSG_KEY, 6, max),
147 "21:17: " + getCheckMessage(MSG_KEY, 6, max),
148 "25:27: " + getCheckMessage(MSG_KEY, 6, max),
149 "29:48: " + getCheckMessage(MSG_KEY, 1, max),
150 };
151
152 verifyWithInlineConfigParser(
153 getNonCompilablePath("InputBooleanExpressionComplexityWhenExpression.java"),
154 expected);
155 }
156
157
158
159
160
161
162
163
164 @Test
165 public void testClearState() throws Exception {
166 final BooleanExpressionComplexityCheck check = new BooleanExpressionComplexityCheck();
167 final DetailAST root = JavaParser.parseFile(
168 new File(getPath("InputBooleanExpressionComplexity.java")),
169 JavaParser.Options.WITHOUT_COMMENTS);
170 final DetailAST method = TestUtil.findTokenInAstByPredicate(root, ast -> {
171 return ast.getType() == TokenTypes.METHOD_DEF;
172 }).orElseThrow();
173 final DetailAST operator = TestUtil.findTokenInAstByPredicate(method, ast -> {
174 return ast.getType() == TokenTypes.LAND;
175 }).orElseThrow();
176
177 check.visitToken(method);
178 check.visitToken(operator);
179 final Object context = TestUtil.getInternalState(check, "context", Object.class);
180 assertWithMessage("Context should be checking before beginTree")
181 .that(TestUtil.getInternalState(context, "checking", Boolean.class))
182 .isTrue();
183 assertWithMessage("Context should count the visited operator")
184 .that(TestUtil.getInternalState(context, "count", Integer.class))
185 .isEqualTo(1);
186
187 check.beginTree(root);
188
189 assertWithMessage("Context stack is not cleared on beginTree")
190 .that(TestUtil.getInternalState(check, "contextStack", Deque.class))
191 .isEmpty();
192 final Object resetContext = TestUtil.getInternalState(check, "context", Object.class);
193 assertWithMessage("Context checking flag is not reset on beginTree")
194 .that(TestUtil.getInternalState(resetContext, "checking", Boolean.class))
195 .isFalse();
196 assertWithMessage("Context count is not reset on beginTree")
197 .that(TestUtil.getInternalState(resetContext, "count", Integer.class))
198 .isEqualTo(0);
199 }
200
201 }