View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.utils.xml.pull;
20  
21  import java.io.IOException;
22  import java.io.StringReader;
23  
24  import org.apache.maven.shared.utils.xml.Xpp3Dom;
25  import org.apache.maven.shared.utils.xml.Xpp3DomBuilder;
26  import org.junit.Test;
27  
28  import static org.apache.maven.shared.utils.xml.Xpp3Dom.mergeXpp3Dom;
29  import static org.junit.Assert.*;
30  
31  /**
32   * @author Kristian Rosenvold
33   */
34  public class Xpp3DomTest {
35  
36      private Xpp3Dom createElement(String element, String value) {
37          Xpp3Dom t1s1 = new Xpp3Dom(element);
38          t1s1.setValue(value);
39          return t1s1;
40      }
41  
42      @Test
43      public void mergePrecedenceSelfClosed() throws XmlPullParserException, IOException {
44          Xpp3Dom parentConfig = build("<configuration><items><item/></items></configuration>");
45          Xpp3Dom childConfig = build("<configuration><items><item>ooopise</item></items></configuration>");
46  
47          Xpp3Dom result = Xpp3Dom.mergeXpp3Dom(childConfig, parentConfig);
48          Xpp3Dom items = result.getChild("items");
49  
50          assertEquals(1, items.getChildCount());
51          Xpp3Dom item = items.getChild(0);
52          assertEquals("ooopise", item.getValue());
53      }
54  
55      @Test
56      public void mergePrecedenceOpenClose() throws XmlPullParserException, IOException {
57          Xpp3Dom parentConfig = build("<configuration><items><item></item></items></configuration>");
58          Xpp3Dom childConfig = build("<configuration><items><item>ooopise</item></items></configuration>");
59  
60          Xpp3Dom result = Xpp3Dom.mergeXpp3Dom(childConfig, parentConfig);
61          Xpp3Dom items = result.getChild("items");
62  
63          assertEquals(1, items.getChildCount());
64          Xpp3Dom item = items.getChild(0);
65          assertEquals("ooopise", item.getValue());
66      }
67  
68      @Test
69      public void selfOverrideOnRootNode() {
70          // Todo: This does not work when loaded. Probably a bug related to null vs "" handling
71          //      Xpp3Dom t1 = build( "<top combine.self='override' attr='value'></top>" );
72  
73          Xpp3Dom t1 = new Xpp3Dom("top");
74          t1.setAttribute("attr", "value");
75  
76          t1.setAttribute(Xpp3Dom.SELF_COMBINATION_MODE_ATTRIBUTE, Xpp3Dom.SELF_COMBINATION_OVERRIDE);
77  
78          Xpp3Dom t2 = build("<top attr2='value2'>val2</top>");
79          Xpp3Dom result = mergeXpp3Dom(t1, t2);
80  
81          assertEquals(2, result.getAttributeNames().length);
82          assertNull(result.getValue());
83      }
84  
85      @Test
86      public void mergeValuesOnRootNode() {
87          Xpp3Dom t1 = build("<root attr='value'/>");
88          Xpp3Dom t2 = build("<root attr2='value2'>t2Val</root>");
89          Xpp3Dom result = mergeXpp3Dom(t1, t2);
90          assertEquals(2, result.getAttributeNames().length);
91          assertEquals(result.getValue(), t2.getValue());
92      }
93  
94      @Test
95      public void mergeAttributesOnRootNode() {
96          Xpp3Dom t1 = build("<root combine.self='merge' attr='value'/>");
97          Xpp3Dom t2 = build("<root attr2='value2'/>");
98  
99          Xpp3Dom dom = mergeXpp3Dom(t1, t2);
100         assertEquals(3, dom.getAttributeNames().length);
101     }
102 
103     @Test
104     public void combineAppend() {
105         Xpp3Dom t1 = new Xpp3Dom("root");
106         t1.setAttribute(Xpp3Dom.CHILDREN_COMBINATION_MODE_ATTRIBUTE, Xpp3Dom.CHILDREN_COMBINATION_APPEND);
107         t1.addChild(createElement("sub", "s1Value"));
108 
109         Xpp3Dom t2 = new Xpp3Dom("root");
110         t2.addChild(createElement("sub", "s1Value"));
111 
112         Xpp3Dom result = mergeXpp3Dom(t1, t2);
113 
114         assertEquals(2, result.getChildren("sub").length);
115     }
116 
117     @Test
118     public void mergeOverride() {
119         Xpp3Dom t1 = new Xpp3Dom("root");
120         t1.setAttribute(Xpp3Dom.CHILDREN_COMBINATION_MODE_ATTRIBUTE, Xpp3Dom.CHILDREN_COMBINATION_APPEND);
121         t1.addChild(createElement("sub", "s1Value"));
122 
123         Xpp3Dom t2 = new Xpp3Dom("root");
124         t2.addChild(createElement("sub", "s1Value"));
125 
126         Xpp3Dom result = mergeXpp3Dom(t1, t2, Boolean.TRUE);
127 
128         assertEquals(1, result.getChildren("sub").length);
129     }
130 
131     @Test(expected = NullPointerException.class)
132     public void nullValue() {
133         //noinspection ConstantConditions
134         new Xpp3Dom("top").setAttribute(null, "value");
135     }
136 
137     @Test(expected = NullPointerException.class)
138     public void nullAttribute() {
139         //noinspection ConstantConditions
140         new Xpp3Dom("root").setAttribute("attr", null);
141     }
142 
143     @Test
144     public void testEquals() {
145         Xpp3Dom dom = new Xpp3Dom("single");
146         dom.addChild(new Xpp3Dom("kid"));
147 
148         Xpp3Dom other = new Xpp3Dom("single");
149         other.addChild(new Xpp3Dom("kid2"));
150 
151         assertEquals(dom, dom);
152         //noinspection ObjectEqualsNull
153         assertFalse(dom.equals(null));
154         assertFalse(dom.equals(new Xpp3Dom((String) null)));
155         assertFalse(dom.equals(other));
156     }
157 
158     @Test
159     public void dominantWinsCollections() throws XmlPullParserException {
160         Xpp3Dom parent = build("<root><entries><entry>uno</entry><entry>dos</entry></entries></root>");
161         Xpp3Dom dominant = build("<root><entries><entry>tres</entry></entries></root>");
162 
163         Xpp3Dom result = mergeXpp3Dom(dominant, parent);
164 
165         Xpp3Dom items = result.getChild("entries");
166         assertEquals(1, items.getChildCount());
167 
168         assertElemEquals("tres", items.getChild(0));
169     }
170 
171     @Test
172     public void combineChildrenAppendTest() throws XmlPullParserException {
173         Xpp3Dom parent =
174                 build("<root><entries><entry>uno</entry><entry>dos</entry><entry>tres</entry></entries></root>");
175         Xpp3Dom child = build("<root><entries combine.children=\"append\"><entry>quatro</entry></entries></root>");
176 
177         Xpp3Dom result = mergeXpp3Dom(child, parent);
178 
179         Xpp3Dom items = result.getChild("entries");
180         assertEquals(4, items.getChildCount());
181 
182         Xpp3Dom[] item = items.getChildren();
183 
184         assertElemEquals("uno", item[0]);
185         assertElemEquals("dos", item[1]);
186         assertElemEquals("tres", item[2]);
187         assertElemEquals("quatro", item[3]);
188     }
189 
190     @Test
191     public void unchangedWithFirstOrLastEmpty() throws Exception {
192         String configStr = "<root><entries><entry/><entry>test</entry><entry/></entries></root>";
193         Xpp3Dom dominant = build(configStr);
194         Xpp3Dom duplicatedDominant = build(configStr);
195         validateEntries(dominant);
196         Xpp3Dom result = mergeXpp3Dom(dominant, duplicatedDominant);
197         validateEntries(result);
198     }
199 
200     private void validateEntries(Xpp3Dom result) {
201         Xpp3Dom entries = result.getChild("entries");
202         assertEquals(3, entries.getChildCount());
203         assertXpp3Null(entries.getChild(0));
204         assertEquals("test", entries.getChild(1).getValue());
205         assertXpp3Null(entries.getChild(2));
206     }
207 
208     static void assertElemEquals(String value, Xpp3Dom element) {
209         assertEquals(value, element.getValue());
210     }
211 
212     void assertXpp3Null(Xpp3Dom entry) {
213         // Todo: When we used xpp3dom, all methods using this assert used to return null
214         assertEquals("", entry.getValue());
215     }
216 
217     @Test
218     public void recessiveChildrenIncludedWhenDominantEmpty() throws Exception {
219         String dominant = "<root><baz>bazzy</baz></root>";
220         String recessive = "<root><bar>barry</bar></root>";
221 
222         Xpp3Dom merged = mergeXpp3Dom(build(dominant), build(recessive));
223 
224         assertEquals(2, merged.getChildCount());
225         assertEquals("bazzy", merged.getChild("baz").getValue());
226         assertEquals("barry", merged.getChild("bar").getValue());
227     }
228 
229     static Xpp3Dom build(String stringContent) {
230         return Xpp3DomBuilder.build(new StringReader(stringContent));
231     }
232 
233     @Test
234     public void duplicatedChildren() throws IOException, XmlPullParserException {
235         String dupes = "<root><baz>x</baz><baz>y</baz></root>";
236         assertEquals("y", build(dupes).getChild("baz").getValue());
237     }
238 }