View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2011-2026 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.qulice.pmd;
6   
7   import com.jcabi.matchers.RegexMatchers;
8   import org.hamcrest.Matchers;
9   import org.hamcrest.core.IsEqual;
10  import org.hamcrest.core.IsNot;
11  import org.junit.jupiter.api.Test;
12  
13  /**
14   * Test case for {@link PmdValidator}'s enforcement of the qulice
15   * constructor rules: fields must be initialized either outside the
16   * constructor or in a single constructor, and constructors may only
17   * delegate or initialize fields.
18   *
19   * @since 0.25.1
20   */
21  final class PmdConstructorTest {
22  
23      /**
24       * Pattern for non-constructor field initialization.
25       */
26      private static final String NO_CON_INIT =
27          "%s\\[\\d+-\\d+\\]: Avoid doing field initialization outside constructor.";
28  
29      /**
30       * Pattern for multiple constructors field initialization.
31       */
32      private static final String MULT_CON_INIT =
33          "%s\\[\\d+-\\d+\\]: Avoid field initialization in several constructors.";
34  
35      /**
36       * Pattern for code in constructor other than field init or delegation.
37       */
38      private static final String CODE_IN_CON =
39          "%s\\[\\d+-\\d+\\]: Only field initialization or call to other constructors in a constructor";
40  
41      @Test
42      void allowsFieldInitializationWhenConstructorIsMissing() throws Exception {
43          final String file = "FieldInitNoConstructor.java";
44          new PmdAssert(
45              file,
46              Matchers.is(true),
47              Matchers.not(
48                  RegexMatchers.containsPattern(
49                      String.format(PmdConstructorTest.NO_CON_INIT, file)
50                  )
51              )
52          ).assertOk();
53      }
54  
55      @Test
56      void forbidsFieldInitializationWhenConstructorExists() throws Exception {
57          final String file = "FieldInitConstructor.java";
58          new PmdAssert(
59              file,
60              Matchers.is(false),
61              RegexMatchers.containsPattern(
62                  String.format(PmdConstructorTest.NO_CON_INIT, file)
63              )
64          ).assertOk();
65      }
66  
67      @Test
68      void allowsStaticFieldInitializationWhenConstructorExists()
69          throws Exception {
70          final String file = "StaticFieldInitConstructor.java";
71          new PmdAssert(
72              file,
73              Matchers.is(true),
74              Matchers.not(
75                  RegexMatchers.containsPattern(
76                      String.format(PmdConstructorTest.NO_CON_INIT, file)
77                  )
78              )
79          ).assertOk();
80      }
81  
82      @Test
83      void forbidsFieldInitializationInSeveralConstructors() throws Exception {
84          final String file = "FieldInitSeveralConstructors.java";
85          new PmdAssert(
86              file,
87              Matchers.is(false),
88              RegexMatchers.containsPattern(
89                  String.format(PmdConstructorTest.MULT_CON_INIT, file)
90              )
91          ).assertOk();
92      }
93  
94      @Test
95      void allowsFieldInitializationInOneConstructor() throws Exception {
96          final String file = "FieldInitOneConstructor.java";
97          new PmdAssert(
98              file,
99              Matchers.is(true),
100             Matchers.not(
101                 RegexMatchers.containsPattern(
102                     String.format(PmdConstructorTest.MULT_CON_INIT, file)
103                 )
104             )
105         ).assertOk();
106     }
107 
108     @Test
109     void forbidsCodeInConstructor() throws Exception {
110         final String file = "CodeInConstructor.java";
111         new PmdAssert(
112             file,
113             Matchers.is(false),
114             RegexMatchers.containsPattern(
115                 String.format(PmdConstructorTest.CODE_IN_CON, file)
116             )
117         ).assertOk();
118     }
119 
120     @Test
121     void allowsLambdaInConstructor() throws Exception {
122         final String file = "LambdaInConstructor.java";
123         new PmdAssert(
124             file,
125             new IsEqual<>(true),
126             new IsNot<>(
127                 RegexMatchers.containsPattern(
128                     String.format(PmdConstructorTest.CODE_IN_CON, file)
129                 )
130             )
131         ).assertOk();
132     }
133 
134     @Test
135     void acceptsCallToConstructorInConstructor() throws Exception {
136         final String file = "CallToConstructorInConstructor.java";
137         new PmdAssert(
138             file,
139             Matchers.is(true),
140             Matchers.not(
141                 RegexMatchers.containsPattern(
142                     String.format(PmdConstructorTest.CODE_IN_CON, file)
143                 )
144             )
145         ).assertOk();
146     }
147 }