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   * @since 0.25.1
19   */
20  final class PmdConstructorTest {
21  
22      /**
23       * Pattern for non-constructor field initialization.
24       */
25      private static final String NO_CON_INIT =
26          "%s\\[\\d+-\\d+\\]: Avoid doing field initialization outside constructor.";
27  
28      /**
29       * Pattern for multiple constructors field initialization.
30       */
31      private static final String MULT_CON_INIT =
32          "%s\\[\\d+-\\d+\\]: Avoid field initialization in several constructors.";
33  
34      /**
35       * Pattern for code in constructor other than field init or delegation.
36       */
37      private static final String CODE_IN_CON =
38          "%s\\[\\d+-\\d+\\]: Only field initialization or call to other constructors in a constructor";
39  
40      @Test
41      void allowsFieldInitializationWhenConstructorIsMissing() throws Exception {
42          final String file = "FieldInitNoConstructor.java";
43          new PmdAssert(
44              file,
45              Matchers.is(true),
46              Matchers.not(
47                  RegexMatchers.containsPattern(
48                      String.format(PmdConstructorTest.NO_CON_INIT, file)
49                  )
50              )
51          ).assertOk();
52      }
53  
54      @Test
55      void forbidsFieldInitializationWhenConstructorExists() throws Exception {
56          final String file = "FieldInitConstructor.java";
57          new PmdAssert(
58              file,
59              Matchers.is(false),
60              RegexMatchers.containsPattern(
61                  String.format(PmdConstructorTest.NO_CON_INIT, file)
62              )
63          ).assertOk();
64      }
65  
66      @Test
67      void allowsStaticFieldInitializationWhenConstructorExists()
68          throws Exception {
69          final String file = "StaticFieldInitConstructor.java";
70          new PmdAssert(
71              file,
72              Matchers.is(true),
73              Matchers.not(
74                  RegexMatchers.containsPattern(
75                      String.format(PmdConstructorTest.NO_CON_INIT, file)
76                  )
77              )
78          ).assertOk();
79      }
80  
81      @Test
82      void forbidsFieldInitializationInSeveralConstructors() throws Exception {
83          final String file = "FieldInitSeveralConstructors.java";
84          new PmdAssert(
85              file,
86              Matchers.is(false),
87              RegexMatchers.containsPattern(
88                  String.format(PmdConstructorTest.MULT_CON_INIT, file)
89              )
90          ).assertOk();
91      }
92  
93      @Test
94      void allowsFieldInitializationInOneConstructor() throws Exception {
95          final String file = "FieldInitOneConstructor.java";
96          new PmdAssert(
97              file,
98              Matchers.is(true),
99              Matchers.not(
100                 RegexMatchers.containsPattern(
101                     String.format(PmdConstructorTest.MULT_CON_INIT, file)
102                 )
103             )
104         ).assertOk();
105     }
106 
107     @Test
108     void forbidsCodeInConstructor() throws Exception {
109         final String file = "CodeInConstructor.java";
110         new PmdAssert(
111             file,
112             Matchers.is(false),
113             RegexMatchers.containsPattern(
114                 String.format(PmdConstructorTest.CODE_IN_CON, file)
115             )
116         ).assertOk();
117     }
118 
119     @Test
120     void allowsLambdaInConstructor() throws Exception {
121         final String file = "LambdaInConstructor.java";
122         new PmdAssert(
123             file,
124             new IsEqual<>(true),
125             new IsNot<>(
126                 RegexMatchers.containsPattern(
127                     String.format(PmdConstructorTest.CODE_IN_CON, file)
128                 )
129             )
130         ).assertOk();
131     }
132 
133     @Test
134     void acceptsCallToConstructorInConstructor() throws Exception {
135         final String file = "CallToConstructorInConstructor.java";
136         new PmdAssert(
137             file,
138             Matchers.is(true),
139             Matchers.not(
140                 RegexMatchers.containsPattern(
141                     String.format(PmdConstructorTest.CODE_IN_CON, file)
142                 )
143             )
144         ).assertOk();
145     }
146 }