1   package org.apache.maven.project;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  
26  import junit.framework.TestCase;
27  
28  import org.apache.maven.model.Build;
29  import org.apache.maven.model.Dependency;
30  import org.apache.maven.model.Extension;
31  import org.apache.maven.model.Model;
32  import org.apache.maven.model.Parent;
33  import org.apache.maven.model.Plugin;
34  import org.apache.maven.model.PluginManagement;
35  import org.codehaus.plexus.util.dag.CycleDetectedException;
36  
37  /**
38   * Test sorting projects by dependencies.
39   *
40   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
41   * @version $Id: ProjectSorterTest.java 1004653 2010-10-05 14:16:48Z bentmann $
42   */
43  public class ProjectSorterTest
44      extends TestCase
45  {
46  
47      private Parent createParent( MavenProject project )
48      {
49          return createParent( project.getGroupId(), project.getArtifactId(), project.getVersion() );
50      }
51  
52      private Parent createParent( String groupId, String artifactId, String version )
53      {
54          Parent plugin = new Parent();
55          plugin.setGroupId( groupId );
56          plugin.setArtifactId( artifactId );
57          plugin.setVersion( version );
58          return plugin;
59      }
60  
61      private Dependency createDependency( MavenProject project )
62      {
63          return createDependency( project.getGroupId(), project.getArtifactId(), project.getVersion() );
64      }
65  
66      private Dependency createDependency( String groupId, String artifactId, String version )
67      {
68          Dependency depdendency = new Dependency();
69          depdendency.setGroupId( groupId );
70          depdendency.setArtifactId( artifactId );
71          depdendency.setVersion( version );
72          return depdendency;
73      }
74  
75      private Plugin createPlugin( MavenProject project )
76      {
77          return createPlugin( project.getGroupId(), project.getArtifactId(), project.getVersion() );
78      }
79  
80      private Plugin createPlugin( String groupId, String artifactId, String version )
81      {
82          Plugin plugin = new Plugin();
83          plugin.setGroupId( groupId );
84          plugin.setArtifactId( artifactId );
85          plugin.setVersion( version );
86          return plugin;
87      }
88  
89      private Extension createExtension( String groupId, String artifactId, String version )
90      {
91          Extension extension = new Extension();
92          extension.setGroupId( groupId );
93          extension.setArtifactId( artifactId );
94          extension.setVersion( version );
95          return extension;
96      }
97  
98      private static MavenProject createProject( String groupId, String artifactId, String version )
99      {
100         Model model = new Model();
101         model.setGroupId( groupId );
102         model.setArtifactId( artifactId );
103         model.setVersion( version );
104         model.setBuild( new Build() );
105         return new MavenProject( model );
106     }
107 
108     public void testShouldNotFailWhenPluginDepReferencesCurrentProject()
109         throws CycleDetectedException, DuplicateProjectException
110     {
111         MavenProject project = createProject( "group", "artifact", "1.0" );
112 
113         Build build = project.getModel().getBuild();
114 
115         Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
116 
117         Dependency dep = createDependency( "group", "artifact", "1.0" );
118 
119         plugin.addDependency( dep );
120 
121         build.addPlugin( plugin );
122 
123         new ProjectSorter( Collections.singletonList( project ) );
124     }
125 
126     public void testShouldNotFailWhenManagedPluginDepReferencesCurrentProject()
127         throws CycleDetectedException, DuplicateProjectException
128     {
129         MavenProject project = createProject( "group", "artifact", "1.0" );
130 
131         Build build = project.getModel().getBuild();
132 
133         PluginManagement pMgmt = new PluginManagement();
134 
135         Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
136 
137         Dependency dep = createDependency( "group", "artifact", "1.0" );
138 
139         plugin.addDependency( dep );
140 
141         pMgmt.addPlugin( plugin );
142 
143         build.setPluginManagement( pMgmt );
144 
145         new ProjectSorter( Collections.singletonList( project ) );
146     }
147 
148     public void testShouldNotFailWhenProjectReferencesNonExistentProject()
149         throws CycleDetectedException, DuplicateProjectException
150     {
151         MavenProject project = createProject( "group", "artifact", "1.0" );
152 
153         Build build = project.getModel().getBuild();
154 
155         Extension extension = createExtension( "other.group", "other-artifact", "1.0" );
156 
157         build.addExtension( extension );
158 
159         new ProjectSorter( Collections.singletonList( project ) );
160     }
161 
162     public void testMatchingArtifactIdsDifferentGroupIds()
163         throws CycleDetectedException, DuplicateProjectException
164     {
165         List<MavenProject> projects = new ArrayList<MavenProject>();
166         MavenProject project1 = createProject( "groupId1", "artifactId", "1.0" );
167         projects.add( project1 );
168         MavenProject project2 = createProject( "groupId2", "artifactId", "1.0" );
169         projects.add( project2 );
170         project1.getDependencies().add( createDependency( project2 ) );
171 
172         projects = new ProjectSorter( projects ).getSortedProjects();
173 
174         assertEquals( project2, projects.get( 0 ) );
175         assertEquals( project1, projects.get( 1 ) );
176     }
177 
178     public void testMatchingGroupIdsDifferentArtifactIds()
179         throws CycleDetectedException, DuplicateProjectException
180     {
181         List<MavenProject> projects = new ArrayList<MavenProject>();
182         MavenProject project1 = createProject( "groupId", "artifactId1", "1.0" );
183         projects.add( project1 );
184         MavenProject project2 = createProject( "groupId", "artifactId2", "1.0" );
185         projects.add( project2 );
186         project1.getDependencies().add( createDependency( project2 ) );
187 
188         projects = new ProjectSorter( projects ).getSortedProjects();
189 
190         assertEquals( project2, projects.get( 0 ) );
191         assertEquals( project1, projects.get( 1 ) );
192     }
193 
194     public void testMatchingIdsAndVersions()
195         throws CycleDetectedException
196     {
197         List<MavenProject> projects = new ArrayList<MavenProject>();
198         MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
199         projects.add( project1 );
200         MavenProject project2 = createProject( "groupId", "artifactId", "1.0" );
201         projects.add( project2 );
202 
203         try
204         {
205             projects = new ProjectSorter( projects ).getSortedProjects();
206             fail( "Duplicate projects should fail" );
207         }
208         catch ( DuplicateProjectException e )
209         {
210             // expected
211             assertTrue( true );
212         }
213     }
214 
215     public void testMatchingIdsAndDifferentVersions()
216         throws CycleDetectedException, DuplicateProjectException
217     {
218         List<MavenProject> projects = new ArrayList<MavenProject>();
219         MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
220         projects.add( project1 );
221         MavenProject project2 = createProject( "groupId", "artifactId", "2.0" );
222         projects.add( project2 );
223 
224         projects = new ProjectSorter( projects ).getSortedProjects();
225         assertEquals( project1, projects.get( 0 ) );
226         assertEquals( project2, projects.get( 1 ) );
227     }
228 
229     public void testPluginDependenciesInfluenceSorting()
230         throws Exception
231     {
232         List<MavenProject> projects = new ArrayList<MavenProject>();
233 
234         MavenProject parentProject = createProject( "groupId", "parent", "1.0" );
235         projects.add( parentProject );
236 
237         MavenProject declaringProject = createProject( "groupId", "declarer", "1.0" );
238         declaringProject.setParent( parentProject );
239         declaringProject.getModel().setParent( createParent( parentProject ) );
240         projects.add( declaringProject );
241 
242         MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
243         pluginLevelDepProject.setParent( parentProject );
244         pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
245         projects.add( pluginLevelDepProject );
246 
247         MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
248         pluginProject.setParent( parentProject );
249         pluginProject.getModel().setParent( createParent( parentProject ) );
250         projects.add( pluginProject );
251 
252         Plugin plugin = createPlugin( pluginProject );
253 
254         plugin.addDependency( createDependency( pluginLevelDepProject ) );
255 
256         Build build = declaringProject.getModel().getBuild();
257 
258         build.addPlugin( plugin );
259 
260         projects = new ProjectSorter( projects ).getSortedProjects();
261 
262         assertEquals( parentProject, projects.get( 0 ) );
263 
264         // the order of these two is non-deterministic, based on when they're added to the reactor.
265         assertTrue( projects.contains( pluginProject ) );
266         assertTrue( projects.contains( pluginLevelDepProject ) );
267 
268         // the declaring project MUST be listed after the plugin and its plugin-level dep, though.
269         assertEquals( declaringProject, projects.get( 3 ) );
270     }
271 
272     public void testPluginDependenciesInfluenceSorting_DeclarationInParent()
273         throws Exception
274     {
275         List<MavenProject> projects = new ArrayList<MavenProject>();
276 
277         MavenProject parentProject = createProject( "groupId", "parent-declarer", "1.0" );
278         projects.add( parentProject );
279 
280         MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
281         pluginProject.setParent( parentProject );
282         pluginProject.getModel().setParent( createParent( parentProject ) );
283         projects.add( pluginProject );
284 
285         MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
286         pluginLevelDepProject.setParent( parentProject );
287         pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
288         projects.add( pluginLevelDepProject );
289 
290         Plugin plugin = createPlugin( pluginProject );
291 
292         plugin.addDependency( createDependency( pluginLevelDepProject ) );
293 
294         Build build = parentProject.getModel().getBuild();
295 
296         build.addPlugin( plugin );
297 
298         projects = new ProjectSorter( projects ).getSortedProjects();
299 
300         System.out.println( projects );
301 
302         assertEquals( parentProject, projects.get( 0 ) );
303 
304         // the order of these two is non-deterministic, based on when they're added to the reactor.
305         assertTrue( projects.contains( pluginProject ) );
306         assertTrue( projects.contains( pluginLevelDepProject ) );
307     }
308 
309     public void testPluginVersionsAreConsidered()
310         throws Exception
311     {
312         List<MavenProject> projects = new ArrayList<MavenProject>();
313 
314         MavenProject pluginProjectA = createProject( "group", "plugin-a", "2.0-SNAPSHOT" );
315         projects.add( pluginProjectA );
316         pluginProjectA.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-b", "1.0" ) );
317 
318         MavenProject pluginProjectB = createProject( "group", "plugin-b", "2.0-SNAPSHOT" );
319         projects.add( pluginProjectB );
320         pluginProjectB.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-a", "1.0" ) );
321 
322         projects = new ProjectSorter( projects ).getSortedProjects();
323 
324         assertTrue( projects.contains( pluginProjectA ) );
325         assertTrue( projects.contains( pluginProjectB ) );
326     }
327 
328     public void testDependencyPrecedesProjectThatUsesSpecificDependencyVersion()
329         throws Exception
330     {
331         List<MavenProject> projects = new ArrayList<MavenProject>();
332 
333         MavenProject usingProject = createProject( "group", "project", "1.0" );
334         projects.add( usingProject );
335         usingProject.getModel().addDependency( createDependency( "group", "dependency", "1.0" ) );
336 
337         MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
338         projects.add( pluginProject );
339 
340         projects = new ProjectSorter( projects ).getSortedProjects();
341 
342         assertEquals( pluginProject, projects.get( 0 ) );
343         assertEquals( usingProject, projects.get( 1 ) );
344     }
345 
346     public void testDependencyPrecedesProjectThatUsesUnresolvedDependencyVersion()
347         throws Exception
348     {
349         List<MavenProject> projects = new ArrayList<MavenProject>();
350 
351         MavenProject usingProject = createProject( "group", "project", "1.0" );
352         projects.add( usingProject );
353         usingProject.getModel().addDependency( createDependency( "group", "dependency", "[1.0,)" ) );
354 
355         MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
356         projects.add( pluginProject );
357 
358         projects = new ProjectSorter( projects ).getSortedProjects();
359 
360         assertEquals( pluginProject, projects.get( 0 ) );
361         assertEquals( usingProject, projects.get( 1 ) );
362     }
363 
364 }