View Javadoc
1   package com.github.mikkoi.maven.plugins.enforcer.rule.propertyusage;
2   
3   import com.github.mikkoi.maven.plugins.enforcer.rule.propertyusage.configuration.FileSpecs;
4   import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
5   import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
6   import org.apache.maven.plugins.enforcer.EnforcerTestUtils;
7   import org.junit.Rule;
8   import org.junit.Test;
9   import org.junit.rules.TemporaryFolder;
10  
11  import javax.annotation.Nonnull;
12  import javax.annotation.Nullable;
13  import java.io.File;
14  import java.nio.charset.Charset;
15  import java.nio.file.Files;
16  import java.nio.file.StandardOpenOption;
17  import java.util.Collection;
18  import java.util.Collections;
19  import java.util.HashSet;
20  import java.util.Set;
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertTrue;
24  
25  /**
26   * Test class PropertyUsageRule.
27   */
28  public final class PropertyUsageRuleTest {
29  
30      private void testProps(
31              // Configuration (null value => use defaults)
32              @Nullable final Boolean definitionsOnlyOnce,
33              @Nullable final Boolean definedPropertiesAreUsed,
34              @Nullable final Boolean usedPropertiesAreDefined,
35              @Nullable final String replaceInTemplateWithPropertyName,
36              @Nullable final Collection<String> definitions,
37              @Nullable final Collection<String> templates,
38              @Nullable final Collection<String> usages,
39              // Results
40              boolean rulePasses, // Rule passes.
41              @Nonnull final Collection<String> propertiesDefinedMoreThanOnce, // There names were defined more than once.
42              @Nonnull final Collection<String> propertiesNotUsed, // These names were never used.
43              @Nonnull final Collection<String> propertiesNotDefined // These names were not defined.
44      ) {
45          boolean isValid;
46          PropertyUsageRule rule = new PropertyUsageRule();
47  
48          // Configuration.
49          if (definitionsOnlyOnce != null) {
50              rule.setDefinitionsOnlyOnce(definitionsOnlyOnce);
51          }
52          if (definedPropertiesAreUsed != null) {
53              rule.setDefinedPropertiesAreUsed(definedPropertiesAreUsed);
54          }
55          if (usedPropertiesAreDefined != null) {
56              rule.setUsedPropertiesAreDefined(usedPropertiesAreDefined);
57          }
58          if (definitions != null) {
59              rule.setDefinitions(definitions);
60          }
61          if (templates != null) {
62              rule.setTemplates(templates);
63          }
64          if (usages != null) {
65              rule.setUsages(usages);
66          }
67          if (replaceInTemplateWithPropertyName != null) {
68              rule.setReplaceInTemplateWithPropertyName(replaceInTemplateWithPropertyName);
69          }
70  
71          // Run rule.
72          try {
73              EnforcerRuleHelper helper = EnforcerTestUtils.getHelper();
74              rule.execute(helper);
75              isValid = true;
76          } catch (EnforcerRuleException e) {
77              if (!rulePasses) {
78                  System.err.println("Rule broken. Error:" + e.getLocalizedMessage());
79              }
80              isValid = false;
81          }
82          assertTrue("Success or failure is as expected.", isValid == rulePasses);
83          assertTrue("Properties not used as expected.", !rule.isDefinedPropertiesAreUsed() || rule.getPropertiesNotUsed().equals(propertiesNotUsed));
84          final Set<String> resultPropertiesNodDefined = new HashSet<>();
85          rule.getPropertiesNotDefined().forEach(val -> resultPropertiesNodDefined.add(val.getProperty()));
86          assertTrue("Properties not defined as expected.", rule.isUsedPropertiesAreDefined() || resultPropertiesNodDefined.equals(propertiesNotDefined));
87          System.err.println(rule.getPropertiesDefinedMoreThanOnce());
88          assertTrue("Properties defined more than once as expected.", rule.getPropertiesDefinedMoreThanOnce().keySet().equals(propertiesDefinedMoreThanOnce));
89      }
90  
91      // Implement feature first.
92      @Test
93      public void testPropertyUsageRuleDefinitionsOnlyOnceFail() {
94          final Collection<String> propertiesDefinedMoreThanOnce = new HashSet<>();
95          propertiesDefinedMoreThanOnce.add("first.property.value");
96          propertiesDefinedMoreThanOnce.add("third.property.value");
97          testProps(
98                  true,
99                  false,
100                 false,
101                 null,
102                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1-double-def.properties")),
103                 null,
104                 null,
105                 false,
106                 propertiesDefinedMoreThanOnce,
107                 Collections.emptySet(),
108                 Collections.emptySet()
109         );
110     }
111 
112     @Test
113     public void testPropertyUsageRuleDefinitionsOnlyOnceOk() {
114         testProps(
115                 true,
116                 false,
117                 false,
118                 null,
119                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1.properties")),
120                 null,
121                 null,
122                 true,
123                 Collections.emptySet(),
124                 Collections.emptySet(),
125                 Collections.emptySet()
126         );
127     }
128 
129     @Test
130     public void testPropertyUsageRuleDefinedOk() {
131         testProps(
132                 false,
133                 true,
134                 false,
135                 null,
136                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1.properties")),
137                 Collections.singleton("properties\\.getProperty\\(\"REPLACE_THIS\"\\)"),
138                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
139                 true,
140                 Collections.emptySet(),
141                 Collections.emptySet(),
142                 Collections.emptySet()
143         );
144     }
145 
146     @Test
147     public void testPropertyUsageRuleDefinedOk2() {
148         testProps(
149                 false,
150                 true,
151                 false,
152                 null,
153                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1.properties")),
154                 null,
155                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
156                 true,
157                 Collections.emptySet(),
158                 Collections.emptySet(),
159                 Collections.emptySet()
160         );
161     }
162 
163     @Test
164     public void testPropertyUsageRuleDefinedOk3() {
165         final Collection<String> templates = new HashSet<>();
166         templates.add("properties\\.getProperty\\(\"REPLACE_THIS\"\\)");
167         templates.add("\\$\\{REPLACE_THIS\\}");
168         testProps(
169                 false,
170                 true,
171                 false,
172                 null,
173                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1.properties")),
174                 templates,
175                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
176                 true,
177                 Collections.emptySet(),
178                 Collections.emptySet(),
179                 Collections.emptySet()
180         );
181     }
182 
183     @Test
184     public void testPropertyUsageRuleDefinedFail1() {
185         final Collection<String> propertiesNotUsed = new HashSet<>();
186         propertiesNotUsed.add("my-too.property.value");
187         propertiesNotUsed.add("other-too.prop.val");
188         propertiesNotUsed.add("also-prop.val");
189         testProps(
190                 false,
191                 true,
192                 false,
193                 null,
194                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app2.properties")),
195                 null,
196                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
197                 false,
198                 Collections.emptySet(),
199                 propertiesNotUsed,
200                 Collections.emptySet()
201         );
202     }
203 
204     @Test
205     public void testPropertyUsageRuleDefinedFail2() {
206         final Collection<String> templates = new HashSet<>();
207         templates.add("properties\\.getProperty\\(\"REPLACE_THIS\"\\)");
208         templates.add("\\$\\{REPLACE_THIS\\}");
209         final Collection<String> propertiesNotUsed = new HashSet<>();
210         propertiesNotUsed.add("my-too.property.value");
211         propertiesNotUsed.add("other-too.prop.val");
212         propertiesNotUsed.add("also-prop.val");
213         testProps(
214                 false,
215                 true,
216                 false,
217                 null,
218                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app2.properties")),
219                 templates,
220                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
221                 false,
222                 Collections.emptySet(),
223                 propertiesNotUsed,
224                 Collections.emptySet()
225         );
226     }
227 
228     @Test
229     public void testPropertyUsageRuleUsedOk1() {
230         testProps(
231                 false,
232                 false,
233                 true,
234                 null,
235                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app1.properties")),
236                 Collections.singleton("properties.getProperty(\"REPLACE_THIS\")"),
237                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App1.java")),
238                 true,
239                 Collections.emptySet(),
240                 Collections.emptySet(),
241                 Collections.emptySet()
242         );
243     }
244 
245     @Test
246     public void testPropertyUsageRuleUsedOk2() {
247         final Collection<String> templates = new HashSet<>();
248         templates.add("properties\\.getProperty\\(\"REPLACE_THIS\"\\)");
249         templates.add("\\$\\{REPLACE_THIS\\}");
250         testProps(
251                 false,
252                 false,
253                 true,
254                 null,
255                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app2.properties")),
256                 templates,
257                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App2.java")),
258                 true,
259                 Collections.emptySet(),
260                 Collections.emptySet(),
261                 Collections.emptySet()
262         );
263     }
264 
265     @Test
266     public void testPropertyUsageRuleUsedOk3() {
267         final Collection<String> templates = new HashSet<>();
268         templates.add("properties\\.getProperty\\(\"REPLACE_THIS\"\\)");
269         templates.add("\\$\\{REPLACE_THIS\\}");
270         testProps(
271                 false,
272                 false,
273                 true,
274                 null,
275                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/app2.properties")),
276                 templates,
277                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App2.java")),
278                 true,
279                 Collections.emptySet(),
280                 Collections.emptySet(),
281                 Collections.emptySet()
282         );
283     }
284 
285     @Test
286     public void testPropertyUsageRuleUsedFail3() {
287         final Collection<String> templates = new HashSet<>();
288         templates.add("properties.getProperty\\(\"REPLACE_THIS\"\\)");
289         templates.add("\\$\\{REPLACE_THIS\\}");
290         Collection<String> propertiesNotDefined = new HashSet<>();
291         propertiesNotDefined.add("my-second.prop.val");
292         propertiesNotDefined.add("my-first.property.value");
293         propertiesNotDefined.add("my-third-val");
294         testProps(
295                 false,
296                 false,
297                 true,
298                 null,
299                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/resources/empty.properties")),
300                 templates,
301                 Collections.singleton(FileSpecs.absoluteCwdAndFile("src/test/java/com/github/mikkoi/maven/plugins/enforcer/rule/propertyusage/App3.java")),
302                 false,
303                 Collections.emptySet(),
304                 Collections.emptySet(),
305                 propertiesNotDefined
306         );
307     }
308 
309     @Test
310     public void testPropertyUsageRuleDefinedFail_Wildcard1() {
311         final Collection<String> templates = new HashSet<>();
312         templates.add("properties\\.getProperty\\(\"REPLACE_ME_HERE\"\\)");
313         final Collection<String> propertiesDefinedMoreThanOnce = new HashSet<>();
314         propertiesDefinedMoreThanOnce.add("first.property.value");
315         propertiesDefinedMoreThanOnce.add("third.property.value");
316         Collection<String> propertiesNotUsed = new HashSet<>();
317         propertiesNotUsed.add("my-second.prop.val");
318         propertiesNotUsed.add("my-first.property.value");
319         propertiesNotUsed.add("my-third-val");
320         testProps(
321                 false,
322                 false,
323                 true,
324                 null,
325                 Collections.singleton("src/test/resources/*.properties"),
326                 templates,
327                 Collections.singleton("src/test/java/**/AppEmpty.java"),
328                 true, // No properties found, so all "found" properties are defined!
329                 propertiesDefinedMoreThanOnce,
330                 propertiesNotUsed,
331                 Collections.emptySet()
332         );
333     }
334 
335     @Test
336     public void testPropertyUsageRuleDefinedFail_Wildcard2() throws Exception {
337         File tempFile = testDir.newFile();
338         assertTrue(tempFile.canWrite());
339         assertTrue(tempFile.setWritable(true));
340         Files.write(tempFile.getAbsoluteFile().toPath(), "very-temporary-property.value=Meaningless value".getBytes(Charset.forName("UTF-8")), StandardOpenOption.WRITE);
341         final Collection<String> templates = new HashSet<>();
342         templates.add("properties\\.getProperty\\(\"REPLACE_ME_HERE\"\\)");
343         templates.add("\\$\\{REPLACE_ME_HERE\\}");
344         Collection<String> definitions = new HashSet<>();
345         definitions.add("src/test/resources/**/*.properties");
346         definitions.add("");
347         definitions.add("src/test/resources/app1.properties");
348         definitions.add(tempFile.getAbsolutePath());
349         definitions.add("src/test/resources/properties-dir/sub-app-props2.properties");
350         final Collection<String> propertiesDefinedMoreThanOnce = new HashSet<>();
351         propertiesDefinedMoreThanOnce.add("first.property.value");
352         propertiesDefinedMoreThanOnce.add("third.property.value");
353         Collection<String> propertiesNotUsed = new HashSet<>();
354         propertiesNotUsed.add("subapp.other.prop.val");
355         propertiesNotUsed.add("third.property.value");
356         propertiesNotUsed.add("subapp.my2.property.value");
357         propertiesNotUsed.add("subapp.my.property.value");
358         propertiesNotUsed.add("subapp.other2.prop.val");
359         propertiesNotUsed.add("very-temporary-property.value");
360         propertiesNotUsed.add("first.property.value");
361         propertiesNotUsed.add("second.property.value");
362         propertiesNotUsed.add("fourth.property.value");
363 
364         testProps(
365                 false,
366                 true,
367                 true,
368                 "REPLACE_ME_HERE",
369                 definitions,
370                 templates,
371                 Collections.singleton("src/test/java/**/App*.java"),
372                 false,
373                 propertiesDefinedMoreThanOnce,
374                 propertiesNotUsed,
375                 Collections.emptySet()
376         );
377     }
378 
379     @Test
380     public void testDefaultValues() {
381         PropertyUsageRule rule = new PropertyUsageRule();
382         assertEquals("Default definitionsOnlyOnce is true.", true, rule.isDefinitionsOnlyOnce());
383         assertEquals("Default definedPropertiesAreUsed is true.", true, rule.isDefinedPropertiesAreUsed());
384         assertEquals("Default usedPropertiesAreDefined is false.", false, rule.isUsedPropertiesAreDefined());
385         assertEquals("Default replaceInTemplateWithPropertyName is correct.", "REPLACE_THIS", rule.getReplaceInTemplateWithPropertyName());
386         assertEquals("Default definitions are correct.", Collections.singleton("src/main/resources/**/*.properties"), rule.getDefinitions());
387         assertEquals("Default templates are correct.", Collections.singleton("\"REPLACE_THIS\""), rule.getTemplates());
388         assertEquals("Default usages are correct.", Collections.singleton("src/main/java/**/*.java"), rule.getUsages());
389     }
390 
391     @Rule
392     public TemporaryFolder testDir = new TemporaryFolder();
393 
394 }