1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency.tree;
20
21 import java.io.File;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.OutputStreamWriter;
25 import java.io.StringReader;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Comparator;
32 import java.util.List;
33 import java.util.Set;
34 import java.util.stream.Collectors;
35
36 import jakarta.json.Json;
37 import jakarta.json.JsonArray;
38 import jakarta.json.JsonObject;
39 import jakarta.json.JsonReader;
40 import org.apache.maven.artifact.Artifact;
41 import org.apache.maven.execution.MavenSession;
42 import org.apache.maven.plugin.LegacySupport;
43 import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
44 import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase;
45 import org.apache.maven.project.MavenProject;
46 import org.apache.maven.shared.dependency.graph.DependencyNode;
47 import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
48
49
50
51
52
53
54
55
56 public class TestTreeMojo extends AbstractDependencyMojoTestCase {
57
58
59 @Override
60 protected String getTestDirectoryName() {
61 return "tree";
62 }
63
64 @Override
65 protected boolean shouldUseFlattenedPath() {
66 return false;
67 }
68
69
70
71
72 @Override
73 protected void setUp() throws Exception {
74
75 super.setUp();
76
77 MavenProject project = new MavenProjectStub();
78 getContainer().addComponent(project, MavenProject.class.getName());
79
80 MavenSession session = newMavenSession(project);
81 getContainer().addComponent(session, MavenSession.class.getName());
82
83 LegacySupport legacySupport = lookup(LegacySupport.class);
84 legacySupport.setSession(session);
85 installLocalRepository(legacySupport);
86 }
87
88
89
90
91
92
93
94
95 public void testTreeTestEnvironment() throws Exception {
96 File testPom = new File(getBasedir(), "target/test-classes/unit/tree-test/plugin-config.xml");
97 TreeMojo mojo = (TreeMojo) lookupMojo("tree", testPom);
98
99 assertNotNull(mojo);
100 assertNotNull(mojo.getProject());
101 MavenProject project = mojo.getProject();
102 project.setArtifact(this.stubFactory.createArtifact("testGroupId", "project", "1.0"));
103
104 Set<Artifact> artifacts = this.stubFactory.getScopedArtifacts();
105 Set<Artifact> directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts();
106 artifacts.addAll(directArtifacts);
107
108 project.setArtifacts(artifacts);
109 project.setDependencyArtifacts(directArtifacts);
110
111 mojo.execute();
112
113 DependencyNode rootNode = mojo.getDependencyGraph();
114 assertNodeEquals("testGroupId:project:jar:1.0:compile", rootNode);
115 assertEquals(2, rootNode.getChildren().size());
116
117 List<String> actualNodes = Arrays.asList(
118 createArtifactCoordinateString(rootNode.getChildren().get(0)),
119 createArtifactCoordinateString(rootNode.getChildren().get(1)));
120 List<String> expectedNodes =
121 Arrays.asList("testGroupId:release:jar:1.0:compile", "testGroupId:snapshot:jar:2.0-SNAPSHOT:compile");
122
123 assertTrue(expectedNodes.containsAll(actualNodes));
124 }
125
126
127
128
129
130
131 public void testTreeDotSerializing() throws Exception {
132 List<String> contents = runTreeMojo("tree1.dot", "dot");
133 assertTrue(findString(contents, "digraph \"testGroupId:project:jar:1.0:compile\" {"));
134 assertTrue(findString(
135 contents,
136 "\"testGroupId:project:jar:1.0:compile\" -> \"testGroupId:snapshot:jar:2.0-SNAPSHOT:compile\""));
137 assertTrue(findString(
138 contents, "\"testGroupId:project:jar:1.0:compile\" -> \"testGroupId:release:jar:1.0:compile\""));
139 }
140
141
142
143
144
145
146 public void testTreeGraphMLSerializing() throws Exception {
147 List<String> contents = runTreeMojo("tree1.graphml", "graphml");
148
149 assertTrue(findString(contents, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));
150 assertTrue(findString(contents, "<y:NodeLabel>testGroupId:project:jar:1.0:compile</y:NodeLabel>"));
151 assertTrue(findString(contents, "<y:NodeLabel>testGroupId:snapshot:jar:2.0-SNAPSHOT:compile</y:NodeLabel>"));
152 assertTrue(findString(contents, "<y:NodeLabel>testGroupId:release:jar:1.0:compile</y:NodeLabel>"));
153 assertTrue(findString(contents, "<key for=\"node\" id=\"d0\" yfiles.type=\"nodegraphics\"/>"));
154 assertTrue(findString(contents, "<key for=\"edge\" id=\"d1\" yfiles.type=\"edgegraphics\"/>"));
155 }
156
157
158
159
160
161
162 public void testTreeTGFSerializing() throws Exception {
163 List<String> contents = runTreeMojo("tree1.tgf", "tgf");
164 assertTrue(findString(contents, "testGroupId:project:jar:1.0:compile"));
165 assertTrue(findString(contents, "testGroupId:snapshot:jar:2.0-SNAPSHOT:compile"));
166 assertTrue(findString(contents, "testGroupId:release:jar:1.0:compile"));
167 }
168
169
170
171
172 public void testTreeJsonCircularDependency() throws IOException {
173 String outputFileName = testDir.getAbsolutePath() + File.separator + "tree1.json";
174 File outputFile = new File(outputFileName);
175 Files.createDirectories(outputFile.getParentFile().toPath());
176 outputFile.createNewFile();
177
178 Artifact artifact1 = this.stubFactory.createArtifact("testGroupId", "project1", "1.0");
179 Artifact artifact2 = this.stubFactory.createArtifact("testGroupId", "project2", "1.0");
180 DefaultDependencyNode node1 = new DefaultDependencyNode(artifact1);
181 DefaultDependencyNode node2 = new DefaultDependencyNode(artifact2);
182
183 node1.setChildren(new ArrayList<DependencyNode>());
184 node2.setChildren(new ArrayList<DependencyNode>());
185
186 node1.getChildren().add(node2);
187 node2.getChildren().add(node1);
188
189 try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(outputFile))) {
190 JsonDependencyNodeVisitor jsonDependencyNodeVisitor = new JsonDependencyNodeVisitor(outputStreamWriter);
191
192 jsonDependencyNodeVisitor.visit(node1);
193 }
194 }
195
196
197
198
199 public void testTreeJsonParsing() throws Exception {
200 List<String> contents = runTreeMojo("tree2.json", "json");
201
202 System.setProperty("jakarta.json.provider", "org.glassfish.json.JsonProviderImpl");
203 try (JsonReader reader = Json.createReader(new StringReader(String.join(System.lineSeparator(), contents)))) {
204 JsonObject root = reader.readObject();
205
206 assertEquals(root.getString("groupId"), "testGroupId");
207 assertEquals(root.getString("artifactId"), "project");
208 assertEquals(root.getString("version"), "1.0");
209 assertEquals(root.getString("type"), "jar");
210 assertEquals(root.getString("scope"), "compile");
211 assertEquals(root.getString("classifier"), "");
212 assertEquals(root.getString("optional"), "false");
213
214 JsonArray children = root.getJsonArray("children");
215 assertEquals(children.size(), 2);
216
217 List<JsonObject> sortedChildren = children.stream()
218 .map(JsonObject.class::cast)
219 .sorted(Comparator.comparing(child -> child.getString("artifactId")))
220 .collect(Collectors.toList());
221
222
223 JsonObject child0 = sortedChildren.get(0);
224 assertEquals(child0.getString("groupId"), "testGroupId");
225 assertEquals(child0.getString("artifactId"), "release");
226 assertEquals(child0.getString("version"), "1.0");
227 assertEquals(child0.getString("type"), "jar");
228 assertEquals(child0.getString("scope"), "compile");
229 assertEquals(child0.getString("classifier"), "");
230 assertEquals(child0.getString("optional"), "false");
231
232 JsonObject child1 = sortedChildren.get(1);
233 assertEquals(child1.getString("groupId"), "testGroupId");
234 assertEquals(child1.getString("artifactId"), "snapshot");
235 assertEquals(child1.getString("version"), "2.0-SNAPSHOT");
236 assertEquals(child1.getString("type"), "jar");
237 assertEquals(child1.getString("scope"), "compile");
238 assertEquals(child1.getString("classifier"), "");
239 assertEquals(child1.getString("optional"), "false");
240 }
241 }
242
243
244
245
246
247
248
249
250
251 private List<String> runTreeMojo(String outputFile, String format) throws Exception {
252 File testPom = new File(getBasedir(), "target/test-classes/unit/tree-test/plugin-config.xml");
253 Path outputFilePath = Paths.get(testDir.getAbsolutePath(), outputFile);
254 TreeMojo mojo = (TreeMojo) lookupMojo("tree", testPom);
255 setVariableValueToObject(mojo, "outputEncoding", "UTF-8");
256 setVariableValueToObject(mojo, "outputType", format);
257 setVariableValueToObject(mojo, "outputFile", outputFilePath.toFile());
258
259 assertNotNull(mojo);
260 assertNotNull(mojo.getProject());
261 MavenProject project = mojo.getProject();
262 project.setArtifact(this.stubFactory.createArtifact("testGroupId", "project", "1.0"));
263
264 Set<Artifact> artifacts = this.stubFactory.getScopedArtifacts();
265 Set<Artifact> directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts();
266 artifacts.addAll(directArtifacts);
267
268 project.setArtifacts(artifacts);
269 project.setDependencyArtifacts(directArtifacts);
270
271 mojo.execute();
272
273 List<String> contents = Files.readAllLines(outputFilePath);
274
275 return contents;
276 }
277
278
279
280
281
282
283
284 private boolean findString(List<String> contents, String str) {
285 for (String line : contents) {
286 if (line.contains(str)) {
287
288 return true;
289 }
290 }
291
292
293 return false;
294 }
295
296
297
298 private void assertNodeEquals(String expectedNode, DependencyNode actualNode) {
299 String[] tokens = expectedNode.split(":");
300
301 assertNodeEquals(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], actualNode);
302 }
303
304 private void assertNodeEquals(
305 String expectedGroupId,
306 String expectedArtifactId,
307 String expectedType,
308 String expectedVersion,
309 String expectedScope,
310 DependencyNode actualNode) {
311 Artifact actualArtifact = actualNode.getArtifact();
312
313 assertEquals("group id", expectedGroupId, actualArtifact.getGroupId());
314 assertEquals("artifact id", expectedArtifactId, actualArtifact.getArtifactId());
315 assertEquals("type", expectedType, actualArtifact.getType());
316 assertEquals("version", expectedVersion, actualArtifact.getVersion());
317 assertEquals("scope", expectedScope, actualArtifact.getScope());
318 }
319
320 private String createArtifactCoordinateString(DependencyNode actualNode) {
321 return actualNode.getArtifact().getGroupId() + ":"
322 + actualNode.getArtifact().getArtifactId() + ":"
323 + actualNode.getArtifact().getType() + ":"
324 + actualNode.getArtifact().getVersion() + ":"
325 + actualNode.getArtifact().getScope();
326 }
327 }