View Javadoc
1   /*
2    * SPDX-FileCopyrightText: Copyright (c) 2011-2026 Yegor Bugayenko
3    * SPDX-License-Identifier: MIT
4    */
5   package com.qulice.maven;
6   
7   import java.util.Arrays;
8   import java.util.LinkedList;
9   import java.util.List;
10  import java.util.Properties;
11  import org.hamcrest.MatcherAssert;
12  import org.hamcrest.Matchers;
13  import org.junit.jupiter.api.Assertions;
14  import org.junit.jupiter.api.Test;
15  
16  /**
17   * Test case for {@link MojoExecutor} conversion of Properties into Xpp3Dom.
18   * @since 1.0
19   */
20  @SuppressWarnings("PMD.AvoidDuplicateLiterals")
21  final class MojoExecutorTest {
22  
23      /**
24       * MojoExecutor can render a collection of Properties as nested XML
25       * (regression for <a href="https://github.com/yegor256/qulice/issues/318">
26       * issue #318</a>).
27       */
28      @Test
29      void rendersCollectionOfPropertiesRecursively() {
30          final Properties dep = new Properties();
31          dep.put("groupId", "org.apache.xmlgraphics");
32          dep.put("artifactId", "batik-ext");
33          dep.put("version", "1.7");
34          final Properties wrapper = new Properties();
35          wrapper.put("dependency", dep);
36          final List<Properties> deps = new LinkedList<>();
37          deps.add(wrapper);
38          final Properties config = new Properties();
39          config.put("ignoredDependencies", deps);
40          MatcherAssert.assertThat(
41              "Dependency details cannot be rendered as toString()",
42              new MojoExecutor(null, null)
43                  .toXppDom(config, "configuration")
44                  .getChild("ignoredDependencies")
45                  .getChild("dependency")
46                  .getChild("groupId")
47                  .getValue(),
48              Matchers.equalTo("org.apache.xmlgraphics")
49          );
50      }
51  
52      /**
53       * MojoExecutor can render nested Properties having multiple keys
54       * (without losing keys beyond the first one).
55       */
56      @Test
57      void preservesAllKeysOfNestedPropertiesInsideCollection() {
58          final Properties entry = new Properties();
59          entry.put("groupId", "org.example");
60          entry.put("artifactId", "sample");
61          final List<Properties> items = new LinkedList<>();
62          items.add(entry);
63          final Properties config = new Properties();
64          config.put("items", items);
65          MatcherAssert.assertThat(
66              "All keys of nested Properties must appear as children",
67              new MojoExecutor(null, null)
68                  .toXppDom(config, "configuration")
69                  .getChild("items").getChildCount(),
70              Matchers.equalTo(2)
71          );
72      }
73  
74      /**
75       * MojoExecutor can render a collection of strings as repeated elements.
76       */
77      @Test
78      void rendersCollectionOfStrings() {
79          final Properties config = new Properties();
80          config.put("patterns", Arrays.asList("alpha", "beta"));
81          MatcherAssert.assertThat(
82              "Collection elements cannot be merged into a single string",
83              new MojoExecutor(null, null)
84                  .toXppDom(config, "configuration")
85                  .getChild("patterns").getChildCount(),
86              Matchers.equalTo(2)
87          );
88      }
89  
90      /**
91       * MojoExecutor can render a plain String value as a leaf node.
92       */
93      @Test
94      void rendersStringValueAsLeaf() {
95          final Properties config = new Properties();
96          config.put("encoding", "UTF-8");
97          MatcherAssert.assertThat(
98              "String value cannot be rendered as a leaf node",
99              new MojoExecutor(null, null)
100                 .toXppDom(config, "configuration")
101                 .getChild("encoding").getValue(),
102             Matchers.equalTo("UTF-8")
103         );
104     }
105 
106     /**
107      * MojoExecutor can render a String array as repeated child nodes.
108      */
109     @Test
110     void rendersStringArrayAsRepeatedChildren() {
111         final Properties config = new Properties();
112         config.put("excludes", new String[] {"first", "second", "third"});
113         MatcherAssert.assertThat(
114             "String array entries cannot be rendered as separate children",
115             new MojoExecutor(null, null)
116                 .toXppDom(config, "configuration")
117                 .getChild("excludes").getChildCount(),
118             Matchers.equalTo(3)
119         );
120     }
121 
122     /**
123      * MojoExecutor fails fast when the property value has an unsupported type.
124      */
125     @Test
126     void failsOnUnsupportedValueType() {
127         final Properties config = new Properties();
128         config.put("amount", 42);
129         Assertions.assertThrows(
130             IllegalArgumentException.class,
131             () -> new MojoExecutor(null, null)
132                 .toXppDom(config, "configuration"),
133             "Unsupported value type must not be silently accepted"
134         );
135     }
136 
137     /**
138      * MojoExecutor can render arbitrarily nested Properties within a value.
139      */
140     @Test
141     void rendersArbitrarilyNestedProperties() {
142         final Properties java = new Properties();
143         java.put("version", "17");
144         final Properties rules = new Properties();
145         rules.put("requireJavaVersion", java);
146         final Properties config = new Properties();
147         config.put("rules", rules);
148         MatcherAssert.assertThat(
149             "Deeply nested Properties cannot be flattened",
150             new MojoExecutor(null, null)
151                 .toXppDom(config, "configuration")
152                 .getChild("rules")
153                 .getChild("requireJavaVersion")
154                 .getChild("version")
155                 .getValue(),
156             Matchers.equalTo("17")
157         );
158     }
159 }