001    package org.apache.maven.project;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.util.ArrayList;
023    import java.util.Collections;
024    import java.util.List;
025    
026    import junit.framework.TestCase;
027    
028    import org.apache.maven.model.Build;
029    import org.apache.maven.model.Dependency;
030    import org.apache.maven.model.Extension;
031    import org.apache.maven.model.Model;
032    import org.apache.maven.model.Parent;
033    import org.apache.maven.model.Plugin;
034    import org.apache.maven.model.PluginManagement;
035    import org.codehaus.plexus.util.dag.CycleDetectedException;
036    
037    /**
038     * Test sorting projects by dependencies.
039     *
040     * @author <a href="mailto:brett@apache.org">Brett Porter</a>
041     */
042    public class ProjectSorterTest
043        extends TestCase
044    {
045    
046        private Parent createParent( MavenProject project )
047        {
048            return createParent( project.getGroupId(), project.getArtifactId(), project.getVersion() );
049        }
050    
051        private Parent createParent( String groupId, String artifactId, String version )
052        {
053            Parent plugin = new Parent();
054            plugin.setGroupId( groupId );
055            plugin.setArtifactId( artifactId );
056            plugin.setVersion( version );
057            return plugin;
058        }
059    
060        private Dependency createDependency( MavenProject project )
061        {
062            return createDependency( project.getGroupId(), project.getArtifactId(), project.getVersion() );
063        }
064    
065        private Dependency createDependency( String groupId, String artifactId, String version )
066        {
067            Dependency depdendency = new Dependency();
068            depdendency.setGroupId( groupId );
069            depdendency.setArtifactId( artifactId );
070            depdendency.setVersion( version );
071            return depdendency;
072        }
073    
074        private Plugin createPlugin( MavenProject project )
075        {
076            return createPlugin( project.getGroupId(), project.getArtifactId(), project.getVersion() );
077        }
078    
079        private Plugin createPlugin( String groupId, String artifactId, String version )
080        {
081            Plugin plugin = new Plugin();
082            plugin.setGroupId( groupId );
083            plugin.setArtifactId( artifactId );
084            plugin.setVersion( version );
085            return plugin;
086        }
087    
088        private Extension createExtension( String groupId, String artifactId, String version )
089        {
090            Extension extension = new Extension();
091            extension.setGroupId( groupId );
092            extension.setArtifactId( artifactId );
093            extension.setVersion( version );
094            return extension;
095        }
096    
097        private static MavenProject createProject( String groupId, String artifactId, String version )
098        {
099            Model model = new Model();
100            model.setGroupId( groupId );
101            model.setArtifactId( artifactId );
102            model.setVersion( version );
103            model.setBuild( new Build() );
104            return new MavenProject( model );
105        }
106    
107        public void testShouldNotFailWhenPluginDepReferencesCurrentProject()
108            throws CycleDetectedException, DuplicateProjectException
109        {
110            MavenProject project = createProject( "group", "artifact", "1.0" );
111    
112            Build build = project.getModel().getBuild();
113    
114            Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
115    
116            Dependency dep = createDependency( "group", "artifact", "1.0" );
117    
118            plugin.addDependency( dep );
119    
120            build.addPlugin( plugin );
121    
122            new ProjectSorter( Collections.singletonList( project ) );
123        }
124    
125        public void testShouldNotFailWhenManagedPluginDepReferencesCurrentProject()
126            throws CycleDetectedException, DuplicateProjectException
127        {
128            MavenProject project = createProject( "group", "artifact", "1.0" );
129    
130            Build build = project.getModel().getBuild();
131    
132            PluginManagement pMgmt = new PluginManagement();
133    
134            Plugin plugin = createPlugin( "other.group", "other-artifact", "1.0" );
135    
136            Dependency dep = createDependency( "group", "artifact", "1.0" );
137    
138            plugin.addDependency( dep );
139    
140            pMgmt.addPlugin( plugin );
141    
142            build.setPluginManagement( pMgmt );
143    
144            new ProjectSorter( Collections.singletonList( project ) );
145        }
146    
147        public void testShouldNotFailWhenProjectReferencesNonExistentProject()
148            throws CycleDetectedException, DuplicateProjectException
149        {
150            MavenProject project = createProject( "group", "artifact", "1.0" );
151    
152            Build build = project.getModel().getBuild();
153    
154            Extension extension = createExtension( "other.group", "other-artifact", "1.0" );
155    
156            build.addExtension( extension );
157    
158            new ProjectSorter( Collections.singletonList( project ) );
159        }
160    
161        public void testMatchingArtifactIdsDifferentGroupIds()
162            throws CycleDetectedException, DuplicateProjectException
163        {
164            List<MavenProject> projects = new ArrayList<MavenProject>();
165            MavenProject project1 = createProject( "groupId1", "artifactId", "1.0" );
166            projects.add( project1 );
167            MavenProject project2 = createProject( "groupId2", "artifactId", "1.0" );
168            projects.add( project2 );
169            project1.getDependencies().add( createDependency( project2 ) );
170    
171            projects = new ProjectSorter( projects ).getSortedProjects();
172    
173            assertEquals( project2, projects.get( 0 ) );
174            assertEquals( project1, projects.get( 1 ) );
175        }
176    
177        public void testMatchingGroupIdsDifferentArtifactIds()
178            throws CycleDetectedException, DuplicateProjectException
179        {
180            List<MavenProject> projects = new ArrayList<MavenProject>();
181            MavenProject project1 = createProject( "groupId", "artifactId1", "1.0" );
182            projects.add( project1 );
183            MavenProject project2 = createProject( "groupId", "artifactId2", "1.0" );
184            projects.add( project2 );
185            project1.getDependencies().add( createDependency( project2 ) );
186    
187            projects = new ProjectSorter( projects ).getSortedProjects();
188    
189            assertEquals( project2, projects.get( 0 ) );
190            assertEquals( project1, projects.get( 1 ) );
191        }
192    
193        public void testMatchingIdsAndVersions()
194            throws CycleDetectedException
195        {
196            List<MavenProject> projects = new ArrayList<MavenProject>();
197            MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
198            projects.add( project1 );
199            MavenProject project2 = createProject( "groupId", "artifactId", "1.0" );
200            projects.add( project2 );
201    
202            try
203            {
204                projects = new ProjectSorter( projects ).getSortedProjects();
205                fail( "Duplicate projects should fail" );
206            }
207            catch ( DuplicateProjectException e )
208            {
209                // expected
210                assertTrue( true );
211            }
212        }
213    
214        public void testMatchingIdsAndDifferentVersions()
215            throws CycleDetectedException, DuplicateProjectException
216        {
217            List<MavenProject> projects = new ArrayList<MavenProject>();
218            MavenProject project1 = createProject( "groupId", "artifactId", "1.0" );
219            projects.add( project1 );
220            MavenProject project2 = createProject( "groupId", "artifactId", "2.0" );
221            projects.add( project2 );
222    
223            projects = new ProjectSorter( projects ).getSortedProjects();
224            assertEquals( project1, projects.get( 0 ) );
225            assertEquals( project2, projects.get( 1 ) );
226        }
227    
228        public void testPluginDependenciesInfluenceSorting()
229            throws Exception
230        {
231            List<MavenProject> projects = new ArrayList<MavenProject>();
232    
233            MavenProject parentProject = createProject( "groupId", "parent", "1.0" );
234            projects.add( parentProject );
235    
236            MavenProject declaringProject = createProject( "groupId", "declarer", "1.0" );
237            declaringProject.setParent( parentProject );
238            declaringProject.getModel().setParent( createParent( parentProject ) );
239            projects.add( declaringProject );
240    
241            MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
242            pluginLevelDepProject.setParent( parentProject );
243            pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
244            projects.add( pluginLevelDepProject );
245    
246            MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
247            pluginProject.setParent( parentProject );
248            pluginProject.getModel().setParent( createParent( parentProject ) );
249            projects.add( pluginProject );
250    
251            Plugin plugin = createPlugin( pluginProject );
252    
253            plugin.addDependency( createDependency( pluginLevelDepProject ) );
254    
255            Build build = declaringProject.getModel().getBuild();
256    
257            build.addPlugin( plugin );
258    
259            projects = new ProjectSorter( projects ).getSortedProjects();
260    
261            assertEquals( parentProject, projects.get( 0 ) );
262    
263            // the order of these two is non-deterministic, based on when they're added to the reactor.
264            assertTrue( projects.contains( pluginProject ) );
265            assertTrue( projects.contains( pluginLevelDepProject ) );
266    
267            // the declaring project MUST be listed after the plugin and its plugin-level dep, though.
268            assertEquals( declaringProject, projects.get( 3 ) );
269        }
270    
271        public void testPluginDependenciesInfluenceSorting_DeclarationInParent()
272            throws Exception
273        {
274            List<MavenProject> projects = new ArrayList<MavenProject>();
275    
276            MavenProject parentProject = createProject( "groupId", "parent-declarer", "1.0" );
277            projects.add( parentProject );
278    
279            MavenProject pluginProject = createProject( "groupId", "plugin", "1.0" );
280            pluginProject.setParent( parentProject );
281            pluginProject.getModel().setParent( createParent( parentProject ) );
282            projects.add( pluginProject );
283    
284            MavenProject pluginLevelDepProject = createProject( "groupId", "plugin-level-dep", "1.0" );
285            pluginLevelDepProject.setParent( parentProject );
286            pluginLevelDepProject.getModel().setParent( createParent( parentProject ) );
287            projects.add( pluginLevelDepProject );
288    
289            Plugin plugin = createPlugin( pluginProject );
290    
291            plugin.addDependency( createDependency( pluginLevelDepProject ) );
292    
293            Build build = parentProject.getModel().getBuild();
294    
295            build.addPlugin( plugin );
296    
297            projects = new ProjectSorter( projects ).getSortedProjects();
298    
299            System.out.println( projects );
300    
301            assertEquals( parentProject, projects.get( 0 ) );
302    
303            // the order of these two is non-deterministic, based on when they're added to the reactor.
304            assertTrue( projects.contains( pluginProject ) );
305            assertTrue( projects.contains( pluginLevelDepProject ) );
306        }
307    
308        public void testPluginVersionsAreConsidered()
309            throws Exception
310        {
311            List<MavenProject> projects = new ArrayList<MavenProject>();
312    
313            MavenProject pluginProjectA = createProject( "group", "plugin-a", "2.0-SNAPSHOT" );
314            projects.add( pluginProjectA );
315            pluginProjectA.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-b", "1.0" ) );
316    
317            MavenProject pluginProjectB = createProject( "group", "plugin-b", "2.0-SNAPSHOT" );
318            projects.add( pluginProjectB );
319            pluginProjectB.getModel().getBuild().addPlugin( createPlugin( "group", "plugin-a", "1.0" ) );
320    
321            projects = new ProjectSorter( projects ).getSortedProjects();
322    
323            assertTrue( projects.contains( pluginProjectA ) );
324            assertTrue( projects.contains( pluginProjectB ) );
325        }
326    
327        public void testDependencyPrecedesProjectThatUsesSpecificDependencyVersion()
328            throws Exception
329        {
330            List<MavenProject> projects = new ArrayList<MavenProject>();
331    
332            MavenProject usingProject = createProject( "group", "project", "1.0" );
333            projects.add( usingProject );
334            usingProject.getModel().addDependency( createDependency( "group", "dependency", "1.0" ) );
335    
336            MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
337            projects.add( pluginProject );
338    
339            projects = new ProjectSorter( projects ).getSortedProjects();
340    
341            assertEquals( pluginProject, projects.get( 0 ) );
342            assertEquals( usingProject, projects.get( 1 ) );
343        }
344    
345        public void testDependencyPrecedesProjectThatUsesUnresolvedDependencyVersion()
346            throws Exception
347        {
348            List<MavenProject> projects = new ArrayList<MavenProject>();
349    
350            MavenProject usingProject = createProject( "group", "project", "1.0" );
351            projects.add( usingProject );
352            usingProject.getModel().addDependency( createDependency( "group", "dependency", "[1.0,)" ) );
353    
354            MavenProject pluginProject = createProject( "group", "dependency", "1.0" );
355            projects.add( pluginProject );
356    
357            projects = new ProjectSorter( projects ).getSortedProjects();
358    
359            assertEquals( pluginProject, projects.get( 0 ) );
360            assertEquals( usingProject, projects.get( 1 ) );
361        }
362    
363    }