View Javadoc
1   package org.apache.maven.plugins.dependency.tree;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  
21  import org.apache.maven.plugin.testing.AbstractMojoTestCase;
22  import org.eclipse.aether.artifact.Artifact;
23  import org.eclipse.aether.artifact.DefaultArtifact;
24  import org.eclipse.aether.graph.DefaultDependencyNode;
25  import org.eclipse.aether.graph.Dependency;
26  import org.eclipse.aether.graph.DependencyNode;
27  import org.junit.Assert;
28  import org.junit.Test;
29  
30  import java.io.IOException;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.HashMap;
34  import java.util.Map;
35  
36  public class VerboseGraphSerializerTest extends AbstractMojoTestCase
37  {
38      private AbstractVerboseGraphSerializer serializer;
39  
40      private static final String PRE_MANAGED_SCOPE = "preManagedScope", PRE_MANAGED_VERSION = "preManagedVersion",
41              MANAGED_SCOPE = "managedScope";
42  
43      @Test
44      public void testBasicTree() throws IOException
45      {
46          serializer = new VerboseGraphTextSerializer();
47          DependencyNode root = new DefaultDependencyNode(
48                  new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null)
49          );
50          DependencyNode left = new DefaultDependencyNode(
51                  new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test" )
52          );
53          DependencyNode right = new DefaultDependencyNode(
54                  new Dependency( new DefaultArtifact( "org.xyz", "right", "zip", "1" ), "provided" )
55          );
56  
57          root.setChildren( Arrays.asList( left, right ) );
58  
59          String actual = serializer.serialize( root );
60          String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
61                  + "\\- org.xyz:right:zip:1:provided\n";
62  
63          Assert.assertEquals(expected, actual);
64      }
65  
66      @Test
67      public void testLargeTree() throws IOException
68      {
69          serializer = new VerboseGraphTextSerializer();
70          // Construct nodes for tree l1 = level 1 with the root being l0
71          DependencyNode root = new DefaultDependencyNode(
72                  new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
73          );
74          DependencyNode l1left = new DefaultDependencyNode(
75                  new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test" )
76          );
77          DependencyNode l1right = new DefaultDependencyNode(
78                  new Dependency( new DefaultArtifact( "org.xyz", "right", "zip", "1" ), "provided" )
79          );
80          DependencyNode l2left = new DefaultDependencyNode(
81                  new Dependency( new DefaultArtifact( "org.maven", "a4", "jar", "2.2.1" ), "system" )
82          );
83          DependencyNode l2middle = new DefaultDependencyNode(
84                  new Dependency( new DefaultArtifact( "com.google", "a5", "zip", "0" ), "import" )
85          );
86          DependencyNode l2right = new DefaultDependencyNode(
87                  new Dependency( new DefaultArtifact( "com.xyz", "a9", "xml", "1.2" ), "runtime" )
88          );
89          DependencyNode l3 = new DefaultDependencyNode(
90                  new Dependency( new DefaultArtifact( "com.xyz", "a6", "xml", "1.2.1" ), "provided" )
91          );
92          DependencyNode l4 = new DefaultDependencyNode(
93                  new Dependency( new DefaultArtifact( "com.example", "a7", "jar", "2.2.2" ), "provided" )
94          );
95          DependencyNode l5right = new DefaultDependencyNode(
96                  new Dependency( new DefaultArtifact( "com.comm", "a7", "jar", "1" ), "compile" )
97          );
98          DependencyNode l5left = new DefaultDependencyNode(
99                  new Dependency( new DefaultArtifact( "com.comm", "a7", "jar", "1" ), "compile" )
100         );
101         DependencyNode l6left = new DefaultDependencyNode(
102                 new Dependency( new DefaultArtifact( "com.example", "a8", "xml", "2.1" ), "compile" )
103         );
104 
105         // Set Node Relationships
106         l5left.setChildren( Arrays.asList( l6left ) );
107         l4.setChildren( Arrays.asList( l5left, l5right ) );
108         l3.setChildren( Arrays.asList( l4 ) );
109         l2middle.setChildren( Arrays.asList( l3 ) );
110 
111         l1left.setChildren( Arrays.asList( l2left, l2middle ) );
112         l1right.setChildren( Arrays.asList( l2right ) );
113 
114         root.setChildren( Arrays.asList( l1left, l1right ) );
115 
116         String actual = serializer.serialize( root );
117         String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
118                 + "|  +- org.maven:a4:jar:2.2.1:system\n" + "|  \\- com.google:a5:zip:0:import\n"
119                 + "|     \\- com.xyz:a6:xml:1.2.1:provided\n" + "|        \\- com.example:a7:jar:2.2.2:provided\n"
120                 + "|           +- com.comm:a7:jar:1:compile\n" + "|           |  \\- com.example:a8:xml:2.1:compile\n"
121                 + "|           \\- (com.comm:a7:jar:1:compile - omitted for duplicate)\n"
122                 + "\\- org.xyz:right:zip:1:provided\n" + "   \\- com.xyz:a9:xml:1.2:runtime\n";
123 
124         Assert.assertEquals(expected, actual);
125     }
126 
127     @Test
128     public void testLargeGraphWithCycles() throws IOException
129     {
130         serializer = new VerboseGraphTextSerializer();
131         // Construct nodes for tree l1 = level 1 with the root being l0
132         DependencyNode root = new DefaultDependencyNode(
133                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
134         );
135         DependencyNode l1left = new DefaultDependencyNode(
136                 new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test" )
137         );
138         DependencyNode l1right = new DefaultDependencyNode(
139                 new Dependency( new DefaultArtifact( "org.xyz", "right", "zip", "1" ), "provided" )
140         );
141         DependencyNode l2left = new DefaultDependencyNode(
142                 new Dependency( new DefaultArtifact( "org.maven", "a4", "jar", "2.2.1" ), "system" )
143         );
144         DependencyNode l2middle = new DefaultDependencyNode(
145                 new Dependency( new DefaultArtifact( "com.google", "a5", "zip", "0" ), "import" )
146         );
147         DependencyNode l2right = new DefaultDependencyNode(
148                 new Dependency( new DefaultArtifact( "com.xyz", "a9", "xml", "1.2" ), "runtime" )
149         );
150         DependencyNode l3 = new DefaultDependencyNode(
151                 new Dependency( new DefaultArtifact( "com.xyz", "a6", "xml", "1.2.1" ), "compile" )
152         );
153         DependencyNode l4 = new DefaultDependencyNode(
154                 new Dependency( new DefaultArtifact( "com.example", "a7", "jar", "2.2.2" ), "provided" )
155         );
156         DependencyNode l5right = new DefaultDependencyNode(
157                 new Dependency( new DefaultArtifact( "com.comm", "a7", "jar", "1" ), "compile" )
158         );
159         DependencyNode l5left = new DefaultDependencyNode(
160                 new Dependency( new DefaultArtifact( "com.comm", "a7", "jar", "1" ), "compile" )
161         );
162         DependencyNode l6left = new DefaultDependencyNode(
163                 new Dependency( new DefaultArtifact( "com.example", "a8", "xml", "2.1" ), "runtime" )
164         );
165 
166         // Set Node Relationships
167         l5left.setChildren( Arrays.asList( l6left ) );
168         l4.setChildren( Arrays.asList( l5left, l5right ) );
169         l3.setChildren( Arrays.asList( l4 ) );
170         l2middle.setChildren( Arrays.asList( l3 ) );
171 
172         l1left.setChildren( Arrays.asList( l2left, l2middle ) );
173         l1right.setChildren( Arrays.asList( l2right ) );
174 
175         root.setChildren( Arrays.asList( l1left, l1right ) );
176 
177         // Introduce cycles
178         l5left.setChildren( Arrays.asList( l2left, l1right, l3 ) );
179 
180         String actual = serializer.serialize( root );
181         String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
182                 + "|  +- org.maven:a4:jar:2.2.1:system\n" + "|  \\- com.google:a5:zip:0:import\n"
183                 + "|     \\- com.xyz:a6:xml:1.2.1:compile\n" + "|        \\- com.example:a7:jar:2.2.2:provided\n"
184                 + "|           +- (com.comm:a7:jar:1:compile - omitted for introducing a cycle with org.maven:a4:"
185                 + "jar:2.2.1:system)\n" + "|           \\- (com.comm:a7:jar:1:compile - omitted for duplicate)\n"
186                 + "\\- org.xyz:right:zip:1:provided\n" + "   \\- com.xyz:a9:xml:1.2:runtime\n";
187 
188         Assert.assertEquals(expected, actual);
189     }
190 
191     @Test
192     public void testTreeWithOptional() throws IOException
193     {
194         serializer = new VerboseGraphTextSerializer();
195         DependencyNode root = new DefaultDependencyNode(
196                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), "")
197         );
198         DependencyNode left = new DefaultDependencyNode(
199                 new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test", true )
200         );
201         DependencyNode right = new DefaultDependencyNode(
202                 new Dependency( new DefaultArtifact( "org.xyz", "right", "zip", "1" ), "provided" )
203         );
204 
205         root.setChildren( Arrays.asList( left, right ) );
206 
207         String actual = serializer.serialize( root );
208         String expected = "com.google:rootArtifact:jar:1.0.0\n"
209                 + "+- (org.apache:left:xml:0.1-SNAPSHOT:test - omitted due to optional dependency)\n"
210                 + "\\- org.xyz:right:zip:1:provided\n";
211 
212         Assert.assertEquals(expected, actual);
213     }
214 
215     @Test
216     public void testTreeWithScopeConflict() throws IOException
217     {
218         serializer = new VerboseGraphTextSerializer();
219         DependencyNode root = new DefaultDependencyNode(
220                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), null )
221         );
222         DependencyNode left = new DefaultDependencyNode(
223                 new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test" )
224         );
225         DependencyNode right = new DefaultDependencyNode(
226                 new Dependency( new DefaultArtifact( "com.google", "conflictArtifact", "jar", "1.0.0" ), "test" )
227         );
228         DependencyNode leftChild = new DefaultDependencyNode(
229                 new Dependency( new DefaultArtifact( "com.google", "conflictArtifact", "jar", "1.0.0" ), "compile" )
230         );
231 
232         left.setChildren( Arrays.asList( leftChild ) );
233         root.setChildren( Arrays.asList( left, right ) );
234 
235         String actual = serializer.serialize( root );
236         String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
237                 + "|  \\- (com.google:conflictArtifact:jar:1.0.0:compile - omitted for conflict with test)\n"
238                 + "\\- com.google:conflictArtifact:jar:1.0.0:test\n";
239 
240         Assert.assertEquals(expected, actual);
241     }
242 
243     @Test
244     public void testTreeWithVersionConflict() throws IOException
245     {
246         serializer = new VerboseGraphTextSerializer();
247         DependencyNode root = new DefaultDependencyNode(
248                 new Dependency( new DefaultArtifact( "com.google", "rootArtifact", "jar", "1.0.0" ), "rootScope" )
249         );
250         DependencyNode left = new DefaultDependencyNode(
251                 new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.1-SNAPSHOT" ), "test" )
252         );
253         DependencyNode right = new DefaultDependencyNode(
254                 new Dependency( new DefaultArtifact( "com.google", "artifact", "jar", "2.0.0" ), "test" )
255         );
256         // Note that as of now the serializer does not deal with conflicts with the project/root node itself
257         DependencyNode leftChild = new DefaultDependencyNode(
258                 new Dependency( new DefaultArtifact( "org.apache", "left", "xml", "0.3.1" ), "compile" )
259         );
260 
261         left.setChildren( Arrays.asList( leftChild ) );
262         root.setChildren( Arrays.asList( left, right ) );
263 
264         String actual = serializer.serialize( root );
265         String expected = "com.google:rootArtifact:jar:1.0.0\n" + "+- org.apache:left:xml:0.1-SNAPSHOT:test\n"
266                 + "|  \\- (org.apache:left:xml:0.3.1:compile - omitted for conflict with 0.1-SNAPSHOT)\n"
267                 + "\\- com.google:artifact:jar:2.0.0:test\n";
268 
269         Assert.assertEquals(expected, actual);
270     }
271 
272     @Test
273     public void testDotOutput()
274     {
275         serializer = new VerboseGraphDotSerializer();
276         DependencyNode root = new DefaultDependencyNode(
277                 new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
278         );
279 
280         DependencyNode l1left = new DefaultDependencyNode(
281                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
282         );
283         DependencyNode l2left = new DefaultDependencyNode(
284                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
285         );
286         Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
287         cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
288         DependencyNode l2middleLeft = new DefaultDependencyNode(
289                 new Dependency( cycleArtifact, "compile" )
290         );
291 
292         DependencyNode l1middle = new DefaultDependencyNode(
293                 new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
294         );
295         // should have scope conflict with l1middle, check to make sure its not version
296         DependencyNode l2middleRight = new DefaultDependencyNode(
297                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
298         );
299 
300         DependencyNode l1right = new DefaultDependencyNode(
301                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
302         );
303         DependencyNode l5right = new DefaultDependencyNode(
304                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
305         );
306         DependencyNode l6right = new DefaultDependencyNode(
307                 new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
308         );
309 
310         Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
311         Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
312         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
313         artifactProperties.put( MANAGED_SCOPE, "compile" );
314         scopeManaged = scopeManaged.setProperties( artifactProperties );
315         DependencyNode l2right = new DefaultDependencyNode(
316                 new Dependency( scopeManaged, "scope" )
317         );
318 
319         Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
320         artifactProperties = new HashMap<>( versionManaged.getProperties() );
321         artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
322         versionManaged = versionManaged.setProperties( artifactProperties );
323         DependencyNode l3right = new DefaultDependencyNode(
324                 new Dependency( versionManaged, "provided" )
325         );
326 
327         Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
328                 "xml", "2" );
329         artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
330         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
331         artifactProperties.put( MANAGED_SCOPE, "compile" );
332         artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
333         scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
334 
335         DependencyNode l4right = new DefaultDependencyNode(
336                 new Dependency( scopeVersionManaged, "runtime" )
337         );
338 
339 
340         Dependency optionalDependency = new Dependency(
341                 new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
342         optionalDependency = optionalDependency.setOptional( true );
343         DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
344 
345         root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
346         l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
347         l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
348         l2middleLeft.setChildren( Collections.singletonList( l6right ) );
349         l1Optional.setChildren( Collections.singletonList( l6right ) );
350         l1middle.setChildren( Collections.singletonList( l2middleRight ) );
351         l1right.setChildren( Collections.singletonList( l2right ) );
352         l2right.setChildren( Collections.singletonList( l3right ) );
353         l3right.setChildren( Collections.singletonList( l4right ) );
354         l4right.setChildren( Collections.singletonList( l5right ) );
355         l5right.setChildren( Collections.singletonList( l6right ) );
356 
357         String actual = serializer.serialize( root );
358         String expected = "digraph \"org.example:root:jar:3.1.1\" {"
359                 + "\n"
360                 + " \"org.example:root:jar:3.1.1\" -> \"org.duplicate:duplicate:xml:2:compile\" ;"
361                 + "\n"
362                 + " \"org.example:root:jar:3.1.1\" -> \"org.apache:maven:jar:1.0-SNAPSHOT:test\" ;"
363                 + "\n"
364                 + " \"org.example:root:jar:3.1.1\" -> \"org.apache:maven-dependency:jar:1.0-SNAPSHOT:test\" ;"
365                 + "\n"
366                 + " \"org.example:root:jar:3.1.1\" -> \"org.apache:optional:jar:1.1:test - omitted due to optional "
367                 + "dependency\" ;" + "\n"
368                 + " \"org.duplicate:duplicate:xml:2:compile\" -> \"org.duplicate:duplicate"
369                 + ":xml:2:compile - omitted for duplicate\" ;" + "\n"
370                 + " \"org.duplicate:duplicate:xml:2:compile\" -> \"org.cycle:cycle:zip:3:compile - omitted due "
371                 + "to cycle\" ;" + "\n"
372                 + " \"org.apache:maven:jar:1.0-SNAPSHOT:test\" -> \"org.apache:maven-dependency"
373                 + ":jar:1.0-SNAPSHOT:compile - omitted for conflict with test\" ;" + "\n"
374                 + " \"org.apache:maven-dependency:jar:1.0-SNAPSHOT:test\" -> \"org.scopeManaged:scope-managed:zip"
375                 + ":2.1:compile - scope managed from runtime\" ;" + "\n"
376                 + " \"org.scopeManaged:scope-managed:zip:2.1:compile\" -> \"org.versionManaged:version-manged:"
377                 + "pom:3.3.3:provided - version managed from 1.1.0\" ;" + "\n"
378                 + " \"org.versionManaged:version-manged:pom:3.3.3:provided\" -> \"org.scopeVersionManaged:"
379                 + "scope-version-managed:xml:2:compile - version managed from 3.1; scope managed from runtime\" ;"
380                 + "\n" + " \"org.scopeVersionManaged:scope-version-managed:xml:2:compile\" -> "
381                 + "\"org.apache:maven-dependency:jar:2.1:test - omitted for conflict with 1.0-SNAPSHOT\" ;"
382                 + "\n" + "}";
383         Assert.assertEquals(expected, actual);
384     }
385 
386     @Test
387     public void testTgfOutput()
388     {
389         serializer = new VerboseGraphTgfSerializer();
390         DependencyNode root = new DefaultDependencyNode(
391                 new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
392         );
393 
394         DependencyNode l1left = new DefaultDependencyNode(
395                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
396         );
397         DependencyNode l2left = new DefaultDependencyNode(
398                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
399         );
400         Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
401         cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
402         DependencyNode l2middleLeft = new DefaultDependencyNode(
403                 new Dependency( cycleArtifact, "compile" )
404         );
405 
406         DependencyNode l1middle = new DefaultDependencyNode(
407                 new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
408         );
409         // should have scope conflict with l1middle, check to make sure its not version
410         DependencyNode l2middleRight = new DefaultDependencyNode(
411                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
412         );
413 
414         DependencyNode l1right = new DefaultDependencyNode(
415                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
416         );
417         DependencyNode l5right = new DefaultDependencyNode(
418                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
419         );
420         DependencyNode l6right = new DefaultDependencyNode(
421                 new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
422         );
423 
424         Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
425         Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
426         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
427         artifactProperties.put( MANAGED_SCOPE, "compile" );
428         scopeManaged = scopeManaged.setProperties( artifactProperties );
429         DependencyNode l2right = new DefaultDependencyNode(
430                 new Dependency( scopeManaged, "scope" )
431         );
432 
433         Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
434         artifactProperties = new HashMap<>( versionManaged.getProperties() );
435         artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
436         versionManaged = versionManaged.setProperties( artifactProperties );
437         DependencyNode l3right = new DefaultDependencyNode(
438                 new Dependency( versionManaged, "provided" )
439         );
440 
441         Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
442                 "xml", "2" );
443         artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
444         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
445         artifactProperties.put( MANAGED_SCOPE, "compile" );
446         artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
447         scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
448 
449         DependencyNode l4right = new DefaultDependencyNode(
450                 new Dependency( scopeVersionManaged, "runtime" )
451         );
452 
453 
454         Dependency optionalDependency = new Dependency(
455                 new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
456         optionalDependency = optionalDependency.setOptional( true );
457         DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
458 
459         root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
460         l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
461         l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
462         l2middleLeft.setChildren( Collections.singletonList( l6right ) );
463         l1Optional.setChildren( Collections.singletonList( l6right ) );
464         l1middle.setChildren( Collections.singletonList( l2middleRight ) );
465         l1right.setChildren( Collections.singletonList( l2right ) );
466         l2right.setChildren( Collections.singletonList( l3right ) );
467         l3right.setChildren( Collections.singletonList( l4right ) );
468         l4right.setChildren( Collections.singletonList( l5right ) );
469         l5right.setChildren( Collections.singletonList( l6right ) );
470 
471         String actual = serializer.serialize( root );
472         String expected = root.hashCode() + " org.example:root:jar:3.1.1" + "\n"
473                 + l1left.hashCode() + " org.duplicate:duplicate:xml:2:compile" + "\n"
474                 + l2left.hashCode() + " (org.duplicate:duplicate:xml:2:compile - omitted for duplicate)"
475                 + "\n" + l2middleLeft.hashCode()
476                 + " (org.cycle:cycle:zip:3:compile - omitted for cycle)" + "\n"
477                 + l1middle.hashCode() + " org.apache:maven:jar:1.0-SNAPSHOT:test" + "\n"
478                 + l2middleRight.hashCode()
479                 + " (org.apache:maven-dependency:jar:1.0-SNAPSHOT:compile - omitted for conflict with test)"
480                 + "\n" + l1right.hashCode() + " org.apache:maven-dependency:jar:1.0-SNAPSHOT:test"
481                 + "\n" + l2right.hashCode()
482                 + " org.scopeManaged:scope-managed:zip:2.1:compile - scope managed from runtime"
483                 + "\n" + l3right.hashCode()
484                 + " org.versionManaged:version-manged:pom:3.3.3:provided - version managed from 1.1.0"
485                 + "\n" + l4right.hashCode()
486                 + " org.scopeVersionManaged:scope-version-managed:xml:2:compile - version managed from 3.1; "
487                 + "scope managed from runtime" + "\n" + l5right.hashCode()
488                 + " (org.apache:maven-dependency:jar:2.1:test - omitted for conflict with 1.0-SNAPSHOT)"
489                 + "\n" + l1Optional.hashCode()
490                 + " (org.apache:optional:jar:1.1:test - omitted due to optional dependency)"
491                 + "\n" + "#" + "\n" + root.hashCode() + " " + l1left.hashCode()
492                 + " compile" + "\n"
493                 + l1left.hashCode() + " " + l2left.hashCode() + " compile omitted for duplicate"
494                 + "\n" + l1left.hashCode() + " " + l2middleLeft.hashCode()
495                 + " compile omitted for cycle" + "\n" + root.hashCode() + " " + l1middle.hashCode()
496                 + " test" + "\n" + l1middle.hashCode() + " " + l2middleRight.hashCode()
497                 + " compile omitted for conflict with test" + "\n" + root.hashCode() + " "
498                 + l1right.hashCode() + " test" + "\n" + l1right.hashCode() + " " + l2right.hashCode()
499                 + " compile managed from runtime" + "\n" + l2right.hashCode() + " "
500                 + l3right.hashCode() + " provided" + "\n" + l3right.hashCode() + " "
501                 + l4right.hashCode() + " compile managed from runtime" + "\n" + l4right.hashCode()
502                 + " " + l5right.hashCode() + " test omitted for conflict with 1.0-SNAPSHOT" + "\n" +
503                 root.hashCode() + " " + l1Optional.hashCode() + " test" + "\n";
504         Assert.assertEquals(expected, actual);
505     }
506 
507     @Test
508     public void testGraphmlOutput()
509     {
510         serializer = new VerboseGraphGraphmlSerializer();
511         DependencyNode root = new DefaultDependencyNode(
512                 new Dependency( new DefaultArtifact( "org.example", "root", "jar", "3.1.1" ), "" )
513         );
514 
515         DependencyNode l1left = new DefaultDependencyNode(
516                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
517         );
518         DependencyNode l2left = new DefaultDependencyNode(
519                 new Dependency( new DefaultArtifact( "org.duplicate", "duplicate", "xml", "2" ), "compile" )
520         );
521         Artifact cycleArtifact = new DefaultArtifact( "org.cycle", "cycle", "zip", "3" );
522         cycleArtifact = cycleArtifact.setProperties( Collections.singletonMap( "Cycle", "true" ) );
523         DependencyNode l2middleLeft = new DefaultDependencyNode(
524                 new Dependency( cycleArtifact, "compile" )
525         );
526 
527         DependencyNode l1middle = new DefaultDependencyNode(
528                 new Dependency( new DefaultArtifact( "org.apache", "maven", "jar", "1.0-SNAPSHOT" ), "test" )
529         );
530         // should have scope conflict with l1middle, check to make sure its not version
531         DependencyNode l2middleRight = new DefaultDependencyNode(
532                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "compile" )
533         );
534 
535         DependencyNode l1right = new DefaultDependencyNode(
536                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "1.0-SNAPSHOT" ), "test" )
537         );
538         DependencyNode l5right = new DefaultDependencyNode(
539                 new Dependency( new DefaultArtifact( "org.apache", "maven-dependency", "jar", "2.1" ), "test" )
540         );
541         DependencyNode l6right = new DefaultDependencyNode(
542                 new Dependency( new DefaultArtifact( "org.abc", "shouldn't show", "xml", "1" ), "compile" )
543         );
544 
545         Artifact scopeManaged = new DefaultArtifact( "org.scopeManaged", "scope-managed", "zip", "2.1" );
546         Map<String, String> artifactProperties = new HashMap<>( scopeManaged.getProperties() );
547         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
548         artifactProperties.put( MANAGED_SCOPE, "compile" );
549         scopeManaged = scopeManaged.setProperties( artifactProperties );
550         DependencyNode l2right = new DefaultDependencyNode(
551                 new Dependency( scopeManaged, "scope" )
552         );
553 
554         Artifact versionManaged = new DefaultArtifact( "org.versionManaged", "version-manged", "pom", "3.3.3" );
555         artifactProperties = new HashMap<>( versionManaged.getProperties() );
556         artifactProperties.put( PRE_MANAGED_VERSION, "1.1.0" );
557         versionManaged = versionManaged.setProperties( artifactProperties );
558         DependencyNode l3right = new DefaultDependencyNode(
559                 new Dependency( versionManaged, "provided" )
560         );
561 
562         Artifact scopeVersionManaged = new DefaultArtifact( "org.scopeVersionManaged", "scope-version-managed",
563                 "xml", "2" );
564         artifactProperties = new HashMap<>( scopeVersionManaged.getProperties() );
565         artifactProperties.put( PRE_MANAGED_SCOPE, "runtime" );
566         artifactProperties.put( MANAGED_SCOPE, "compile" );
567         artifactProperties.put( PRE_MANAGED_VERSION, "3.1" );
568         scopeVersionManaged = scopeVersionManaged.setProperties( artifactProperties );
569 
570         DependencyNode l4right = new DefaultDependencyNode(
571                 new Dependency( scopeVersionManaged, "runtime" )
572         );
573 
574         Dependency optionalDependency = new Dependency(
575                 new DefaultArtifact( "org.apache", "optional", "jar", "1.1" ), "test" );
576         optionalDependency = optionalDependency.setOptional( true );
577         DependencyNode l1Optional = new DefaultDependencyNode( optionalDependency );
578 
579         root.setChildren( Arrays.asList( l1left, l1middle, l1right, l1Optional ) );
580         l1left.setChildren( Arrays.asList( l2left, l2middleLeft ) );
581         l2left.setChildren( Collections.singletonList( l6right ) ); // l6right shouldn't show due to omitted parent node
582         l2middleLeft.setChildren( Collections.singletonList( l6right ) );
583         l1Optional.setChildren( Collections.singletonList( l6right ) );
584         l1middle.setChildren( Collections.singletonList( l2middleRight ) );
585         l1right.setChildren( Collections.singletonList( l2right ) );
586         l2right.setChildren( Collections.singletonList( l3right ) );
587         l3right.setChildren( Collections.singletonList( l4right ) );
588         l4right.setChildren( Collections.singletonList( l5right ) );
589         l5right.setChildren( Collections.singletonList( l6right ) );
590 
591         String actual = serializer.serialize( root );
592         String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <graphml xmlns=\"http://graphml.graph"
593                 + "drawing.org/xmlns\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:y=\"http://www.ywo"
594                 + "rks.com/xml/graphml\" xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns http://graphml."
595                 + "graphdrawing.org/xmlns/1.0/graphml.xsd\">" + "\n" + "  <key for=\"node\" id=\"d0\" "
596                 + "yfiles.type=\"nodegraphics\"/>" + "\n" + "  <key for=\"edge\" id=\"d1\" yfiles"
597                 + ".type=\"edgegraphics\"/>" + "\n"
598                 + "<graph id=\"dependencies\" edgedefault=\"directed\">"
599                 + "\n" + "<node id=\"" + root.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
600                 + "<y:NodeLabel>" + "org.example:root:jar:3.1.1</y:NodeLabel></y:ShapeNode></data></node>"
601                 + "\n" + "<node id=\"" + l1left.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
602                 + "<y:NodeLabel>org.duplicate:duplicate:xml:" + "2:compile</y:NodeLabel></y:ShapeNode></data></node>"
603                 + "\n"
604                 + "<node id=\"" + l1middle.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:"
605                 + "maven:jar:1.0-SNAPSHOT:test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
606                 + "<node id=\"" + l1right.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven"
607                 + "-dependency:jar:1.0-SNAPSHOT:test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
608                 + "<node id=\"" + l1Optional.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:"
609                 + "optional:jar:1.1:test - omitted due to optional dependency</y:NodeLabel></y:ShapeNode></data></node>"
610                 + "\n" + "<node id=\"" + l2left.hashCode() + "\"><data key=\"d0\"><y:ShapeNode>"
611                 + "<y:NodeLabel>org.duplicate:duplicate:xml:2:compile - omitted for duplicate</y:NodeLabel>"
612                 + "</y:ShapeNode></data></node>" + "\n" + "<node id=\"" + l2middleLeft.hashCode()
613                 + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.cycle:cycle:zip:3:compile - omitted due to cycle"
614                 + "</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
615                 + "<node id=\"" + l2middleRight.hashCode() + "\">"
616                 + "<data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven-dependency:jar:1.0-SNAPSHOT:compile "
617                 + "- omitted for conflict with test</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
618                 + "<node id=\"" + l2right.hashCode() + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.scopeManaged"
619                 + ":scope-managed:zip:2.1:compile - scope managed from runtime</y:NodeLabel></y:ShapeNode></data>"
620                 + "</node>" + "\n" + "<node id=\"" + l3right.hashCode() + "\"><data key=\"d0\">"
621                 + "<y:ShapeNode><y:NodeLabel>org.versionManaged:version-manged:pom:3.3.3:provided - version managed "
622                 + "from 1.1.0</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
623                 + "<node id=\"" + l4right.hashCode()
624                 + "\"><data key=\"d0\"><y:ShapeNode><y:NodeLabel>org.scopeVersionManaged:scope-version-managed:xml:"
625                 + "2:compile - version managed from 3.1; scope managed from runtime</y:NodeLabel></y:ShapeNode>"
626                 + "</data></node>" + "\n" + "<node id=\"" + l5right.hashCode() + "\"><data key="
627                 + "\"d0\"><y:ShapeNode><y:NodeLabel>org.apache:maven-dependency:jar:2.1:test - omitted for"
628                 + " conflict with 1.0-SNAPSHOT</y:NodeLabel></y:ShapeNode></data></node>" + "\n"
629                 + "<edge source=\"" + root.hashCode() + "\" target=\"" + l1left.hashCode()
630                 + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile</y:EdgeLabel></y:PolyLineEdge></data>"
631                 + "</edge>" + "\n" + "<edge source=\"" + root.hashCode() + "\" target=\""
632                 + l1middle.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test</y:EdgeLabel>"
633                 + "</y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\"" + root.hashCode()
634                 + "\" target=\"" + l1right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test"
635                 + "</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\""
636                 + root.hashCode() + "\" target=\"" + l1Optional.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge>"
637                 + "<y:EdgeLabel>test omitted due to optional dependency</y:EdgeLabel></y:PolyLineEdge></data></edge>"
638                 + "\n" + "<edge source=\"" + l1left.hashCode() + "\" target=\""
639                 + l2left.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted "
640                 + "for duplicate</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
641                 + "<edge source=\"" + l1left.hashCode() + "\" target=\"" + l2middleLeft.hashCode()
642                 + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted due to cycle</y:EdgeLabel>"
643                 + "</y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\"" + l1middle.hashCode()
644                 + "\" target=\""
645                 + l2middleRight.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>compile omitted"
646                 + " for conflict with test</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
647                 + "<edge source=\"" + l1right.hashCode() + "\" target=\"" + l2right.hashCode() + "\"><data key=\"d1\">"
648                 + "<y:PolyLineEdge><y:EdgeLabel>compile, scope managed from runtime</y:EdgeLabel></y:PolyLineEdge>"
649                 + "</data></edge>" + "\n" + "<edge source=\"" + l2right.hashCode() + "\" target="
650                 + "\"" + l3right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>provided"
651                 + "</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n" + "<edge source=\""
652                 + l3right.hashCode() + "\" target=\"" + l4right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge>"
653                 + "<y:EdgeLabel>compile, scope managed from runtime</y:EdgeLabel></y:PolyLineEdge></data>"
654                 + "</edge>" + "\n" + "<edge source=\"" + l4right.hashCode() + "\" target=\""
655                 + l5right.hashCode() + "\"><data key=\"d1\"><y:PolyLineEdge><y:EdgeLabel>test omitted "
656                 + "for conflict with 1.0-SNAPSHOT</y:EdgeLabel></y:PolyLineEdge></data></edge>" + "\n"
657                 + "</graph></graphml>";
658         Assert.assertEquals(expected, actual);
659     }
660 }